2

我正在制作一个模块,可以将所有文件从保管箱上的应用程序文件夹下载到设备。

现在,我正在使用 Core API 下载文件。一切正常。但是对于多个文件,我不知道当前文件何时完成下载以转到下一个文件。

这是我的下载代码:

final String cachePath = FileHandler.ROOT_LOCAL_FOLDER_DIR + "/" + mFile.getFileName();
            try {
                mFos = new FileOutputStream(cachePath);
            } catch (FileNotFoundException e) {
                mErrorMsg = "Couldn't create a local file to store the image";
                return false;
            }

            ProgressListener mProgressLisenter = new ProgressListener() {

                @Override
                public void onProgress(long arg0, long arg1) {
                    // TODO Auto-generated method stub
                    tmpFile = new File(cachePath);
                    OnDownloadProgressDropboxChecked(FileHandler.PROGRESS_STATUS_ONPROGRESS, (int) (arg0 * 100 / arg1));
                }

                @Override
                public long progressInterval() {
                    return 100;
                }
            };
            mDownloaded = mApi.getFile(mFile.getFileId(), null, mFos, mProgressLisenter);
                    OnDownloadDropboxChecked(TRUE, "Download complete");
        } catch (DropboxUnlinkedException e) {
            mErrorMsg = "Unlinked";
        } catch (DropboxPartialFileException e) {
            // We canceled the operation
            mErrorMsg = "Download canceled";

        } catch (DropboxServerException e) {
        }
}

我试过了:

  • 捕获进度下载,当达到 100% 时通知 - 这样,Dropbox 的 OnProgress 不会立即显示,有时它不会达到 100%
  • 把它放在异步任务中 - 没用

我现在一头雾水,任何进步对我都有好处。


编辑:
解决方案是在 getFile() 下放置一些触发器,然后它可以工作。

这是我的完整课程:

public class DownloadFile extends AsyncTask<Void, Long, Boolean> implements DConst {

    Context act;
    private DropboxAPI<?> mApi;
    // private String mPath;

    private FileOutputStream mFos;

    private boolean mCanceled;
    private Long mFileLen;
    private String mErrorMsg;
    private String mFileName;
    String path;
    DFile mFile;
    DropboxAPI.DropboxFileInfo mDownloaded;

    @SuppressWarnings("deprecation")
    public DownloadFile(Context act, DropboxAPI<?> api, DFile mDFile) {
        // We set the context this way so we don't accidentally leak activities
        this.act = act;
        mApi = api;
        mFile = mDFile;
        path = mDFile.getFileId();
        mFileName = mDFile.getFileName();
        OnDownloadProgressDropboxChecked(FileHandler.PROGRESS_STATUS_START, 0);
    }

    File tmpFile;

    @Override
    protected Boolean doInBackground(Void... params) {
        try {

            final String cachePath = FileHandler.ROOT_LOCAL_FOLDER_DIR + "/" + mFile.getFileName();
            try {
                mFos = new FileOutputStream(cachePath);
            } catch (FileNotFoundException e) {
                mErrorMsg = "Couldn't create a local file to store the image";
                return false;
            }

            ProgressListener mProgressLisenter = new ProgressListener() {

                @Override
                public void onProgress(long arg0, long arg1) {
                    // TODO Auto-generated method stub
                    tmpFile = new File(cachePath);
                    OnDownloadProgressDropboxChecked(FileHandler.PROGRESS_STATUS_ONPROGRESS, (int) (arg0 * 100 / arg1));
                    Log.d("Dolphin got interval", String.valueOf(tmpFile.length() + " - " + arg0 + " - " + arg1));
                }

                @Override
                public long progressInterval() {
                    return 100;
                }
            };
            mDownloaded = mApi.getFile(mFile.getFileId(), null, mFos, mProgressLisenter);

        } catch (DropboxUnlinkedException e) {
            mErrorMsg = "Unlinked";
        } catch (DropboxPartialFileException e) {
            // We canceled the operation
            mErrorMsg = "Download canceled";

        } catch (DropboxServerException e) {
            // Server-side exception. These are examples of what could happen,
            // but we don't do anything special with them here.
            if (e.error == DropboxServerException._304_NOT_MODIFIED) {
                // won't happen since we don't pass in revision with metadata
            } else if (e.error == DropboxServerException._401_UNAUTHORIZED) {
                // Unauthorized, so we should unlink them. You may want to
                // automatically log the user out in this case.
            } else if (e.error == DropboxServerException._403_FORBIDDEN) {
                // Not allowed to access this
            } else if (e.error == DropboxServerException._404_NOT_FOUND) {
                // path not found (or if it was the thumbnail, can't be
                // thumbnailed)
            } else if (e.error == DropboxServerException._406_NOT_ACCEPTABLE) {
                // too many entries to return
            } else if (e.error == DropboxServerException._415_UNSUPPORTED_MEDIA) {
                // can't be thumbnailed
            } else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) {
                // user is over quota
            } else {
                // Something else
            }
            // This gets the Dropbox error, translated into the user's language
            mErrorMsg = e.body.userError;
            if (mErrorMsg == null) {
                mErrorMsg = e.body.error;
            }
        } catch (DropboxIOException e) {
            // Happens all the time, probably want to retry automatically.
            mErrorMsg = "Network error.  Try again.";
        } catch (DropboxParseException e) {
            // Probably due to Dropbox server restarting, should retry
            mErrorMsg = "Dropbox error.  Try again.";
        } catch (DropboxException e) {
            // Unknown error
            mErrorMsg = "Unknown error.  Try again.";
        } finally {
            if (mFos != null) {
                try {
                    mFos.close();
                    return true;
                } catch (IOException e) {
                }
            }
        }
        return false;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        OnDownloadProgressDropboxChecked(FileHandler.PROGRESS_STATUS_FINISH, 0);
        if (result) {
            OnDownloadDropboxChecked(TRUE, "Download complete");
        } else {
            OnDownloadDropboxChecked(FALSE, mErrorMsg);
        }
    }

    OnAsyncDownloadListener onAsyncDownloadListener;
    OnAsyncDownloadProgressListener onAsyncDownloadProgressListener;

    private void OnDownloadDropboxChecked(int res, String messenger) {
        if (onAsyncDownloadListener != null) {
            onAsyncDownloadListener.OnAsyncDownload(res, messenger);
        }
    }

    private void OnDownloadProgressDropboxChecked(int status, int percent) {
        if (onAsyncDownloadProgressListener != null) {
            onAsyncDownloadProgressListener.OnAsyncDownloadProgress(status, percent);
        }
    }

    public void setOnAsyncDownloadListener(OnAsyncDownloadListener listener) {
        onAsyncDownloadListener = listener;
    }

    public void setOnAsyncDownloadProgressListener(OnAsyncDownloadProgressListener listener) {
        onAsyncDownloadProgressListener = listener;
    }

    public interface OnAsyncDownloadListener {
        public abstract void OnAsyncDownload(int res, String messenger);
    }

    public interface OnAsyncDownloadProgressListener {
        public abstract void OnAsyncDownloadProgress(int status, int percent);
    }
}

由 Asynctask 的“OnDownloadDropboxChecked()”引起的错误在 getFile() 之前触发。所以它返回一个错误的通知。

4

1 回答 1

2

将我的评论转换为答案:

如果我没看错,您使用的是 Android Core API SDK,对吗?如果是这样,我认为当 mApi.getFile 返回时,该文件已下载。所以你可以在下一行做任何你需要做的事情。

于 2013-09-06T05:52:29.633 回答