生活虐你千百遍,你要待生活如初恋!!
今天仍然很忙,抽出1h,来梳理下内容
这里简单记录下在工作过程中,适配Android8遇到的坑,Android 9 、10 、持续更新...
当targetSdkVersion小于26时,没有问题,当targetSDK等于26时,就会出现下述问题。
(1)APK文件下载失败
(2)通知栏不显示
(3)下载成功没有跳出应用安装界面
问题1: APK文件下载失败
是因为代码中申请的其实是READ_EXTERNAL_STORAGE读存储权限,这在Android O(Android 8.0)之前是没有任何问题的,因为读写是一组权限,同属存储权限,只要申请了同组权限中的一个,同组中的其他在清单文件中列出了的权限也就被授予了。但是Android O(Android 8.0)运行时权限有了变动,就是系统只会授予应用明确请求的权限,然而一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准,但是还是需要去申请,这点和Android O(Android 8.0)之前不同。由于这里创建下载文件,实际上是往存储中写文件,需要写存储权限WRITE_EXTERNAL_STORAGE,于是将代码点击更新时申请READ_EXTERNAL_STORAGE改为申请WRITE_EXTERNAL_STORAGE。运行测试,APK文件是可以下载成功了。第一个问题得到解决。
问题2: 通知栏不显示
在Android O(Android 8.0)之前的手机上,更新下载APK文件时,通知栏会显示下载进度的通知,然而Android O(Android 8.0)的手机上,targetSDK等于26时,下载文件并没有通知栏显示。查看官网Android O行为变更,发现通知的创建与显示发生了变化,创建通知之前还需要创建一个NotificationChannel
示例代码如下:
private NotificationManagernotificationManager;
private Notificationnotification; //下载通知进度提示
private Notification.Builderbuilder;
private boolean flag =false; //进度框消失标示 之后发送通知
private final static int NOTIFY_ID =100;
NotificationCompat.BuildermBuilder =null;
private void showNotification() {
notificationManager = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
String CHANNEL_ID ="your_custom_id";//应用频道Id唯一值, 长度若太长可能会被截断,
String CHANNEL_NAME ="your_custom_name";//最长40个字符,太长会被截断
mBuilder =new NotificationCompat.Builder(mContext, CHANNEL_ID);
// notification = new NotificationCompat.Builder(mContext, CHANNEL_ID)
final Notification notification =mBuilder.setContentTitle("")
.setSmallIcon(R.mipmap.logo_jgz_icon)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.ic_launcher_round))
.setAutoCancel(true)
.build();
//Android 8.0 以上需包添加渠道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel =new NotificationChannel(CHANNEL_ID,
CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(notificationChannel);
}
notificationManager.notify(NOTIFY_ID, notification);
}
问题3:APK文件下载成功没有正常跳到应用安装界面
Android O (Android 8.0) 中,Google 移除掉了容易被滥用的“允许未知来源”应用的开关,在安装 Play Store 之外的第三方来源的 Android 应用的时候,竟然没有了“允许未知来源”的检查框,如果你还是想要安装某个被自己所信任的开发者的 app,则需要在每一次都手动授予“安装未知应用”的许可。
首先在AndroidManifest.xml 清单文件中添加安装未知来源应用的权限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
然后在用户点击更新时判断是否开启了该应用的“允许安装未知来源”的权限,没有的话,就引导用户去开启该应用的“允许安装未知来源”的权限,判断代码如下:
private void installAPK(){
boolean hasInstallPerssion = getPackageManager().canRequestPackageInstalls();
if (hasInstallPerssion ) {
//安装应用的逻辑
intentAPK()
} else {
//跳转至“安装未知应用”权限界面,引导用户开启权限,可以在onActivityResult中接收权限的开启结果
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
startActivityForResult(intent, REQUEST_CODE_UNKNOWN_APP);
}
}
//接收“安装未知应用”权限的开启结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_UNKNOWN_APP) {
installAPK();
}
}
//安装应用的逻辑
priviate void intentAPK(){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
File file = new File(absolutePath);
Log.e("install", absolutePath);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 7.0+以上版本Uri apkUri = FileProvider.getUriForFile(BaseApps.getInstance(), BaseApps.getInstance().getPackageName() + ".fileProvider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
}
startActivity(intent);
}
到此,今天的内容整理完毕,继续回到工作的烧脑状态...