繁体   English   中英

无需用户交互即可自动更新 APP ==> Permission Denial: not allowed to send broadcast android.intent.action.PACKAGE_ADDED

[英]Update APP automatically without user interaction facing issue==> Permission Denial: not allowed to send broadcast android.intent.action.PACKAGE_ADDED

我想在有新版本时自动更新APP,无需用户交互,假设有新版本可用,并下载到android的Downloads目录。

我按照以下示例进行操作。

Java 样品: https://stackoverflow.com/a/51705614

Kotlin 样品: https://www.sisik.eu/blog/android/dev-admin/update-app

面对这个例外

system_process W/ActivityManager: Permission Denial: not allowed to send broadcast android.intent.action.PACKAGE_ADDED from pid=-1, uid=10191
system_process W/ActivityManager: Unable to send startActivity intent
    java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.PACKAGE_ADDED from pid=-1, uid=10191
        at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:21323)
        at com.android.server.am.ActivityManagerService.broadcastIntentInPackage(ActivityManagerService.java:21974)
        at com.android.server.am.PendingIntentRecord.sendInner(PendingIntentRecord.java:372)
        at com.android.server.am.PendingIntentRecord.sendWithResult(PendingIntentRecord.java:245)
        at com.android.server.am.ActivityManagerService.sendIntentSender(ActivityManagerService.java:8446)
        at android.content.IntentSender.sendIntent(IntentSender.java:191)
        at android.content.IntentSender.sendIntent(IntentSender.java:155)
        at com.android.server.pm.PackageInstallerService$PackageInstallObserverAdapter.onUserActionRequired(PackageInstallerService.java:888)
        at android.app.PackageInstallObserver$1.onUserActionRequired(PackageInstallObserver.java:28)
        at com.android.server.pm.PackageInstallerSession.commitLocked(PackageInstallerSession.java:951)
        at com.android.server.pm.PackageInstallerSession.access$200(PackageInstallerSession.java:120)
        at com.android.server.pm.PackageInstallerSession$3.handleMessage(PackageInstallerSession.java:294)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:193)
        at android.os.HandlerThread.run(HandlerThread.java:65)

AndroidManifest.xml

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AutoUpdateAppPractice"
        android:usesCleartextTraffic="true">

        <receiver
            android:name="UpdateReceiver"
            android:enabled="true"
            android:exported="true">

            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
            </intent-filter>

        </receiver>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.INSTALL_PACKAGE" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

CustomPackageInstaller.java

package com.odine.autoupdateapppractice;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class CustomPackageInstaller {

    public static void installPackage(Context context, String installSessionId, String packageName, InputStream apkStream) {

        PackageManager packageManger = context.getPackageManager();
        PackageInstaller packageInstaller = packageManger.getPackageInstaller();

        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);

        params.setAppPackageName(packageName);
        PackageInstaller.Session session = null;

        try {
            Log.e(TAG, "installPackage: try");

            int sessionId = packageInstaller.createSession(params);
            session = packageInstaller.openSession(sessionId);
            OutputStream out = session.openWrite(installSessionId, 0, -1);
            byte buffer[] = new byte[1024];
            int length;
            int count = 0;
            while ((length = apkStream.read(buffer)) != -1) {
                out.write(buffer, 0, length);
                count += length;
            }
            session.fsync(out);
            out.close();

            Intent intent = new Intent(Intent.ACTION_PACKAGE_ADDED);
            session.commit(PendingIntent.getBroadcast(context, sessionId, intent, PendingIntent.FLAG_UPDATE_CURRENT).getIntentSender());


        } catch (Exception ex) {
            Log.e(TAG, "installPackage: catch");
            ex.printStackTrace();

        } finally {
            Log.e(TAG, "installPackage: finally");

            if (session != null) {
                session.close();
            }
        }

    }

}

并在我的MainActivity.java按钮上单击调用CustomPackageInstaller.installPackage()上面写的 class

 File file= new File(filePath);
 InputStream targetStream = new FileInputStream(file);

 CustomPackageInstaller.installPackage(
                MainActivity.this,
                "2",
                "com.odine.autoupdateapppractice",
                targetStream);

您收到的错误消息几乎可以告诉您问题所在。 您已请求 package 安装程序在完成时通过发送带有 ACTION = android.intent.action.PACKAGE_ADDED的广播Intent通知您。 此广播Intent只能由 Android 框架发送。 常规应用无法发送此广播Intent

为此,您应该使用显式Intent ,在其中指定组件(包名称和 class 名称)。 为此,您可以让 package 安装程序启动ActivityBroadcastReceiver


注意:您的应用必须是设备所有者才能在没有用户交互的情况下执行此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM