如何在Android中显示FTP下载的进度条更新

时间:2019-06-13 11:30:19

标签: java android android-intent

我正在尝试下载apk文件以更新我的应用程序,并且apk放置在ftp服务器中,我正在使用FTP客户端下载该apk。

即使我打电话给mProgress.setProgress(percent);  ProgressBar不能从我通过ftp下载apk文件的功能中得到更新

public class UpdateAppByFTP extends AsyncTask<String,Void,Void> {
private Context context;
CopyStreamAdapter streamListener;
public void setContext(Context mContext){
    context = mContext;
}
private ProgressDialog mProgress;
@Override
protected void onPreExecute(){
    super.onPreExecute();
    mProgress = new ProgressDialog(this.context);
    mProgress.setMessage("Downloading new apk .. Please wait...");
    mProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    //mProgress.setIndeterminate(true);
    mProgress.show();
}
@Override
protected void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);
    mProgress.dismiss(); //Dismiss the above Dialogue
}
@Override
protected Void doInBackground(String... arg0) {
    try {
        String serverName       = arg0[0];
        String userName         = arg0[1];
        String password         = arg0[2];
        String serverFilePath   = arg0[3];
        String localFilePath    = arg0[4];            if(getFileByFTP(serverName,userName,password,serverFilePath,localFilePath)){
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File(localFilePath)), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
            context.startActivity(intent);
        }else{
            //Do nothing could not download
        }
        String apkLocation="/download/"+"SmartPOS.apk";
        Intent intent1 = new Intent(Intent.ACTION_VIEW);
        intent1.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() +apkLocation)), "application/vnd.android.package-archive");
        intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
        context.startActivity(intent1);
    } catch (Exception e) {
    }
    return null;
}
//Below code to download using FTP
public  boolean getFileByFTP(String serverName, String userName,
                                   String password, String serverFilePath, String localFilePath)
        throws Exception {
    FTPClient ftp = new FTPClient();
    try {
        ftp.connect(serverName);
        int reply = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftp.disconnect();
            return false;
        }
    } catch (IOException e) {
        if (ftp.isConnected()) {
            try {
                ftp.disconnect();
            } catch (IOException f) {
                throw e;
            }
        }
        throw e;
    } catch (Exception e) {
        throw e;
    }
    try {
        if (!ftp.login(userName, password)) {
            ftp.logout();
        }
        ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
        ftp.enterLocalPassiveMode();
        final int lenghtOfFile =(int)getFileSize(ftp,serverFilePath); 
        OutputStream output = new FileOutputStream(localFilePath);
        CountingOutputStream cos = new CountingOutputStream(output) {
            protected void beforeWrite(int n) {
                super.beforeWrite(n);
                int percent = Math.round((getCount() * 100) / lenghtOfFile);
                Log.d("FTP_DOWNLOAD", "bytesTransferred /downloaded"+percent);
                System.err.println("Downloaded "+getCount() + "/" + percent);
                mProgress.setProgress(percent);
            }
        };
        ftp.setBufferSize(2024*2048);//To increase the  download speed
        ftp.retrieveFile(serverFilePath, output);
        output.close();
        ftp.noop(); // check that control connection is working OK
        ftp.logout();
        return true;
    }
    catch (FTPConnectionClosedException e) {
        Log.d("FTP_DOWNLOAD", "ERROR FTPConnectionClosedException:"+e.toString());
        throw e;
    } catch (IOException e) {
        Log.d("FTP_DOWNLOAD", "ERROR IOException:"+e.toString());
        throw e;
    } catch (Exception e) {
        Log.d("FTP_DOWNLOAD", "ERROR Exception:"+e.toString());
        throw e;
    } finally {
        if (ftp.isConnected()) {
            try {
                ftp.disconnect();
            } catch (IOException f) {
                throw f;
            }
        }
    }
}
private static long getFileSize(FTPClient ftp, String filePath) throws Exception {
    long fileSize = 0;
    FTPFile[] files = ftp.listFiles(filePath);
    if (files.length == 1 && files[0].isFile()) {
        fileSize = files[0].getSize();
    }
    Log.d("FTP_DOWNLOAD", "File size = " + fileSize);
    return fileSize;
 }
 }

基本上,UI不会更新,也不确定CountingOutputStream是否是找到文件下载大小的正确方法。

谢谢。

2 个答案:

答案 0 :(得分:0)

我更改了代码的这个retrieveFile部分,现在可以了

ftp.retrieveFile(serverFilePath,cos);

答案 1 :(得分:0)

我尝试了您的解决方案,它对我来说效果很好,文件大小高达 30 MB,从 FTP 开始,每次下载都会崩溃。所以我假设每次调用 getCount() 方法都会导致一些问题。

我什至尝试在单独的线程上运行 getCount(),但仍然没有用。

所以最后我将百分比(进度)变量更改为本地/FTP 文件大小的 FileSize 的分数。因此,在上述情况下,它将是:

int percent = Math.round(output.length() * 100) / lenghtOfFile);

工作正常。