廢話:bugly這些也挺好用的,偶爾需要自己寫...
1.請求安裝未知應用來源的權限
//配置權限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
btnInstall.setOnClickListener(v -> {
if (Build.VERSION.SDK_INT >= 26) {
boolean b = getPackageManager().canRequestPackageInstalls();
if (b) {
//存儲權限申請
requestWriteExternalStorage();
} else {
//請求安裝未知應用來源的權限
showDialogRequestInstall();
}
} else {
requestWriteExternalStorage();
}
});
//跳轉讓用戶手動開啓權限
private void showDialogRequestInstall() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("權限管理")
.setMessage("請開啓允許應用安裝權限")
.setPositiveButton("確定", (dialog, which) -> {
dialog.dismiss();
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
startActivityForResult(intent, Constant.REQUECT_INSTALL_PERMISSION);
});
builder.show();
}
2.權限請求
//隨便搜一下 有很多框架可以使用 這裏使用
implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar'
//配置權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
private void requestWriteExternalStorage() {
PermissionManager.newBuilder(this)
.setPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.callBack(new PermissionManager.PermissionRequestCallBack() {
@Override
public void successCallBack() {
//請求成功回調
downloadApk();
}
@Override
public void failureCallBack() {
//請求失敗回調
//提示用戶自己去權限管理處開啓權限
showGetPermissionDialog();
}
});
}
public static void showGetPermissionDialog(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("權限管理")
.setMessage("請前往權限管理開啓相應權限")
.setPositiveButton("前往", (dialogInterface, i) -> {
dialogInterface.dismiss();
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse(ConstantObject.PACKAGE_URL_SCHEME + context.getPackageName()));
context.startActivity(intent);
})
.setNegativeButton("取消", (dialogInterface, i) -> dialogInterface.dismiss());
builder.setCancelable(false);
builder.show();
}
//權限請求的工具類 可能有未知問題的 emmmm
public class PermissionManager {
private static PermissionManager mPermissionManager;
private static RxPermissions rxPermissions;
private String permission;
private PermissionManager() {
}
public static PermissionManager newBuilder(Activity activity) {
mPermissionManager = new PermissionManager();
rxPermissions = new RxPermissions(activity);
return mPermissionManager;
}
public PermissionManager setPermission(String permission){
this.permission = permission;
return this;
}
public void callBack(final PermissionRequestCallBack callBack) {
rxPermissions.request(permission)
.filter(it -> callBack!=null)
.subscribe(aBoolean -> {
if (aBoolean) {
callBack.successCallBack();
} else {
callBack.failureCallBack();
}
}, t-> t.printStackTrace());
}
public interface PermissionRequestCallBack {
void successCallBack();
void failureCallBack();
}
}
3.下載
//一般網絡請求框架都能下載文件的 這裏使用:
implementation 'com.liulishuo.filedownloader:library:1.7.4'
//配置權限
<uses-permission android:name="android.permission.INTERNET" />
//在Application裏初始化 FileDownloader.init(this);
//下載鏈接
private String apkUrl ="";
//下載存儲路徑 根目錄下的apk文件夾
private String apkPath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/apk/"+"yingyongming.apk";
private void downloadApk() {
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setMessage("下載中0%...");
alertDialog.setCancelable(false);
alertDialog.show();
FileDownloader.getImpl().create(apkUrl)
.setPath(apkPath)
.setListener(new FileDownloadListener() {
@Override
protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
}
@Override
protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
}
@Override
protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
alertDialog.setMessage("下載中"+(int)((double) soFarBytes / (double) totalBytes * 100)+"%...");
}
@Override
protected void blockComplete(BaseDownloadTask task) {
}
@Override
protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
}
@Override
protected void completed(BaseDownloadTask task) {
alertDialog.setMessage("下載中100%...");
alertDialog.dismiss();
installApp(context, "包名", apkPath);
}
@Override
protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
}
@Override
protected void error(BaseDownloadTask task, Throwable e) {
alertDialog.dismiss();
e.printStackTrace();
}
@Override
protected void warn(BaseDownloadTask task) {
}
}).start();
}
4.安裝 需要注意7.0之後文件的訪問是通過FileProvider
在res文件下創建xml文件夾 創建共享的目錄文件 xxx.xml
其中
<files-path>:內部存儲空間應用私有目錄下的 files/ 目錄,等同於 Context.getFilesDir() 所獲取的目錄路徑;
<cache-path>:內部存儲空間應用私有目錄下的 cache/ 目錄,等同於 Context.getCacheDir() 所獲取的目錄路徑;
<external-path>:外部存儲空間根目錄,等同於 Environment.getExternalStorageDirectory() 所獲取的目錄路徑;
<external-files-path>:外部存儲空間應用私有目錄下的 files/ 目錄,等同於 Context.getExternalFilesDir(null) 所獲取的目錄路徑;
<external-cache-path>:外部存儲空間應用私有目錄下的 cache/ 目錄,等同於 Context.getExternalCacheDir();
//在AndroidManifest.xml 中配置 FileProvider
<application>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.yourname"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
public static void installApp(Context context,String packageName,String mUrl) {
File appFile = new File(mUrl);
if (!appFile.getParentFile().exists()) {
appFile.getParentFile().mkdir();
}
//判斷版本是否在7.0以上
//跳轉到新版本應用安裝頁面
if (Build.VERSION.SDK_INT >= 24) {
//yourname 是定義在xxxx.xml中的值
Uri apkUri = FileProvider.getUriForFile(context, packageName+".yourname", appFile);//在AndroidManifest中的android:authorities值
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
install.setDataAndType(apkUri, "application/vnd.android.package-archive");
context.startActivity(install);
} else {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(Uri.fromFile(appFile), "application/vnd.android.package-archive");
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(install);
}
System.exit(0);
}
5.效果圖
6.告辭