android - 在 DownloadManager DOWNLOAD_COMPLETE 广播接收器上接收广播 Intent 时出错
问题描述
当我尝试从 Android 下载管理器获取下载文件的状态时,出现以下错误。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.purelightaudio.healer, PID: 24201
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.DOWNLOAD_COMPLETE flg=0x10 pkg=com.purelightaudio.healer (has extras) } in com.purelightaudio.healer.network.FileDownLoadService$1@3f6d991
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1132)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:68)
at android.database.CursorWrapper.getInt(CursorWrapper.java:122)
at android.database.CursorWrapper.getInt(CursorWrapper.java:122)
at android.app.DownloadManager$CursorTranslator.getLong(DownloadManager.java:1485)
at android.app.DownloadManager$CursorTranslator.getInt(DownloadManager.java:1477)
at com.purelightaudio.healer.network.FileDownLoadService.getDownloadStatus(FileDownLoadService.java:146)
at com.purelightaudio.healer.network.FileDownLoadService.access$100(FileDownLoadService.java:31)
at com.purelightaudio.healer.network.FileDownLoadService$1.onReceive(FileDownLoadService.java:230)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1122)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
并授予读取、写入存储和访问网络/国际的权限
private void downloadFile(String mediaTitle, final Track track, DownloadManager downloadManager, int downloadCount) {
Uri uri = Uri.parse(track.getTrackUrl());
folder = new File(mContext.getFilesDir().toString() + MEDIA_FOLDER);
if (!folder.exists()) {
folder.mkdir();
}
Log.d("Track aa",folder.toString()+ track.getTrackName());
downloadReference = downloadManager.enqueue(new DownloadManager.Request(uri)
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle(track.getTrackName())
.setDescription(mediaTitle)
.setVisibleInDownloadsUi(false)
.setDestinationInExternalPublicDir(folder.toString(), track.getTrackName()));
downloadMap.put(downloadReference,downloadCount);
}
广播接收器代码。
BroadcastReceiver onComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//check if the broadcast message is for our enqueued download
long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
int position = downloadMap.get(referenceId);
if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
if (getDownloadStatus(referenceId)) {
callBack.onCompleteDownloadNext(position);
Toast.makeText(context, "Download Complete " + media.getTracks().get(position).getTrackName(), Toast.LENGTH_SHORT).show();
Log.d("Track Downloaded", folder.toString() + media.getTracks().get(position).getTrackName());
Log.d("Track Downloaded", downloadManager.getUriForDownloadedFile(referenceId).toString());
dataBaseUtils.AddTrackLocalUrl(downloadManager.getUriForDownloadedFile(referenceId).toString(), media.getTracks().get(position).getTrackId());
} else {
callBack.onErrorDownload(position);
Toast.makeText(context, "Download Failed " + media.getTracks().get(position).getMediaTitle(), Toast.LENGTH_SHORT).show(); dataBaseUtils.AddTrackLocalUrl(Config.ERROR_DOWNLOAD,media.getTracks().get(position).getTrackId());
}
}
Log.d("Track Download",intent.getAction());
completeDownloadCount++;
if (media.getTracks().size() == completeDownloadCount){
callBack.onCompleteDownload(platListId!=0?String.valueOf(platListId):null);
}
}
};
下载状态码
/**
* Get File Download Status from the Download reference
* @return isSuccessful download boolean
* @param referenceId
*/
private boolean getDownloadStatus(long referenceId){
DownloadManager.Query downloadQuery = new DownloadManager.Query();
//set the query filter to our previously Enqueued download
downloadQuery.setFilterById(referenceId);
//Query the download manager about downloads that have been requested.
Cursor cursor = ((DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE)).query(downloadQuery);
//column for download status
int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
int status = cursor.getInt(columnIndex);
//column for reason code if the download failed or paused
int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
int reason = cursor.getInt(columnReason);
String statusText = "";
String reasonText = "";
boolean isSuccessful = false;
switch(status){
case DownloadManager.STATUS_FAILED:
statusText = "STATUS_FAILED";
break;
case DownloadManager.STATUS_PAUSED:
statusText = "STATUS_PAUSED";
break;
case DownloadManager.STATUS_PENDING:
statusText = "STATUS_PENDING";
break;
case DownloadManager.STATUS_RUNNING:
statusText = "STATUS_RUNNING";
break;
case DownloadManager.STATUS_SUCCESSFUL:
isSuccessful = true;
statusText = "STATUS_SUCCESSFUL";
break;
return isSuccessful;
}
有什么帮助吗?
解决方案
act=android.intent.action.DOWNLOAD_COMPLETE flg=0x10 pkg=com.purelightaudio.healer(有附加功能)} 在 com.purelightaudio.healer.network.FileDownLoadService$1@3f6d991 at android.app.LoadedApk$ReceiverDispatcher$Args.run( LoadedApk.java:1132) 在 android.os.Handler.handleCallback(Handler.java:751) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:154) ) 在 android.app.ActivityThread.main(ActivityThread.java:6077) 在 java.lang.reflect.Method.invoke(Native Method) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866 ) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)引起:android.database.CursorIndexOutOfBoundsException:请求索引 -1,在 android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136) 的 android.database.AbstractCursor.checkPosition(AbstractCursor.java:460) 的大小为 1
我敢打赌:
intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); 应该是
intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0L);
或者您应该在获取位置之前处理 getLongExtra() 的默认值,例如:
long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if(referenceId == -1)
return;
int position = downloadMap.get(referenceId);
我还建议您查看此博客: http: //jhshi.me/2013/12/02/how-to-use-downloadmanager/index.html,了解有关 Downloadmanager 的详细信息。
推荐阅读
- python - python中的咳嗽识别
- angular - 根据表单中的选择更改占位符
- python - TypeError:将一个函数传递给另一个函数时,“函数”对象不可下标
- stored-procedures - 如何将 VARCHAR2 的 TYPE VARRAY 参数列表传递给 PL-SQL 存储过程并在循环中访问参数列表
- python - 如何告诉python传递给函数的意外变量类型在上下文中是正确的
- sql - 如何通过 Oracle 中的 SQL 查询找到每个 id 的 TOP/MAX 值?
- reactjs - 为什么在 React 示例中使用 null 初始化 useRef?
- uwp - 如何在 UWP 应用程序中清除 MediaPlayer 的缓存?
- ios - swift 5 TextBox 值在标签中显示
- amazon-web-services - 带有traefik的ec2-instance前面的aws WAF