targetSdk 28适配

升级配置

1.编译的build tool版本
build_tool_version=28.0.3
compile_sdk_version=28
min_sdk_version=16
target_sdk_version=28
2.gradle升级到5.1.1
distributionUrl=https://services.gradle.org/distributions/gradle-5.1.1-all.zip
3.升级gradle buildTools,由3.0.1升级到3.4.1(配置app bundle 至少3.4.0)
'com.android.tools.build:gradle:3.4.1'

升级遇到的问题

1. java.io.IOException: Cleartext HTTP traffic to
错误1: java.io.IOException: Cleartext HTTP traffic to 包名 not permitted
原因分析:
从Android 6.0开始引入了对Https的推荐支持,与以往不同,Android P的系统上面默认所有Http的请求都被阻止了。


原本这个属性的默认值从true改变为false
解决办法:
AnroidManifest.xml中的application显示设置


更为根本的解决办法是修改应用程序中Http的请求为Https,当然这也需要服务端的支持。

2.在8.0之后前台服务使用startForegroundService()启动
错误2: 在8.0之后前台服务使用startForegroundService()启动,需要权限

3. android 8.0 报错StartForeground Bad Notification Error

错误3:android 8.0 报错StartForeground Bad Notification Error 解决方法
在android8.0后 需要给notification设置一个channelid

public final static String channelName="cn.george.app";

mNotificationManager.createNotificationChannel(
new NotificationChannel(channelName,
"Channel One",
NotificationManager.IMPORTANCE_HIGH));

NotificationCompat.Builder builder =
new NotificationCompat.Builder(this,channelName)
.setContent(remoteViews)
.setSmallIcon(R.mipmap.pic);

4.Only fullscreen opaque activities can request orientation

错误4:Android 8.0.0错误:Only fullscreen opaque activities can request orientation
原因:对activity的theme设置了

<--这个属性true不能和这个Activity指定屏幕方向同时使用-->
true
8.0.0源码中

if (isTranslucentOrFloating) {
throw new IllegalStateException(
"Only fullscreen opaque activities can request orientation");
}
抛出了异常,会在8.0.0手机出现闪退,在8.0.0之后的版本8.0.1做了处理。
解决办法,item改为

如果非要使用这个属性true,那就不要指定屏幕的方向
false

或者

去掉

android:screenOrientation="xx"
5.android.support.v4.app.Fragment.setMenuVisibility(boolean)' on a null object reference

错误5:android.support.v4.app.Fragment.setMenuVisibility(boolean)' on a null object reference
android.support.v4.app.FragmentPagerAdapter.setPrimaryItem(Unknown Source:23)
原因:
在api25的时候:

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment)object;
if (fragment != mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem.setMenuVisibility(false);
mCurrentPrimaryItem.setUserVisibleHint(false);
}
if (fragment != null) {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
}
mCurrentPrimaryItem = fragment;
}
}
在api28的时候

public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
this.setPrimaryItem((View)container, position, object);
}
发现28的时候object标记了@NoNull不能为null。则否则null异常。
所以不能传null。
6. Android8.0 属性动画组合AnimatorSet增加了setCurrentPlayTime和reverse方法
允许倒过来播放属性动画组合。
setCurrentPlayTime和reverse方法的调用方式示例如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
animSet.setCurrentPlayTime(0); // 设置当前播放的时间点
animSet.reverse(); // 从动画尾巴开始倒播至setCurrentPlayTime设置的时间点
}
7. 普通应用不允许修改系统设置
也就是Android8.0之后无法再调用系统设置的修改方法Settings.System.putInt,像原来在代码里调整屏幕亮度的办法就不再适用了。
8、悬浮窗要使用类型TYPE_APPLICATION_OVERLAY,原来的类型TYPE_SYSTEM_ALERT从Android8.0开始被舍弃了。
设置悬浮窗类型的兼容代码示例如下:

    WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();
    // 设置为TYPE_SYSTEM_ALERT类型,才能悬浮在其它页面之上
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        // 注意TYPE_SYSTEM_ALERT从Android8.0开始被舍弃了
        wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
    } else {
        // 从Android8.0开始悬浮窗要使用TYPE_APPLICATION_OVERLAY
        wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
    }

9、获取设备序列号的方式由Build.SERIAL改为Build.getSerial(),同时还需要先获得权限READ_PHONE_STATE
获取设备序列号的兼容代码示例如下:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        et_wifi_name.setText(Build.getSerial());
    } else {
        et_wifi_name.setText(Build.SERIAL);
    }

另android10.0变更
1、Android10默认开启沙箱模式,即使已经动态申请了存储卡读写权限,在外部存储上读写文件仍然失败。
首先确保代码已经添加动态申请存储权限的逻辑,然后给AndroidManifest.xml中的application节点增加以下属性:

        android:requestLegacyExternalStorage="true"

还要补充新的权限配置MANAGE_EXTERNAL_STORAGE,配置样例如下:

    
    

2、普通应用无法开启或者关闭WiFi功能
一旦build.gradle的targetSdkVersion设置29或更高数值(表示目标SDK版本为Android11或以上版本),则调用WifiManager实例的setWifiEnabled方法始终返回false,也就是无法成功设置WiFi的启用状态。此时要在代码中添加版本号判断,如果当前系统版本大于等于29,就不再开关WiFi,代码例子如下:

        if (Build.VERSION.SDK_INT >= 29) { // Android10之后,普通应用不能开关WiFi
            ck_wlan.setEnabled(false);
        } else {
            ck_wlan.setOnCheckedChangeListener(this);
        }

3、Android10新增了健身运动权限ACTIVITY_RECOGNITION
使用计步器时需要声明健身运动权限,改动点说明如下:
(1)修改AndroidManifest.xml,增加新的权限配置

    
    

(2)打开计步器页面时需要动态申请健身运动权限android.permission.ACTIVITY_RECOGNITION,代码片段如下:

if (Build.VERSION.SDK_INT >= 29) {
    // Android10.0之后使用计步器需要健身运动权限
    if (PermissionUtil.checkPermission(this, "android.permission.ACTIVITY_RECOGNITION", (int) v.getId() % 4096)) {
        startActivity(new Intent(this, StepActivity.class));
    }
}

Gradle build Tools升级问题

1、item下面不能有元素值,如下:
5
在buildConfig中配置res value的值
如果是第三方lib库中的
可在自己工程的ids.xml中配置一个无子元素的item
2、android.enableBuildCache=false 设置无效
gradle buildTools 2.2.3中enableBuildCache可设置不利用缓存编译
3.4.1中设置无效
2.2.3中设置过后编译,build文件夹中会出现:
/build/intermediates/bundles/default
/build/intermediates/exploded-aar
升级到3.4.1之后,以上两文件夹消失,只存在:
/build/intermediates/packaged-classes/release
引用的aar中拉取的maven仓库包都存在在~/.gradle/cache中

Android Q(10.0)版本新特性和兼容性适配

你可能感兴趣的:(targetSdk 28适配)