持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
Android 8
权限
在Android 8之前,如果一个应用申请运行时权限并且用户授予其权限,那么Android系统会将该权限同组的其他权限也一并授予应用。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//申请读权限
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, requestCode);
比如上面我们只是申请了SD卡的读取权限,但是一旦用户授予了该权限,我们的APP也会同时具有SD卡的写权限(WRITE_EXTERNAL_STORAGE
),而对于针对 Android 8.0 的应用,此行为已被纠正,Android系统只会授予明确申请的权限。
广播
移除掉了所有的隐式广播,对于针对 Android 8.0 的应用,我们需要使用显示广播进行注册。
透明主题的Activity
在做一些支付回调的界面的时候,我们喜欢将Activity主题设置为透明,但是在targetSdk=27,Android系统版本为8.0的手机上会出现一个bug。
java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
只有不透明的全屏Activity可以自主设置界面方向。要解决这个问题,我们要么舍弃透明效果,要么去掉screenOrientation
属性。
安装APK
Android 8.0去除了“允许未知来源”选项,如果我们的APP有安装apk的功能,就需要在AndroidManifest.xml
文件中添加安装未知来源应用的权限。
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
这样APP在安装apk的时候会自动询问用户并完成授权。
如果APP是应用商店类的,我们希望在安装之前就引导用户完成授权,这时候可以先检测是否具有安装权限。如果没有直接跳转权限界面,引导用户开启权限。
boolean hasPermission = getPackageManager().canRequestPackageInstalls()
canRequestPackageInstalls()
方法返回是否具有安装apk的权限。
Uri uri = Uri.parse("package:" + this.getPackageName());
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, uri);
startActivityForResult(intent, 100);
如果没有权限,就跳转至“安装未知应用”权限界面,引导用户开启权限。
通知栏
Android 8.0 引入了通知渠道,每个通知都需要配置渠道id和渠道名称,这样可以方便用户单独去关闭某个通知。
在8.0之前使用NotificationCompat.Builder就可以创建通知然后使用NotificationManager显示出来。
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(MainActivity.this)
.setContentTitle("title")
.setContentText("content")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher)) .build();
manager.notify(1,notification);
但是在8.0开始,我们还需要设置渠道的id和渠道的名称,然后在使用NotificationCompat.Builder创建通知的时候使用该渠道显示通知。
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = "channel_chat";
String channelName = "name";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
notificationManager.createNotificationChannel(channel);
Notification notification = new Notification.Builder(MainActivity.this, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentTitle("title")
.setContentText("content")
.build();
notificationManager.notify(1, notification);