下载管理器下载后安装新的 apk 并退出 运行 应用程序

Install new apk after download by Download Manager and exit from running app

我已经使用 java 创建了 android 应用程序。但我想在没有 Playstore 的情况下升级我的应用程序。 我尝试手动下载,但这样做有更多时间。 我想简单点。 所以我使用下载管理器从我的服务器下载新文件。 现在我不知道如何自动安装我的新应用程序。

我该怎么办?

这是显而易见的:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="28"/>

<application
        ...
        android:supportsRtl="true"
        android:usesCleartextTraffic="true"
        android:requestLegacyExternalStorage="true"
        ...
</application>

这是我尝试下载的文件:

String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
destination += name_app_list;

final Uri uri = Uri.parse("file://" + destination);

final DownloadManager.Request request = new DownloadManager.Request(Uri.parse("url" + name_app_list));
request.setDestinationUri(uri);
request.setMimeType("application/vnd.android.package-archive");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
final long downloadID = manager.enqueue(request);

而且我已尝试安装该 apk :

BroadcastReceiver onComplete = new BroadcastReceiver() {
   public void onReceive(Context ctxt, Intent intent) {
      Intent intez = new Intent(Intent.ACTION_VIEW);
      intez.setDataAndType(Uri.fromFile(new File(name_app_list)), "application/vnd.android.package-archive");
      startActivity(intez);
   }
};

registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

这个错误:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dsi.updateapp/com.dsi.updateapp.MainActivity}: android.os.FileUriExposedException: file:///storage/emulated/0/Download/1.4/phd.apk exposed beyond app through Intent.getData()
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
     Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Download/1.4/phd.apk exposed beyond app through Intent.getData()
        at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
        at android.net.Uri.checkFileUriExposed(Uri.java:2346)
        at android.content.Intent.prepareToLeaveProcess(Intent.java:8933)
        at android.content.Intent.prepareToLeaveProcess(Intent.java:8894)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1517)
        at android.app.Activity.startActivityForResult(Activity.java:4224)
        at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:597)
        at android.app.Activity.startActivityForResult(Activity.java:4183)
        at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:583)
        at android.app.Activity.startActivity(Activity.java:4507)
        at android.app.Activity.startActivity(Activity.java:4475)
        at com.dsi.updateapp.MainActivity.openFile(MainActivity.java:202)
        at com.dsi.updateapp.MainActivity.onCreate(MainActivity.java:109)
        at android.app.Activity.performCreate(Activity.java:6662)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)

找了一整天后,我得到了解决方案 谢谢你评论我的 post :) 这是我的解决方案 添加到清单:

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

</provider>

添加新目录和文件 xml/provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="downloads" path="."/>
</paths>

然后在 Activity 中:

BroadcastReceiver onComplete = new BroadcastReceiver() {
   public void onReceive(Context ctxt, Intent intent) {
      Uri uri = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider", destination);
      Intent intents = new Intent(Intent.ACTION_VIEW);
      intents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      intents.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
      intents.setDataAndType(uri,"application/vnd.android.package-archive");
      startActivity(intents);
   }
};

registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));