背景
读取壁纸图片,在阳光沙滩上一个版本中我是用的Android官方lib是比较的,appcompat 1.3.1读取壁纸使用的权限是READ_MEDIA_IMAGES,为什么?这是as给我的提示,申请这个权限可以读取。低版本继续使用READ_EXTERNAL_STORAGE。
也就是在配置文件声明
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
当运行时判断当前是不是Android14,如果是申请READ_MEDIA_IMAGES,不是申请上面的。 在旧版lib中编译代码申请权限正常,读取也是正常。升级了ktx,appcompat等组件后居然直接崩溃了。
崩溃信息
Process: com.example.a202422, PID: 6160
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.a202422/com.example.a202422.MainActivity}: java.lang.SecurityException: Permission android.permission.READ_EXTERNAL_STORAGE denied for package com.example.a202422
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4084)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4244)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:99)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2657)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:222)
at android.os.Looper.loop(Looper.java:314)
at android.app.ActivityThread.main(ActivityThread.java:8816)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:569)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1090)
Caused by: java.lang.SecurityException: Permission android.permission.READ_EXTERNAL_STORAGE denied for package com.example.a202422
at android.os.Parcel.createExceptionOrNull(Parcel.java:3057)
at android.os.Parcel.createException(Parcel.java:3041)
at android.os.Parcel.readException(Parcel.java:3024)
at android.os.Parcel.readException(Parcel.java:2966)
at android.app.IWallpaperManager$Stub$Proxy.getWallpaperWithFeature(IWallpaperManager.java:1011)
at android.app.WallpaperManager$Globals.getCurrentWallpaperLocked(WallpaperManager.java:770)
at android.app.WallpaperManager$Globals.peekWallpaperBitmap(WallpaperManager.java:667)
at android.app.WallpaperManager$Globals.peekWallpaperBitmap(WallpaperManager.java:634)
at android.app.WallpaperManager.getDrawable(WallpaperManager.java:1008)
at android.app.WallpaperManager.getDrawable(WallpaperManager.java:970)
at com.example.a202422.MainActivity.onCreate(MainActivity.kt:42)
at android.app.Activity.performCreate(Activity.java:8894)
at android.app.Activity.performCreate(Activity.java:8859)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1470)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4066)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4244)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:99)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2657)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:222)
at android.os.Looper.loop(Looper.java:314)
at android.app.ActivityThread.main(ActivityThread.java:8816)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:569)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1090)
Caused by: android.os.RemoteException: Remote stack trace:
at android.os.storage.StorageManager.checkPermissionAndAppOp(StorageManager.java:1828)
at android.os.storage.StorageManager.checkPermissionAndAppOp(StorageManager.java:1805)
at android.os.storage.StorageManager.checkPermissionAndAppOp(StorageManager.java:1875)
at android.os.storage.StorageManager.checkExternalStoragePermissionAndAppOp(StorageManager.java:1943)
at android.os.storage.StorageManager.checkPermissionReadImages(StorageManager.java:1920)
从这个信息中很容易找到原因,Permission android.permission.READ_EXTERNAL_STORAGE denied for package com.example.a202422 就说我没申请权限,但是,但是:
defaultConfig {
applicationId = "com.example.a202422"
minSdk = 26
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
我的设备是Android14红米Note14 pro,编译的target 35(Android15),不管34还是35都是一样的,我已经超过32,不应该申请READ_EXTERNAL_STORAGE权限,这个权限最大支持32(理论上),特别上架谷歌要小心写权限范围。
好吧,既然你需要这个权限我就申请试试。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
直接声明,也不设置max了。
val permissions = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
)
for (permission in permissions) {
if (ContextCompat.checkSelfPermission(
this,
permission
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(this, permissions, 200)
return
}
}
跑起来,居然把授权拉起来了,真有你的澎湃OS,还能申请。我直接同意。
就离谱??????????????????????????
但是做适配我又需要最新lib组件,必须升级。
放弃适配,高版本继续申请READ_MEDIA_IMAGES,返回null展示默认图片背景图。