Android 从文件系统 Web 服务器下载文件不工作
Android File Download from File system web server not working
列表工作正常,但问题是我无法从网络服务器文件系统下载文件。当我尝试单击其中一个列表项时,该对话框将显示,但几秒钟后该应用程序将崩溃。我正在使用 GenyMotion 模拟器
文件名是正确的url,我猜它在保存部分
Memo.java
package com.example.androidtablayout;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class Memo extends ListActivity {
// Declare Variables
JSONObject jsonobject;
JSONArray jsonarray;
ListView listview;
ArrayList<HashMap<String, String>> arraylist;
ProgressDialog mProgressDialog, dialog;
JSONParser jsonParser = new JSONParser();
String email;
SessionManager session;
String[] services;
private String url = "http://10.0.3.2/sunshine-ems/memo.php";
// single product url
// ALL JSON node names
private static final String MEMO_ID = "memo_id";
private static final String MEMO_SENDER = "sender";
private static final String MEMO_FILENAME = "file_name";
Button btnLogout;
String username;
String download_path = "";
String dest_file_path = "";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.announc);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
session = new SessionManager(getApplicationContext());
username = session.getUsername();
btnLogout = (Button) findViewById(R.id.btnLogout);
btnLogout.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// Launching All products Activity
session.logoutUser();
Intent i = new Intent(getApplicationContext(), Login.class);
startActivity(i);
}
});
new DownloadJSON().execute();
ListView lv = getListView();
lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
String memo_filename = ((TextView) view.findViewById(R.id.txt_service)).getText().toString();
download_path = "http://www.sunshine-ems.balay-indang.com/attachments/memo/"+memo_filename+".docx";
String sd_path = Environment.getExternalStorageDirectory().getPath();
dest_file_path = sd_path+"/"+memo_filename+".docx";
dialog = ProgressDialog.show(Memo.this, "", "Downloading file...", true);
new Thread(new Runnable() {
public void run() {
//Log.d("Download Path", dest_file_path+" "+download_path);
downloadFile(download_path, dest_file_path);
}
}).start();
}
});
}
//download
public void downloadFile(String download_path, String dest_file_path) {
try {
File dest_file = new File(dest_file_path);
URL u = new URL(download_path);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(dest_file));
fos.write(buffer);
fos.flush();
fos.close();
hideProgressIndicator();
} catch(FileNotFoundException e) {
hideProgressIndicator();
return;
} catch (IOException e) {
hideProgressIndicator();
return;
}
}
void hideProgressIndicator(){
runOnUiThread(new Runnable() {
public void run() {
dialog.dismiss();
}
});
}
// DownloadJSON AsyncTask
private class DownloadJSON extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(Memo.this);
mProgressDialog.setTitle("Loading Services");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
@Override
protected String doInBackground(String... params) {
username = session.getUsername();
List<NameValuePair> params1 = new ArrayList<NameValuePair>();
params1.add(new BasicNameValuePair("username", username));
JSONObject json = jsonParser.makeHttpRequest(url, "POST", params1);
// Check your log cat for JSON reponse
Log.d("Check JSON ", json.toString());
// Create the array
arraylist = new ArrayList<HashMap<String, String>>();
try {
int success = json.getInt("success");
if (success == 1) {
// Locate the array name
jsonarray = json.getJSONArray("memos");
for (int i = 0; i < jsonarray.length(); i++) {
json = jsonarray.getJSONObject(i);
String m_id = json.optString(MEMO_ID);
String m_subject = json.getString(MEMO_FILENAME);
String m_sender = json.getString(MEMO_SENDER);
// Retrive JSON Objects
HashMap<String, String> map = new HashMap<String, String>();
map.put(MEMO_ID, m_id);
map.put(MEMO_FILENAME, m_subject);
map.put(MEMO_SENDER, m_sender);
// Set the JSON Objects into the array
arraylist.add(map);
}
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String file_url) {
mProgressDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
Memo.this,
arraylist,
R.layout.listview_services,
new String[] { MEMO_ID, MEMO_FILENAME, MEMO_SENDER },
new int[] { R.id.transac_id, R.id.txt_service,
R.id.txt_date });
// updating listview
setListAdapter(adapter);
}
});
}
}
}
我觉得下载没问题,可能是saving/writing部分有问题。也许是目标路径或接近该路径的东西
还有下载后在哪里可以看到下载的文件?
我正在使用 GenyMotion 模拟器
对于菜鸟问题,我很抱歉
非常感谢
问题似乎是这一行(因为它是唯一的数组):
byte[] buffer = new byte[contentLength];
查看 contentLenght 的声明,似乎 conn.getContentLength() 返回负数。
Returns the content length in bytes specified by the response header field
content-length or -1 if this field is not set or cannot be represented as an int.
我复制了您的代码并使用调试器进行了检查:contentLenght 始终为 -1。
我刚刚重写了您的 downloadFile 函数以使用 HttpURLConnection 而不是 URLConnection。此外,它多次使用一个小缓冲区,而不是创建一个大缓冲区。
//download
public void downloadFile(String download_path, String dest_file_path) {
try {
URL u = new URL(download_path);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
InputStream stream = conn.getInputStream();
File f = new File(dest_file_path);
FileOutputStream fos = new FileOutputStream(f);
int bytesRead = 0;
byte[] buffer = new byte[4096];
while ((bytesRead = stream.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
fos.close();
stream.close();
hideProgressIndicator();
} catch(FileNotFoundException e) {
hideProgressIndicator();
return;
} catch (IOException e) {
hideProgressIndicator();
return;
}
}
之后您可以使用ADB 查看该文件。 Android 设备监视器包含一个文件资源管理器,位于 "path-to\AndroidSDK\tools\monitor.bat"(使用 Windows)
列表工作正常,但问题是我无法从网络服务器文件系统下载文件。当我尝试单击其中一个列表项时,该对话框将显示,但几秒钟后该应用程序将崩溃。我正在使用 GenyMotion 模拟器
文件名是正确的url,我猜它在保存部分
Memo.java
package com.example.androidtablayout;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class Memo extends ListActivity {
// Declare Variables
JSONObject jsonobject;
JSONArray jsonarray;
ListView listview;
ArrayList<HashMap<String, String>> arraylist;
ProgressDialog mProgressDialog, dialog;
JSONParser jsonParser = new JSONParser();
String email;
SessionManager session;
String[] services;
private String url = "http://10.0.3.2/sunshine-ems/memo.php";
// single product url
// ALL JSON node names
private static final String MEMO_ID = "memo_id";
private static final String MEMO_SENDER = "sender";
private static final String MEMO_FILENAME = "file_name";
Button btnLogout;
String username;
String download_path = "";
String dest_file_path = "";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.announc);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
session = new SessionManager(getApplicationContext());
username = session.getUsername();
btnLogout = (Button) findViewById(R.id.btnLogout);
btnLogout.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// Launching All products Activity
session.logoutUser();
Intent i = new Intent(getApplicationContext(), Login.class);
startActivity(i);
}
});
new DownloadJSON().execute();
ListView lv = getListView();
lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
String memo_filename = ((TextView) view.findViewById(R.id.txt_service)).getText().toString();
download_path = "http://www.sunshine-ems.balay-indang.com/attachments/memo/"+memo_filename+".docx";
String sd_path = Environment.getExternalStorageDirectory().getPath();
dest_file_path = sd_path+"/"+memo_filename+".docx";
dialog = ProgressDialog.show(Memo.this, "", "Downloading file...", true);
new Thread(new Runnable() {
public void run() {
//Log.d("Download Path", dest_file_path+" "+download_path);
downloadFile(download_path, dest_file_path);
}
}).start();
}
});
}
//download
public void downloadFile(String download_path, String dest_file_path) {
try {
File dest_file = new File(dest_file_path);
URL u = new URL(download_path);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(dest_file));
fos.write(buffer);
fos.flush();
fos.close();
hideProgressIndicator();
} catch(FileNotFoundException e) {
hideProgressIndicator();
return;
} catch (IOException e) {
hideProgressIndicator();
return;
}
}
void hideProgressIndicator(){
runOnUiThread(new Runnable() {
public void run() {
dialog.dismiss();
}
});
}
// DownloadJSON AsyncTask
private class DownloadJSON extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(Memo.this);
mProgressDialog.setTitle("Loading Services");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
@Override
protected String doInBackground(String... params) {
username = session.getUsername();
List<NameValuePair> params1 = new ArrayList<NameValuePair>();
params1.add(new BasicNameValuePair("username", username));
JSONObject json = jsonParser.makeHttpRequest(url, "POST", params1);
// Check your log cat for JSON reponse
Log.d("Check JSON ", json.toString());
// Create the array
arraylist = new ArrayList<HashMap<String, String>>();
try {
int success = json.getInt("success");
if (success == 1) {
// Locate the array name
jsonarray = json.getJSONArray("memos");
for (int i = 0; i < jsonarray.length(); i++) {
json = jsonarray.getJSONObject(i);
String m_id = json.optString(MEMO_ID);
String m_subject = json.getString(MEMO_FILENAME);
String m_sender = json.getString(MEMO_SENDER);
// Retrive JSON Objects
HashMap<String, String> map = new HashMap<String, String>();
map.put(MEMO_ID, m_id);
map.put(MEMO_FILENAME, m_subject);
map.put(MEMO_SENDER, m_sender);
// Set the JSON Objects into the array
arraylist.add(map);
}
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String file_url) {
mProgressDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
Memo.this,
arraylist,
R.layout.listview_services,
new String[] { MEMO_ID, MEMO_FILENAME, MEMO_SENDER },
new int[] { R.id.transac_id, R.id.txt_service,
R.id.txt_date });
// updating listview
setListAdapter(adapter);
}
});
}
}
}
我觉得下载没问题,可能是saving/writing部分有问题。也许是目标路径或接近该路径的东西
还有下载后在哪里可以看到下载的文件? 我正在使用 GenyMotion 模拟器 对于菜鸟问题,我很抱歉 非常感谢
问题似乎是这一行(因为它是唯一的数组):
byte[] buffer = new byte[contentLength];
查看 contentLenght 的声明,似乎 conn.getContentLength() 返回负数。
Returns the content length in bytes specified by the response header field content-length or -1 if this field is not set or cannot be represented as an int.
我复制了您的代码并使用调试器进行了检查:contentLenght 始终为 -1。
我刚刚重写了您的 downloadFile 函数以使用 HttpURLConnection 而不是 URLConnection。此外,它多次使用一个小缓冲区,而不是创建一个大缓冲区。
//download
public void downloadFile(String download_path, String dest_file_path) {
try {
URL u = new URL(download_path);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
InputStream stream = conn.getInputStream();
File f = new File(dest_file_path);
FileOutputStream fos = new FileOutputStream(f);
int bytesRead = 0;
byte[] buffer = new byte[4096];
while ((bytesRead = stream.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
fos.close();
stream.close();
hideProgressIndicator();
} catch(FileNotFoundException e) {
hideProgressIndicator();
return;
} catch (IOException e) {
hideProgressIndicator();
return;
}
}
之后您可以使用ADB 查看该文件。 Android 设备监视器包含一个文件资源管理器,位于 "path-to\AndroidSDK\tools\monitor.bat"(使用 Windows)