轉載請聲明,本文來自:
本文僅描述當前項目apk遇到的適配9.0問題,所以不是全面的,請自行參考;
適配一:
純後臺服務,需要在AndroidManifest.xml添加權限
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
適配二:
java.lang.SecurityException: Permission Denial: reading provider-name uri content://provider-CONTENT_URI from pid=5114, uid=10065 requires 權限, or grantUriPermission()
at android.os.Parcel.createException(Parcel.java:1949)
at android.os.Parcel.readException(Parcel.java:1917)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:418)
at android.content.ContentResolver.query(ContentResolver.java:804)
at android.content.ContentResolver.query(ContentResolver.java:753)
at android.content.ContentResolver.query(ContentResolver.java:711)
at com.privateclass.ssl.ContentResolverUtils.quertData(ContentResolverUtils.java:30)
修改部分:
我是在MainActivity.class裏重寫方法的
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.d(TAG, "requestCode=" + requestCode + "; --->" + Arrays.toString(permissions)
+ "; grantResult=" + Arrays.toString(grantResults));
switch (requestCode) {
case 0: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
// request successfully, handle you transactions
} else {
// permission denied
// request failed
}
return;
}
default:
break;
}
}
參考:Android: requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
適配三:(這個是7.0的權限適配)
Sending non-protected broadcast action from system 1616:packagename/u0a64 pkg packagename
java.lang.Throwable
at com.android.server.am.ActivityManagerService.checkBroadcastFromSystem(ActivityManagerService.java:21275)
at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:21879)
at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:22021)
at android.app.IActivityManagerbroadcastIntentStub.onTransact(IActivityManager.java:167)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3311)
修改部分:
這是因爲“靜態廣播的exported爲true的時候必須同時加上permission限制”
8.0的只要求intent加上package就可, 現在還需要加上權限
參考:protected-broadcast 規範使用(ERROR: Sending non-protected broadcast)
在加權限的時候,還需要對權限進行聲明,不然會報錯
/system_process W/BroadcastQueue: Permission Denial: broadcasting Intent { XXXX (has extras) } from XXXX (pid=1628, uid=10038) requires XXXX due to receiver XXXX
<manifest
<!-- 此處聲明權限,可以在任意需要發送該廣播的app中聲明 -->
<uses-permission android:name="自定義的權限" />
<application
<receiver
android:name=".MsgReceiver"
android:enabled="true"
android:exported="true"
android:permission="自定義的權限">
</receiver>
</application>
<permission
android:name="自定義的權限"
android:protectionLevel="normal" />
</manifest>
適配四:(這個是8.0的Service適配)
ActivityManager: ANR in cn.digirun.update.smart
PID: 5212
Reason: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{45a21a7 u0 package/service}
Load: 2.36 / 2.21 / 2.24
CPU usage from 0ms to 9159ms later (2019-04-02 18:31:47.260 to 2019-04-02 18:31:56.419):
27% 922/system_server: 16% user + 11% kernel / faults: 5609 minor
修改部分:
在AndroidManifest中添加權限
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
在Service.class 中添加代碼
@Override
public void onCreate() {
super.onCreate();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
String Notifi_Channel = BaseApplication.context.getPackageName() + ".MDMConObsService";
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), Notifi_Channel);
notificationVersion(this, Notifi_Channel, "BackGround Service", false);
Notification notification = builder.build();
startForeground(1, notification);
}
mdmContentObserver = new MDMContentObserver(new Handler());
}
public static void notificationVersion(Context context, String channelId, String channelName, boolean voiceVibration) {
// String channelID = "cn.digirun.update.smart.Notification";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
if (!voiceVibration) {
channel.enableLights(false);
channel.enableVibration(false);
channel.setImportance(NotificationManager.IMPORTANCE_LOW);//設置爲low, 通知欄不會有聲音
}
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);
}
}
適配五:
System.err: java.net.UnknownServiceException: CLEARTEXT communication to .oss-cn-beijing.aliyuncs.com not permitted by network security policy
2019-04-04 10:47:58.126 429-429/? I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
2019-04-04 10:47:58.129 429-429/? I/chatty: uid=1000(system) /system/bin/surfaceflinger identical 2 lines
2019-04-04 10:47:58.129 429-429/? I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
2019-04-04 10:47:58.131 1580-1580 W/System.err: at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:139)
2019-04-04 10:47:58.131 1580-1580/ W/System.err: at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:195)
2019-04-04 10:47:58.131 1580-1580/ W/System.err: at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
2019-04-04 10:47:58.131 1580-1580/ W/System.err: at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
2019-04-04 10:47:58.131 1580-1580/ W/System.err: at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
2019-04-04 10:47:58.131 1580-1580/ W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
2019-04-04 10:47:58.131 1580-1580/ W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
2019-04-04 10:47:58.131 1580-1580/W/System.err: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at com.lzy.okgo.interceptor.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:93)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at okhttp3.RealCall.execute(RealCall.java:69)
2019-04-04 10:47:58.132 1580-1580/ W/System.err: at com.lzy.okgo.request.base.Request.execute(Request.java:383)
這個還是9.0默認取消了http的通訊,要使用https 導致的。
修改部分:
方法一:(臨時過渡)
在AndroidManifest.xml裏添加
<application
android:networkSecurityConfig="@xml/network_security_config">
</application>
在res/xml 目錄下新建文件夾 network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
方法二:
後期請將後臺和設備接口都替換成https協議
適配六:
找不到Activity
componentName = null
MyClass: Unexpected remote exception
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.qualcomm.update.REBOOT flg=0x10000000 (has extras) }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2014)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1675)
at android.app.ContextImpl.startActivity(ContextImpl.java:917)
at android.app.ContextImpl.startActivity(ContextImpl.java:888)
at android.content.ContextWrapper.startActivity(ContextWrapper.java:379)
下面是我在8.0的時候代碼,在9.0 的時候componentName爲null了
//兼容8.0 修改成以下
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ResolveInfo resolveInfo = getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
ComponentName componentName = intent.resolveActivity(getPackageManager());
Log.e(TAG, ": componentName = " + (componentName == null ? "null" : (componentName.getPackageName() + "|" + componentName.getClassName())));
if (componentName != null) {
intent.setComponent(componentName);
}
}
適配修改:
莫名其妙的好了, 問題就出現了一次,後面就沒有復現了,待後續觀察