Android 安装apk 适配7.0 8.0

1.首先清单文件中加入权限

<!--安装包相关权限-->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

2. application中加入, 注意 android:authorities="${applicationId}.provider" 这部分要和后面使用对应上

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

3.进行逻辑上相关判断, 8.0以上要设置未知来源的权限,    targetSdkVersion需要设置要大于等于26, 否则 haveInstallPermission  只能获取到false

boolean haveInstallPermission;

                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            haveInstallPermission = getPackageManager().canRequestPackageInstalls();
                            if (!haveInstallPermission) {
                                //没有未知来源安装权限权限
                                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                                builder.setTitle("提示");
                                builder.setMessage("安装应用需要打开未知来源权限,请去设置中开启应用权限,以允许安装来自此来源的应用");
                                builder.setPositiveButton("去设置", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                            startInstallPermissionSettingActivity();
                                        }
                                    }
                                });
                                builder.show();
                                return;//防止系统执行默认的方法会跳转页面后弹窗提示,所以会重复 return 掉
                            }else {
                                showProgressDialog("正在下载:0%");
                                ToolUtils.downloadApk(MainActivity.this, verUrl);
                            }
                        }else {
                            showProgressDialog("正在下载:0%");
                            ToolUtils.downloadApk(MainActivity.this, verUrl);
                        }
@RequiresApi(api = Build.VERSION_CODES.O)
    private void startInstallPermissionSettingActivity() {
        //注意这个是8.0新API
        Uri packageURI = Uri.parse("package:" + getPackageName());
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
        startActivityForResult(intent, REQUEST_CODE_INSTALL_PERMISSION);
    }
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_INSTALL_PERMISSION) {
            showProgressDialog("正在下载:0%");
            ToolUtils.downloadApk(MainActivity.this, verUrl);//再次执行安装流程,包含权限判等
        }
    }

4.下载处理相关:

 public static void downloadApk(final Context context, final String fileUrl) {
        ((BaseActivity) context).showProgressDialog("正在下载:" + 0 + "%");
        String mPath;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            mPath = Environment.getExternalStorageDirectory() + "/download";
            final File dir = new File(mPath);
            dir.getAbsolutePath().toString();
            if (!dir.exists()) {
                dir.mkdir();
            }


            final File apkFile = new File(dir, getFileName(fileUrl));
            if (apkFile.exists()) {
                apkFile.delete();
            }

            // 请求Api
            new AsyncTask<Void, Integer, String>() {
                @Override
                protected String doInBackground(Void... voids) {
                    try {
                        // 构造URL
                        URL url = new URL(fileUrl);
                        // 打开连接
                        URLConnection con = url.openConnection();
                        //获得文件的长度
                        int contentLength = con.getContentLength();
                        System.out.println("长度 :" + contentLength);
                        // 输入流
                        InputStream is = con.getInputStream();
                        // 1K的数据缓冲
                        byte[] bs = new byte[1024];
                        // 读取到的数据长度
                        int len;
                        // 输出的文件流
                        OutputStream os = new FileOutputStream(apkFile);
                        // 开始读取
                        int count = 0;
                        while ((len = is.read(bs)) != -1) {
                            os.write(bs, 0, len);
                            count += len;
                            if (count == contentLength) {
                                ((BaseActivity) context).cancelProgressDialog();
                            }
                            publishProgress((int) ((count / (float) contentLength) * 100));

                        }
                        // 完毕,关闭所有链接
                        os.close();
                        is.close();

                        installApk(context, apkFile);

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return null;
                }

                @Override
                protected void onProgressUpdate(Integer... integers) {
                    ((BaseActivity) context).showProgressDialog("正在下载:" + integers[0] + "%");
                }

                @Override
                protected void onPostExecute(String result) {

                }
            }.execute();

        }
    }
   //安装
    public static void installApk(Context context, File apkFile) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //兼容7.0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            FileProvider7.setIntentDataAndType(context,
                    intent, "application/vnd.android.package-archive", apkFile, true);
        } else {
            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }

        if (context.getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
            context.startActivity(intent);
        }
        context.startActivity(intent);
        android.os.Process.killProcess(android.os.Process.myPid());
    }

5.工具类


import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;

import java.io.File;
import java.util.List;

/**
 * Created by zhanghongyang01 on 17/5/31.
 */

public class FileProvider7 {

    public static Uri getUriForFile(Context context, File file) {
        Uri fileUri = null;
        if (Build.VERSION.SDK_INT >= 24) {
            fileUri = getUriForFile24(context, file);
        } else {
            fileUri = Uri.fromFile(file);
        }
        return fileUri;
    }



    public static Uri getUriForFile24(Context context, File file) {
        Uri fileUri = android.support.v4.content.FileProvider.getUriForFile(context,
                context.getPackageName() + ".provider",
                file);
        return fileUri;
    }


    public static void setIntentDataAndType(Context context,
                                            Intent intent,
                                            String type,
                                            File file,
                                            boolean writeAble) {
        if (Build.VERSION.SDK_INT >= 24) {
            intent.setDataAndType(getUriForFile(context, file), type);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            if (writeAble) {
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            }
        } else {
            intent.setDataAndType(Uri.fromFile(file), type);
        }
    }


    public static void setIntentData(Context context,
                                     Intent intent,
                                     File file,
                                     boolean writeAble) {
        if (Build.VERSION.SDK_INT >= 24) {
            intent.setData(getUriForFile(context, file));
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            if (writeAble) {
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            }
        } else {
            intent.setData(Uri.fromFile(file));
        }
    }


    public static void grantPermissions(Context context, Intent intent, Uri uri, boolean writeAble) {

        int flag = Intent.FLAG_GRANT_READ_URI_PERMISSION;
        if (writeAble) {
            flag |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
        }
        intent.addFlags(flag);
        List<ResolveInfo> resInfoList = context.getPackageManager()
                .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            context.grantUriPermission(packageName, uri, flag);
        }
    }


}
发布了30 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_36029400/article/details/90446198