注意事项:
6.0及以下用context.getFilesDir().getPath()或者context.getCacheDir().getPath();安装都会报Apk文件不正确,无法正常打开;
7.0及以上没有问题。
installApkO(8.0 需要判断是否允许了安装未知来源应用的权限)
private void installApkO(Context context, String downloadApkPath) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//是否有安装位置来源的权限
boolean haveInstallPermission = getPackageManager().canRequestPackageInstalls();
if (haveInstallPermission) {
KLog.i("8.0手机已经拥有安装未知来源应用的权限,直接安装!");
installApk(context, downloadApkPath);
} else {
final AlertDialog.Builder normalDialog = new AlertDialog.Builder(MainActivity.this);
normalDialog.setTitle("权限申请");
normalDialog.setMessage("安装应用需要打开安装未知来源应用权限,请去设置中开启权限!");
normalDialog.setPositiveButton("去设置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Uri packageUri = Uri.parse("package:" + getPackageName());
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageUri);
startActivityForResult(intent, 10086);
}
});
normalDialog.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
normalDialog.show();
}
} else {
// 8.0 以下
installApk(context, downloadApkPath);
}
}
installApk(7.0 及以上和6.0 及以下安装差异)
public void installApk(Context context, String downloadApk) {
File file = new File(downloadApk);
if (!file.exists()) {
ToastUtils.showLong("安装包不存在!");
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String type = getMimeType(file);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//7.0 及以上
Uri apkUri = FileProvider.getUriForFile(context, getPackageName() + ".provider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, type);
} else {
//6.0 及以下
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, type);
}
context.startActivity(intent);
}
getMimeType
private static String getSuffix(File file) {
if (file == null || !file.exists() || file.isDirectory()) {
return null;
}
String fileName = file.getName();
if (fileName.equals("") || fileName.endsWith(".")) {
return null;
}
int index = fileName.lastIndexOf(".");
if (index != -1) {
return fileName.substring(index + 1).toLowerCase(Locale.US);
} else {
return null;
}
}
public static String getMimeType(File file) {
String suffix = getSuffix(file);
if (suffix == null) {
return "file/*";
}
String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(suffix);
if (type != null || !type.isEmpty()) {
return type;
}
return "file/*";
}
onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 10086) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
boolean hasInstallPermission = getPackageManager().canRequestPackageInstalls();
//再次执行安装流程,包含权限判等
if (hasInstallPermission && !TextUtils.isEmpty(apkFilePath)) {
//再次启动安装流程
installApkO(MainActivity.this, apkFilePath);
}
}
}
}
getDiskCacheDir(6.0及以下用context.getFilesDir().getPath()或者context.getCacheDir().getPath();安装都会报包解析错误;)
public String getDiskCacheDir(Context context) {
String cachePath = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable()) {
// 不需要动态获取读写权限
cachePath = context.getExternalCacheDir().getPath();
} else {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
ApkUtil .checkApkExist(this, getPackageName());
return null;
}
// 不需要动态获取读写权限
cachePath = context.getCacheDir().getPath();
}
return cachePath;
}
ApkUtil
public class ApkUtil {
/**
* 应用市场包名
*/
private static final String[] PACKAGENAME = {
"com.tencent.android.qqdownloader", "com.qihoo.appstore", "com.baidu.appsearch", "com.xiaomi.market", "com.huawei.appmarket", "com.bbk.appstore",
"com.meizu.mstore", "com.wandoujia.phoenix2", "com.oppo.market", "cn.goapk.market", "com.android.vending", "com.lenovo.leos.appstore", "com.mappn.gfan"
};
public static boolean checkApkExist(Context context, String appPkg) {
try {
for (String packageName : PACKAGENAME) {
if (isAvilible(context, packageName)) {
launchAppDetail(context, appPkg, packageName);
return true;
}
}
} catch (RuntimeException e) {
e.printStackTrace();
}
return false;
}
/**
* 判断是否安装了某应用
*
* @param context
* @param packageName
* @return
*/
private static boolean isAvilible(Context context, String packageName) {
final PackageManager packageManager = context.getPackageManager();
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
List<String> pName = new ArrayList<String>();
if (pinfo != null) {
for (int i = 0; i < pinfo.size(); i++) {
String pn = pinfo.get(i).packageName;
pName.add(pn);
}
}
return pName.contains(packageName);
}
/**
* 启动到应用商店app详情界面
*/
private static void launchAppDetail(Context context, String appPkg, String marketPkg) {
try {
if (TextUtils.isEmpty(appPkg)) {
return;
}
Uri uri = Uri.parse("market://details?id=" + appPkg);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if (!TextUtils.isEmpty(marketPkg)) {
intent.setPackage(marketPkg);
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
}