1.权限相关
1.1 manifest相关
<!-- 打开系统安装界面需要此权限--> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:usesCleartextTraffic="true"> 支持明文请求网络,例如http请求
android 7.0以上版本禁止分享本地文件到第三方应用 差不都就是这个意思,反正就是不添加这个provider就不能唤起系统安装进程
<!-- 非androidx 使用这个android.support.v4.content.FileProvider-->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.zznode.zznodesdp.fileprovider" //此处包名+.fileprovider
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
在res目录下创建xml文件夹 ,创建file_paths.xml文件
此处是暴露内存所有地址,path具体位置可以设置添加
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path path="." name="file_paths" />
</paths>
2.activity代码
public class SdpActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks{
private File apkFile;
private ProgressDialog dialog;
final String apkUrl = "http://180.168.70.186:8808/apk/app-release.apk";
String phoneNo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sdp);
Intent intent = getIntent();
Uri data = intent.getData();
phoneNo = data.getQueryParameter("phoneNo");
String[] perms = {Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,};
if (EasyPermissions.hasPermissions(this, perms)) {
checkInstallApp();
} else {
//没有权限进行提示且申请权限
EasyPermissions.requestPermissions(this,"应用需要权限,请允许", 0, perms);
}
}
private void checkInstallApp(){
//拥有权限进行操作
if (checkAppInstalled(this,"com.zznode.esiflutter")){
System.out.println("已经安装sdp");
intentSdp();
}else {
//未安装sdp 下载apk
showNormalDialog();
}
}
//跳转到sdp
private void intentSdp(){
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("zznodesdp://login?phoneNo="+phoneNo));
startActivity(intent);
finish();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
private boolean checkAppInstalled(Context context, String pkgName) {
if (pkgName== null || pkgName.isEmpty()) {
return false;
}
final PackageManager packageManager = context.getPackageManager();
List<PackageInfo> info = packageManager.getInstalledPackages(0);
if(info == null || info.isEmpty())
return false;
for ( int i = 0; i < info.size(); i++ ) {
if(pkgName.equals(info.get(i).packageName)) {
return true;
}
}
return false;
}
private void showNormalDialog(){
final AlertDialog.Builder normalDialog =
new AlertDialog.Builder(this);
// normalDialog.setIcon(R.drawable.icon_dialog);
normalDialog.setTitle("未安装能力提升APP是否安装?");
normalDialog.setPositiveButton("安装",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//...To-do
downloadAPK(apkUrl);
System.out.println("开始更新");
}
});
normalDialog.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
intentSdp();
}
});
// 显示
normalDialog.show();
}
public void downloadAPK(final String apkUrl){
//启动异步任务处理
new AsyncTask<Void, Integer, Void>() {
//1主线程显示提示试图
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(SdpActivity.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.show();
apkFile = new File(getExternalFilesDir(null), "update.apk");
}
//2分线程,联网请求
@Override
protected Void doInBackground(Void... params) {
try{
//1 得到链接对象
URL url = new URL(apkUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(15000);
connection.connect();
int responseCode = connection.getResponseCode();
if(responseCode == 200){
//设置dialog最大进度
dialog.setMax(connection.getContentLength());
InputStream is = connection.getInputStream();
FileOutputStream fos = new FileOutputStream(apkFile);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1){
fos.write(buffer, 0, len);
//在分线程发布进度
publishProgress(len);
// dialog.incrementProgressBy(len);
}
fos.close();
is.close();
}
connection.disconnect();
installAPK();
}catch (Exception e){
try {//携带下载链接跳转到浏览器
if (!TextUtils.isEmpty(apkUrl) && apkUrl.contains("http")) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse(apkUrl);
intent.setData(content_url);
startActivity(intent);
}
} catch (Exception eer) {
//异常处理
eer.printStackTrace();
}
e.printStackTrace();
}
return null;
}
//3主线程,更新界面
@Override
protected void onPostExecute(Void aVoid) {
dialog.dismiss();
}
//在主线程中更新进度 (在publishProgress之后执行)
@Override
protected void onProgressUpdate(Integer... values) {
dialog.incrementProgressBy(values[0]);
}
}.execute();
}
/**
* 启动安装apk
*/
private void installAPK() {
Intent intent = new Intent(Intent.ACTION_VIEW);
//判断是否是AndroidN以及更高的版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//authority值需和manifest中匹配,包名+.fileprovider
Uri contentUri = FileProvider.getUriForFile(this, "com.zznode.zznodesdp.fileprovider", apkFile);
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
startActivity(intent);
finish();
}
@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
checkInstallApp();
}
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
finish();
}
}
3.build.gradle中添加依赖
//需要宿主引用 implementation 'pub.devrel:easypermissions:1.2.0'
本文详细记录了在Android中进行APK下载安装的过程,包括设置manifest权限,创建file_paths.xml以暴露内存路径,以及在activity代码中的实现和build.gradle中的依赖添加。
5328

被折叠的 条评论
为什么被折叠?



