问题描述
1. 问题描述昨晚在更新了公司的app,接着推送出去了,发现有人反馈说自动更新用不了。我调试了一下,定位到代码和报错信息如下:代码:
try { //创建下载任务,downloadUrl就是下载链接 DownloadManager.Request request = new DownloadManager.Request(Uri.parse('xxxx下载链接')) .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOCUMENTS, 'Honey_.apk') .setTitle('下载标题') .setMimeType('') .setVisibleInDownloadsUi(true) .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) .setDescription('下载的具体描述'); //获取下载管理器 DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); //将下载任务加入下载队列,否则不会进行下载 long TaskID = downloadManager.enqueue(request); LogUtils.e(OpenLog,TAG,'TaskId:'+TaskID);} catch (Exception e) { LogUtils.e(OpenLog,TAG,'Exception2:'+e.getMessage());}
在long TaskID = downloadManager.enqueue(request);这里,抛出异常了:
E/MainActivity: Exception2:need WRITE_EXTERNAL_STORAGE permission to use DESTINATION_FILE_URI: uid 10207 does not have android.permission.WRITE_EXTERNAL_STORAGE.2. 解决答案
报错信息是,我没有声明权限?查了一下,我是有声明的:
<?xml version='1.0' encoding='utf-8'?><manifest xmlns:android='http://schemas.android.com/apk/res/android' package='testmodules'> <uses-permission android:name='android.permission.INTERNET' /> <uses-permission android:name='android.permission.WRITE_EXTERNAL_STORAGE' /> <applicationandroid:name='.chestnut.MyApplication'android:allowBackup='true'android:icon='@mipmap/app_ico'android:label='@string/app_name'android:supportsRtl='true'android:theme='@style/AppTheme'><activity android:name='.chestnut.MainActivity'> <intent-filter><action android:name='android.intent.action.MAIN' /><category android:name='android.intent.category.LAUNCHER' /> </intent-filter></activity><activity android:name='.chestnut.Main2Activity' /><activity android:name='.chestnut.DialogActivity' android:theme='@style/DialogTransparent' /> </application></manifest>
之前一直是这样声明的,也没有报错什么的,然后,Google,百度一下,发现,要写成如下的:
<?xml version='1.0' encoding='utf-8'?><manifest xmlns:android='http://schemas.android.com/apk/res/android' package='testmodules'> <uses-permission android:name='android.permission.INTERNET' /> <uses-permission android:name='android.permission.WRITE_EXTERNAL_STORAGE' /> <applicationandroid:name='.chestnut.MyApplication'android:allowBackup='true'android:icon='@mipmap/app_ico'android:label='@string/app_name'android:supportsRtl='true'android:theme='@style/AppTheme'><activity android:name='.chestnut.MainActivity'> <intent-filter><action android:name='android.intent.action.MAIN' /><category android:name='android.intent.category.LAUNCHER' /> </intent-filter></activity> </application> <uses-permission android:name='android.permission.WRITE_EXTERNAL_STORAGE' /></manifest>
额,Application开始前,Manifest开始后,要加入写权限,Application结束后,Manifest结束前,要加入写权限,这样做,才,没问题...
那,是为什么要这样做...?
问题解答
回答1:这解决办法太奇怪了, 我相信这不是正解!
Android 6.0 (API LEVEL 23) 以后都需要动态申请权限, 当然也需要在AndroidManifest.xml中声明该权限. 动态权限申请要求客户端在执行操作前, 以对话窗口的形式主动向用户申请权限. 如果申请成功, 那么接着执行后续操作; 若在若申请失败了(或者根本没去申请)的情况下, 直接执行需要申请权限的操作, 那就等着报错吧...
github上有很多封装得很好的库, 可以自己去了解下. 强烈推荐使用:
googlesamples/easypermissions
p.s.其他的库总会有一些问题, 具体可以看issues.