Android应用程序下载APK文件并打开它(安装)



我想知道您是否可以提供帮助,我正在尝试下载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

感谢您的帮助

由于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和许可

注意。我使用了androidx版本的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)
        }
    }

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

最新更新