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)