[英]App crashes with Permission Denial: not allowed to send broadcast android.intent.action.SCREEN_ON
[英]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 安装程序启动Activity
或BroadcastReceiver
。
注意:您的应用必须是设备所有者才能在没有用户交互的情况下执行此操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.