Android开发 新版本下载更新 apk安装权限申请 适用Android8.0 7.0 6.0

安装权限申请:

1. AdroidManifest.xml

<!--添加REQUEST_INSTALL_PACKAGES权限-->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

以下放在 application内

<!-- FileProvider配置访问路径,适配7.0及其以上 -->
<provider android:name="android.support.v4.content.FileProvider"
	android:authorities="包名+.fileprovider"
	android:exported="false"
	android:grantUriPermissions="true">
	<meta-data
		android:name="android.support.FILE_PROVIDER_PATHS"
		android:resource="@xml/file_paths"/>
</provider>

2. 在资源文件夹res/xml下新建file_provider.xml文件 

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <external-path path="" name="files_root"/>
    </paths>
</resources>

name:是一个虚设的文件名(可以自由命名),对外可见路径的一部分,隐藏真实文件目录

path:是一个相对目录,相对于当前的子标签根目录,表示内部内存卡根目录,对应根目录等价于Context.getFilesDir() 

3. 版本更新工具类:

public class VersionUtil extends AppCompatActivity {

    private static Activity recieveActivity;

    private static String result, downloadURL, version = "";

    /**
     * 获取当前程序的版本号
     */
    private static void getAPKVersion(Boolean isNeed) {
        try {
            //获取packagemanager的实例
            PackageManager packageManager = recieveActivity.getPackageManager();

            //getPackageName()是当前类的包名,0代表是获取版本信息
            PackageInfo packInfo = packageManager.getPackageInfo(recieveActivity.getPackageName(), 0);

            Log.i("TAG", "版本号" + packInfo.versionCode);
            Log.i("TAG", "版本名" + packInfo.versionName);

            version = String.valueOf(packInfo.versionCode);

            checkVersion(isNeed);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 提示版本更新的对话框
     */
    private static void showDialogUpdate() {
        // 这里的属性可以一直设置,因为每次设置后返回的是一个builder对象
        AlertDialog.Builder builder = new AlertDialog.Builder(recieveActivity);
        // 设置提示框的标题
        builder.setTitle("提示");
        // 设置要显示的信息
        builder.setMessage("检查到新版本,确定下载并更新吗?");
        // 设置确定按钮
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                boolean isPermit = getPersimmionsRsult();
                if (isPermit) {
                    downloadAPK();
                }
            }
        });
        // 设置取消按钮
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                return;
            }
        });
        // 显示对话框
        builder.show();
    }

    @TargetApi(23)
    private static void getPersimmions() {
        int SDK_PERMISSION_REQUEST = 127;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ArrayList<String> permissions = new ArrayList<String>();
            /***
             * 用户如果禁止,则每次进入都会申请
             */
            //读写权限
            if (recieveActivity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                ToastUtil.showToast(recieveActivity, "安装app需要您勾选读写权限");
                permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            }

            if (permissions.size() > 0) {
                ActivityCompat.requestPermissions(recieveActivity, permissions.toArray(new String[permissions.size()]), SDK_PERMISSION_REQUEST);
            }
        }
    }

    @TargetApi(23)
    private static boolean getPersimmionsRsult() {
        boolean isPermit = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (recieveActivity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                isPermit = false;
                ToastUtil.showToast(recieveActivity, "未勾选读写权限");
            } else {
                isPermit = true;
            }
        }
        return isPermit;
    }

    private static void downloadAPK() {
        final ProgressDialog pd;    //进度条对话框
        pd = new ProgressDialog(recieveActivity);
        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pd.setMessage("正在下载更新");
        pd.show();

        //启动子线程下载任务
        new Thread() {
            @Override
            public void run() {
                try {
                    File file = getFileFromServer(downloadURL, pd);
                    sleep(3000);
                    installApk(file);
                    pd.dismiss(); //结束掉进度条对话框
                } catch (Exception e) {
                    //下载apk失败
                    ToastUtil.showToast(recieveActivity, "下载新版本失败");
                    e.printStackTrace();
                }
            }
        }.start();

    }

    /**
     * 从服务器获取apk文件的代码
     * 传入网址uri,进度条对象即可获得一个File文件
     * (要在子线程中执行)
     * @param uri
     * @param pd
     * @return
     * @throws Exception
     */
    private static File getFileFromServer(String uri, ProgressDialog pd) throws Exception {
        //如果相等的话表示当前的sdcard挂载在手机上并且是可用的
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            URL url = new URL(uri);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            //获取到文件的大小
            pd.setMax(conn.getContentLength() / 1024);
            InputStream is = conn.getInputStream();
            long time = System.currentTimeMillis();//当前时间的毫秒数
            File file = new File(Environment.getExternalStorageDirectory(), time + "updata.apk");
            FileOutputStream fos = new FileOutputStream(file);
            BufferedInputStream bis = new BufferedInputStream(is);

            byte[] buffer = new byte[1024];
            int len;
            int total = 0;
            while ((len = bis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
                total += len;
                //获取当前下载量
                pd.setProgress(total / 1024);
            }
            fos.close();
            bis.close();
            is.close();
            return file;
        } else {
            return null;
        }
    }

    /**
     * 安装apk
     * @param file
     */
    private static void installApk(File file) {
        if (!file.exists()) {
            return;
        }
        try {
            Intent intent = new Intent();
            //执行动作
            intent.setAction(Intent.ACTION_VIEW);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            //版本在7.0以上是不能直接通过uri访问的
            //兼容7.0
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {             
                Uri contentUri = FileProvider.getUriForFile(recieveActivity.getApplication().getApplicationContext(), recieveActivity.getPackageName() + ".fileprovider", file); //recieveActivity.getPackageName() 取得包名
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
                //兼容8.0
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    boolean hasInstallPermission = recieveActivity.getPackageManager().canRequestPackageInstalls();
                    if (!hasInstallPermission) {
                        ToastUtil.showToast(recieveActivity, "安装app需要您勾选允许安装未知应用权限");
                        startInstallPermissionSettingActivity();
                        //return;
                    }
                }
            } else {
                intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");               
            }
            if (recieveActivity.getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
                recieveActivity.startActivity(intent);
            }
            //如果不加,最后不会提示完成、打开。
            android.os.Process.killProcess(android.os.Process.myPid());
        } catch (Throwable e) {
            e.printStackTrace();
            ToastUtil.showToast(recieveActivity, "未知应用权限开启失败,请重启应用");
        }
    }

    /**     * 跳转到设置-允许安装未知来源-页面     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private static void startInstallPermissionSettingActivity() {
        //注意这个是8.0新API
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        recieveActivity.startActivityForResult(intent, 99);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        Log.i("VersionUtil", "此处重写失败,未解决。。。"); //在本功能暂不影响使用
    }

}

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值