Android各版本适配之8.0

相关链接:

●安装apk的权限

首先第一步:我们需要在清单文件中添加一项权限
 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> 
有了这个权限之后,安装apk时判断:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !getPackageManager().canRequestPackageInstalls()){
   PermissionUtil.requestPermissions(this,PermissionUtil.PERMISSION_INSTALL_PACKAGES_CODE, Manifest.permission.REQUEST_INSTALL_PACKAGES);
}

具体权限管理请移步文章开头的6.0的权限管理文章查看。

通知栏的适配

Android O版本对通知做了规范性的控制,强制用户在发送通知的时候,对通知进行系统性的管理,新增了channel渠道功能:

private String Notification_ID = "5";
private String Notification_CHANNEL_1 = "channel5";

private void showNotification(long cancelTime, String text) {
   try {
      Context app = context.getApplicationContext();
      NotificationManager nm = (NotificationManager) app
            .getSystemService(Context.NOTIFICATION_SERVICE);
      final int id = Integer.MAX_VALUE / 13 + 1;
      nm.cancel(id);

      long when = System.currentTimeMillis();
      Notification notification;
      PendingIntent pi = PendingIntent.getActivity(app, 0, new Intent(), 0);
      if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){
         NotificationChannel
               channel = new NotificationChannel(String.valueOf(Notification_ID), Notification_CHANNEL_1, NotificationManager.IMPORTANCE_LOW);
         channel.enableLights(true);//是否在桌面icon右上角展示小红点
         channel.setLightColor(Color.GREEN);//小红点颜色
         channel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
         nm.createNotificationChannel(channel);

         notification = new Notification.Builder(context)
               .setChannelId(String.valueOf(Notification_ID))//该句适配android 8.0 版本
               .setSmallIcon(notifyIcon)
               .setContentTitle(notifyTitle)
               .setTicker(text)
               .setContentText(text)
               .setWhen(when)
               .setContentIntent(pi).setNumber(0)
               .getNotification();
         notification.flags |= Notification.FLAG_AUTO_CANCEL;

      }else {
         notification = new Notification.Builder(context)
               .setSmallIcon(notifyIcon)
               .setContentTitle(notifyTitle)
               .setTicker(text)
               .setContentText(text)
               .setContentIntent(pi).setNumber(0)
               .setWhen(when)
               .getNotification();
         notification.flags |= Notification.FLAG_AUTO_CANCEL;
      }

      nm.notify(id, notification);

      if (cancelTime > 0) {
         Message msg = new Message();
         msg.what = MSG_CANCEL_NOTIFY;
         msg.obj = nm;
         msg.arg1 = id;
         UIHandler.sendMessageDelayed(msg, cancelTime, this);
      }
   } catch (Exception e) {
      e.printStackTrace();
   }
}
这样就会在8.0系统上弹出通知了。当然还需要及时的关闭通知,当更新进度条加载完成或者其他时候
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    //关闭通知通道
    notificationManager.deleteNotificationChannel("1");
}
悬浮框(7.0,8.0会崩溃)
在一些广播中需要弹出对话框的应用场景,没有依附的activity,这个时候就可以用悬浮窗。
在Android系统中,如果应用需要弹出一个悬浮窗口,就需要申请一项特殊权限“
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

Android O之前的系统中申请了该权限后,再给对应的window设置type:WindowManager.LayoutParams.TYPE_SYSTEM_ALERT悬浮窗口就可以显示出来。但是在Android O的系统中,google规定申请"android.permission.SYSTEM_ALERT_WINDOW"权限的应用需要给悬浮窗设置type:WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY.

悬浮窗口才能显示出来,如果不设置该TYPE,会Crash,8.0代码修改如下:

public static void showLogoutDialog(final Context context) {
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    View view = View.inflate(context, R.layout.dialog_logout, null);
    builder.setView(view);
    final AlertDialog dialog = builder.create();
    
    //设置弹出全局对话框,但是这句话并不能解决在android的其他手机上能弹出来(例如用户华为p10 就无法弹框)
    // dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_TOAST);
    
    //只有这样才能弹框
    if (Build.VERSION.SDK_INT>=26) {//8.0新特性
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
    }else{
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    }
    dialog.show();
}
另外,6.0后需要申请悬浮窗权限,属于特殊权限,关于此权限的申请请看文章开头的6.0的适配文章链接;

透明Activity报错

Android 8.0透明Activity报错 "Only fullscreen activities can request orientation"

1、分析问题

首先,我的代码是这样的: 
style.xml

<style name="app_transparent_activity" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowContentTransitions">true</item>
    <item name="android:windowSoftInputMode">adjustPan</item>    <item name="android:windowDrawsSystemBarBackgrounds">false</item>
    <item name="android:windowBackground">@color/app_transparent_color</item>
    <item name="android:windowIsTranslucent">true</item>//透明    <item name="android:windowIsFloating">true</item>//悬浮
</style>
  • AndroidManifest.xml
<activity
    android:name=".appmanager.mianframe.UsagePermissionGuideActivity"
    android:launchMode="singleInstance"
    android:screenOrientation="portrait"
    android:theme="@style/app_transparent_activity"/>

