Android 9.0 简单适配

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shijianduan1/article/details/88969249

转载请声明,本文来自:


本文仅描述当前项目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.IActivityManagerStub.onTransactStub.onTransactbroadcastIntent(IActivityManager.java:10171)atandroid.app.IActivityManager(IActivityManager.java:10171) at android.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

参考:Android发送权限受限的广播,指定接受方!

<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);
               }
     }

适配修改:
莫名其妙的好了, 问题就出现了一次,后面就没有复现了,待后续观察

展开阅读全文

没有更多推荐了,返回首页