近期项目做适配8.0,坑不断呀。首先 介绍下7.0和8.0中的一些修改,在7.0的中有共享文件的限制,对外提供的文件,不能显示文件路径;在8.0中限制了广播的注册方式,取消大部分静态注册广播。这些都是基本操作了,同时还有一些厂商自己的修改,以下只介绍项目中遇到的坑,如部分华为系统对DownloadManager中的网络有限制要求,在下载的是时候要设置好是wifi还是数据网络,不然免谈,最后说下一个卡了好久的大坑Android 8.0 Oreo 中,Google 移除掉了容易被滥用的“允许位置来源”应用的开关,在安装 Play Store 之外的第三方来源的 Android 应用的时候,竟然没有了“允许未知来源”的检查框,如果你还是想要安装某个被自己所信任的开发者的 app,则需要在每一次都手动授予“安装未知应用”的许可,这个不是重点。重点是到了安装的时候界面的只是一闪而过,没有任何提示,任何报错,完全是轻飘飘的来,轻飘飘的走,啥也不留下,问题都不知道怎么查。
坑已经介绍完,开始填坑,第一个坑广播坑监听安装完成广播,需要动态注册,单例加判空处理只注册一次
//初始化的时候判断是否为空,为空才将它初始化,这样就能保证始终存在一个。
if (snDownloadReceiver == null) {
intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.DOWNLOAD_COMPLETE");
intentFilter.addAction("android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED");
snDownloadReceiver = new SnDownloadReceiver();
GlobalContext.getInstance().context.registerReceiver(snDownloadReceiver, intentFilter);
}
第二个坑文件共享的坑首先在mainfest中配置
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.android7.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
之后在res目录下创建一个xml文件夹同时创建一个xml文件命名file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--
该方式提供在应用的外部存储区根目录的下的文件。
它对应Context#getExternalFilesDir(String) Context.getExternalFilesDir(null)
返回的路径。eg:”/storage/emulated/0/Android/data/com.jph.simple/files”
-->
<external-files-path
name="external_file_path"
path="Download/" />
</paths>
接着就看文件intent启动文件的地方
Intent intent = new Intent(Intent.ACTION_VIEW);
File apkFile = new File(GlobalContext.getInstance().getDownloadPath());
if (!apkFile.exists()) {
return;
}
//判断是否是AndroidN以及更高的版本
if (GlobalContext.getInstance().context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.N) {
// 由于没有在Activity环境下启动Activity,设置下面的标签
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = android.support.v4.content.FileProvider.getUriForFile(GlobalContext.getInstance().context, GlobalContext.getInstance().context.getPackageName() + ".android7.fileprovider", apkFile);
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + apkFile.getAbsolutePath()), "application/vnd.android.package-archive");
}
GlobalContext.getInstance().context.startActivity(intent);
第二个坑已经完成,之后就是华为限制了downloadmanager下载的坑,在下载之前对网络进行检测,记载网络类型,网络是否可用
private static boolean isNetworkOnline() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("ping -c 1 fiapp.suning.com");
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
boolean exitValue = ipProcess.waitFor(800, TimeUnit.MILLISECONDS);
return exitValue;
} else {
int exitValue = ipProcess.waitFor();
return (exitValue == 0);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return false;
}
public static boolean isNetConnect() {
try {
ConnectivityManager connectivityManager = (ConnectivityManager) GlobalContext.getInstance().context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if (info != null && info.isConnected()) {
//根据目前连接的网络设置网络类型
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
PayHelper.getInstance().setNetType(DownloadManager.Request.NETWORK_WIFI);
} else {
PayHelper.getInstance().setNetType(DownloadManager.Request.NETWORK_MOBILE);
}
return true;
}
} catch (Exception e) {
return false;
}
return false;
}
public static void downloadApk(Context context, String url) {
if (!isNetConnect() || !isNetworkOnline()) {
ToastUtil.showMessage(context.getResources().getString(R.string.snpay_no_internet));
return;
}
String serviceNameInString = Context.DOWNLOAD_SERVICE;
DownloadManager downloadManager = (DownloadManager) context.getSystemService(serviceNameInString);
Uri uri = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(uri);
/设置网络
request.setAllowedNetworkTypes(PayHelper.getInstance().getNetType());
//在通知栏中显示
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
request.setTitle("下载中...");
request.setVisibleInDownloadsUi(true);
//此处要和增加的xml文件中对应使用
File destFile = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "epa.apk");
if (destFile.exists()) {
destFile.delete();
}
request.setDestinationUri(Uri.parse("file://" + destFile.getAbsolutePath()));
//获得唯一下载id
long reqId = downloadManager.enqueue(request);
GlobalContext.getInstance().setDownloadId(reqId);
GlobalContext.getInstance().setDownloadPath(destFile.getPath());
}
好了还有最后一个坑就是8.0限制外部应用安装的问题,解决很简单
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />