android app下载apk文件并打开它(安装)

问题描述 投票:0回答:1

我想知道你是否可以提供帮助,我试图在版本检查后下载一个apk文件作为更新。它正在下载apk但它不会打开apk文件,在尝试打开apk时会打印错误

错误:

E/UpdateAPP: Update error! file:///storage/emulated/0/download/update.apk exposed beyond app through Intent.getData()

代码:

public class UpdateApp extends AsyncTask<String,Void,Void> {
    private Context context;
    public void setContext(Context contextf){
        context = contextf;
    }

    @Override
    protected Void doInBackground(String... arg0) {
        try {
            URL url = new URL(arg0[0]);
            HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            String PATH = Environment.getExternalStorageDirectory() + "/download/";
            File file = new File(PATH);
            file.mkdirs();
            File outputFile = new File(file, "update.apk");
            if(outputFile.exists()){
                outputFile.delete();
            }
            FileOutputStream fos = new FileOutputStream(outputFile);

            InputStream is = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len1);
            }
            fos.close();
            is.close();

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "/update.apk")), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
            context.startActivity(intent);


        } catch (Exception e) {
            Log.e("UpdateAPP", "Update error! " + e.getMessage());
        }
        return null;
    }}

我的targetSdkVersion:

targetSdkVersion 27

谢谢您的帮助

java android
1个回答
2
投票

从API 26开始,'REQUEST_INSTALL_PACKAGES'权限是实现安装apk文件的必要权限。

  1. 在res / xml文件夹中创建'file_paths.xml'以使用FileProvider api
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="" path="/" />
</paths>
  1. 在AndroidManifest.xml中声明FileProvider和权限

注意。我使用的是Filex版本的FileProvider,如果你不使用androidx,请确保android.support.v4.content.FileProvider

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

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

</provider>
  1. 通过FileProvider api获取'Uri'并请求安装权限
private fun openFile(file: File) {
        val uri = if (Build.VERSION.SDK_INT >= 24) {
            val authority = packageName + ".fileprovider"
            FileProvider.getUriForFile(this, authority, file)
        } else {
            Uri.fromFile(file)
        }

        val myMime = MimeTypeMap.getSingleton()
        val mimeType = myMime.getMimeTypeFromExtension(file.extension)

        val intent = Intent(Intent.ACTION_VIEW).apply {
            setDataAndType(uri, mimeType)
            flags = Intent.FLAG_ACTIVITY_NEW_TASK
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        }

        if (Build.VERSION.SDK_INT >= 26 && !packageManager.canRequestPackageInstalls()) {
            startActivity(
                Intent(
                    Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
                    Uri.parse("package:$packageName")
                )
            )
        } else {
            intent.action = Intent.ACTION_VIEW
            startActivity(intent)
        }
    }

编辑 - >删除我的项目中使用的特定方法。

© www.soinside.com 2019 - 2024. All rights reserved.