转载请声明,本文来自:
本文仅描述当前项目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.IActivityManager S t u b . o n T r a n s a c t Stub.onTransact Stub.onTransactbroadcastIntent ( I A c t i v i t y M a n a g e r . j a v a : 10171 ) a t a n d r o i d . a p p . I A c t i v i t y M a n a g e r (IActivityManager.java:10171) at android.app.IActivityManager (IActivityManager.java:10171)atandroid.app.IActivityManagerStub.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);
}
}
适配修改:
莫名其妙的好了, 问题就出现了一次,后面就没有复现了,待后续观察