如何在安卓中展示FTP下载进度条更新

3

我试图从FTP服务器下载一个apk文件来更新我的应用程序,并且我正在使用FTP客户端来下载该apk。

尽管我调用了mProgress.setProgress(percent);,但进度条在我使用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;
 }
 }

基本上,用户界面没有更新,我也不确定 CountingOutputStream 是找到文件已下载大小的正确方法。
谢谢。
2个回答

1

我修改了代码中的retrieveFile部分,现在它已经正常了。

ftp.retrieveFile(serverFilePath, cos);

注:Original Answer翻译成"最初的回答"这一要求没有被涉及到。

0

我尝试了您的解决方案,对于从FTP下载的文件大小不超过30 MB的情况下,它可以正常工作,但是当文件大小超过30 MB时,每次下载都会崩溃。因此,我认为是 getCount() 方法被每次调用所导致的问题。

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

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

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

运行良好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接