从上面可以看出,我的activity是一个状态栏透明并且背景透明的activity。在26的编译版本时是可以正常的使用的,但是当把编译版本升级到27时,就会出现”Only fullscreen activities can request orientation”异常。这是google出于安全的考虑,对android8.0以后的版本做的处理,当一个Activity固定方向并且是透明的,在8.0以后的版本中就会抛出异常。相关源码如下:

Entry ent = AttributeCache.instance().get(packageName,realTheme, com.android.internal.R.styleable.Window, userId);
final boolean translucent = ent != null && (ent.array.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, false)|| (!ent.array.hasValue(
                com.android.internal.R.styleable.Window_windowIsTranslucent) &&  ent.array.getBoolean(com.android.internal.R.styleable.Window_windowSwipeToDismiss,false)));
fullscreen = ent != null && !ent.array.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent;
fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array);
noDisplay = ent != null && ent.array.getBoolean(com.android.internal.R.styleable.Window_windowNoDisplay, false);

if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen && appInfo.targetSdkVersion >= O) {
    throw new IllegalStateException("Only fullscreen activities can request orientation");
}

上面是27的源码片段,通过上面我们可以看出当三个条件同时满足的时候,系统会抛出”Only fullscreen activities can request orientation”异常。先分别来说说这三个条件都表示什么意思:

  1. ActivityInfo.isFixedOrientation(requestedOrientation) —— 表示判断当前的|Activity是否固定了方向
  2. fullscreen —— 表示Activity是否是透明的或者是否悬浮在Activity上,是透明的或者悬浮在Activity上fullscreen就等于false
  3. appInfo.targetSdkVersion >= O —— 表示版本号大于等于26

当以上的三个条件同时满足的时候,系统框架就会抛出异常。

2、解决问题的方法

这个问题在最新的SDK中已经修复,我们在API Level 27的设备上已经无法重现,但我们手头的API Level 26的设备还是能重现。而且根据上面的代码来看,如果想保留当前Activity的style,“isTranslucentOrFloating”的逻辑根本没法绕过,所以想绕开很难,目前能想到的大概两个方向:

  1. 1.推迟SDK升级,等官方修复被大多数设备采用;
  2. 2.升级SDK,但重构一下代码,看看已有的非“fullscreen” Activity是不是都是必要的,例如用Fragment实现周围半透明效果,能不能直接把Fragment加入到当前Activity(当然Detach Fragment是有重绘View的开销的)。
  3. 3.使用Dialog代替透明的Activity
  4. 4.不固定Activity的方向
  5. 5.使用不透明且不是悬浮的主题(我采用此解决办法,8.0以后改为不透明不悬浮)
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android是一个开源的移动操作系统,由Google开发。它的各个版本都有不同的特性和适配要求。下面是Android各个版本适配情况: 1. Android 1.0:这是Android的首个正式版本,发布于2008年。它主要适配了当时的早期智能手机。 2. Android 1.5 Cupcake:这个版本引入了许多新特性,包括虚拟键盘、文本选择和复制功能等。它的适配要求相对较低,可以在较旧的设备上运行。 3. Android 1.6 Donut:这个版本增加了搜索框和快捷方式等功能。它的适配要求与Cupcake相似。 4. Android 2.0/2.1 Eclair:这个版本引入了许多新特性,包括支持多点触控、HTML5视频播放和Live壁纸等。它的适配要求相对较高,需要较新的设备支持。 5. Android 2.2 Froyo:这个版本引入了许多新特性,包括支持移动热点和Adobe Flash等。它的适配要求与Eclair相似。 6. Android 2.3 Gingerbread:这个版本引入了许多新特性,包括支持NFC和下载管理器等。它的适配要求相对较高,需要较新的设备支持。 7. Android 4.0 Ice Cream Sandwich:这个版本引入了许多新特性,包括全新的用户界面和面部解锁等。它的适配要求相对较高,需要较新的设备支持。 8. Android 4.1/4.2/4.3 Jelly Bean:这个版本引入了许多新特性,包括Google Now和通知增强等。它的适配要求与Ice Cream Sandwich相似。 9. Android 4.4 KitKat:这个版本引入了许多新特性,包括透明状态栏和打印支持等。它的适配要求相对较高,需要较新的设备支持。 10. Android 5.0/5.1 Lollipop:这个版本引入了许多新特性,包括Material Design和多用户支持等。它的适配要求相对较高,需要较新的设备支持。 11. Android 6.0 Marshmallow:这个版本引入了许多新特性,包括指纹识别和运行时权限等。它的适配要求相对较高,需要较新的设备支持。 12. Android 7.0/7.1 Nougat:这个版本引入了许多新特性,包括分屏模式和通知增强等。它的适配要求相对较高,需要较新的设备支持。 13. Android 8.0/8.1 Oreo:这个版本引入了许多新特性,包括自适应图标和通知渠道等。它的适配要求相对较高,需要较新的设备支持。 14. Android 9 Pie:这个版本引入了许多新特性,包括手势导航和应用程序切片等。它的适配要求相对较高,需要较新的设备支持。 15. Android 10:这个版本引入了许多新特性,包括暗黑模式和系统级录屏等。它的适配要求相对较高,需要较新的设备支持。 16. Android 11:这个版本引入了许多新特性,包括聊天气泡和无线Android Auto等。它的适配要求相对较高,需要较新的设备支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值