Android 未收到 ACTION_MY_PACKAGE_REPLACED
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12666734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ACTION_MY_PACKAGE_REPLACED not received
提问by Ton
I am using ACTION_MY_PACKAGE_REPLACED to receive when my app is updated or resinstalled. My problem is that the event is never triggered (I tried Eclipse and real device). This is what I do:
我正在使用 ACTION_MY_PACKAGE_REPLACED 来接收我的应用程序更新或重新安装时的信息。我的问题是该事件从未被触发(我尝试过 Eclipse 和真实设备)。这就是我所做的:
Manifest:
显现:
<receiver android:name=".MyEventReceiver" >
<intent-filter android:priority="1000" >
<action android:name="android.intent.action.ACTION_MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
Code:
代码:
public class MyEventReceiver extends BroadcastReceiver
{
@Override public void onReceive(Context context, Intent intent)
{
if ("android.intent.action.ACTION_MY_PACKAGE_REPLACED".equals(intent.getAction()))
{ //Restart services
}
}
}
This code is simple, in real one I used other events like BOOT_COMPLETED and others, and they work but ACTION_MY_PACKAGE_REPLACED. Thanks.
这段代码很简单,实际上我使用了其他事件,如 BOOT_COMPLETED 和其他事件,它们可以工作但 ACTION_MY_PACKAGE_REPLACED。谢谢。
采纳答案by Ton
Getting information from all the users I could solve my situation this way. All of them were right, with little points to notice:
从所有用户那里获取信息我可以通过这种方式解决我的情况。他们都是对的,有一点需要注意:
In manifest:
在清单中:
<receiver android:name=".MyEventReceiver" >
<intent-filter android:priority="1000" >
<!--other actions I need-->
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
And code:
和代码:
public class MyEventReceiver extends BroadcastReceiver
{
@Override public void onReceive(Context context, Intent intent)
{
if(Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction()))
{ if(intent.getData().getSchemeSpecificPart().equals(context.getPackageName()))
{ //Restart services.
}
}
}
}
In my Android release (2.3 Gingerbread) I was not able to use MY_PACKAGE_REPLACED but we solved using PACKAGE_REPLACED (will advise of any app been replaced) but asking if it is ours with:
在我的 Android 版本(2.3 Gingerbread)中,我无法使用 MY_PACKAGE_REPLACED 但我们使用 PACKAGE_REPLACED 解决了(会建议任何应用程序被替换)但询问它是否是我们的:
if(intent.getData().getSchemeSpecificPart().equals(context.getPackageName()))
{
}
Thanks to all
谢谢大家
回答by android developer
for some reason, a google developer (named "Dianne Hackborn") thinks it is possible to register to the PACKAGE_REPLACED intent of the current app alone (read archived version here, original link here).
出于某种原因,谷歌的开发者(名为“戴安娜Hackborn”),认为这是可以注册单独的PACKAGE_REPLACED意图当前应用程序的(读取存档版本在这里,原来的链接在这里)。
however, i can't find any way of doing it correctly, so i've made a compromise: it will use the newest API when available.
但是,我找不到任何正确执行此操作的方法,因此我做出了妥协:它将在可用时使用最新的 API。
Sadly, I can't find out why it can't be debugged, but it does work (you can write to the log if you wish).
遗憾的是,我不知道为什么它不能被调试,但它确实有效(如果你愿意,你可以写入日志)。
here's the code:
这是代码:
manifest:
显现:
<receiver
android:name=".OnUpgradeBroadcastReceiver"
android:enabled="@bool/is_at_most_api_11" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver
android:name=".OnUpgradeBroadcastReceiver"
android:enabled="@bool/is_at_least_api_12" >
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
res/values/version_checks.xml
res/values/version_checks.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="is_at_least_api_12" type="bool">false</item>
<item name="is_at_most_api_11" type="bool">true</item>
</resources>
res/values-v12/version_checks.xml
res/values-v12/version_checks.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="is_at_least_api_12" type="bool">true</item>
<item name="is_at_most_api_11" type="bool">false</item>
</resources>
OnUpgradeBroadcastReceiver.java
OnUpgradeBroadcastReceiver.java
public class OnUpgradeBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
if (VERSION.SDK_INT <= VERSION_CODES.HONEYCOMB
&& !context.getPackageName().equals(intent.getData().getSchemeSpecificPart())) {
android.util.Log.d("AppLog", "other apps were upgraded");
return;
}
android.util.Log.d("AppLog", "current app was upgraded");
EDIT: In today's Android versions, when you should set minSdk to be at least 14, you don't need this, and indeed you should just use MY_PACKAGE_REPLACED and that's it. No need for the booleans etc...
编辑:在今天的 Android 版本中,当您应该将 minSdk 设置为至少 14 时,您不需要这个,实际上您应该只使用 MY_PACKAGE_REPLACED 就可以了。不需要布尔值等...
回答by cprcrack
The accepted answerdoesn't work any more with Android Studio 1.0+ because of manifest merge issues, as seen here. Totally based on android developer's answer, I fixed the issue with the following implementation:
该接受的答案不工作了与Android工作室1.0+因为清单合并的问题,因为看到这里。完全基于android开发人员的回答,我通过以下实现解决了这个问题:
AndroidManifest.xml:
AndroidManifest.xml:
<receiver android:name=".UpdateReceiver$LegacyUpdateReceiver" android:enabled="@bool/shouldUseActionPackageReplaced" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver android:name=".UpdateReceiver" android:enabled="@bool/shouldUseActionMyPackageReplaced" >
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
/res/values/resources.xml:
/res/values/resources.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="shouldUseActionPackageReplaced">true</bool>
<bool name="shouldUseActionMyPackageReplaced">false</bool>
</resources>
/res/values-v12/resources.xml:
/res/values-v12/resources.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="shouldUseActionPackageReplaced">false</bool>
<bool name="shouldUseActionMyPackageReplaced">true</bool>
</resources>
UpdateReceiver.java:
更新接收器.java:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class UpdateReceiver extends BroadcastReceiver
{
public static class LegacyUpdateReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
if (intent != null && intent.getData() != null && context.getPackageName().equals(intent.getData().getSchemeSpecificPart()))
{
onUpdate(context);
}
}
}
@Override
public void onReceive(Context context, Intent intent)
{
onUpdate(context);
}
public static void onUpdate(Context context)
{
Log.d("LOG", "Current app updated");
}
}
回答by Steven Elliott
I just want to add my own two pence worth here, because I had problems getting this to work and debugging it .. I am using a Lollipop device:
我只想在这里加上我自己的两便士,因为我在让它工作和调试时遇到了问题..我正在使用棒棒糖设备:
This is the code I used:
这是我使用的代码:
<receiver android:name=".services.OnUpdateReceiver">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
To debug it, you need to make sure you have installed the update on your phone, just via Eclipse debug is fine, and opened the app at least one time, then you can simply edit your debug configuration:
要调试它,你需要确保你的手机已经安装了更新,通过 Eclipse 调试就可以了,并且至少打开了一次应用程序,然后你可以简单地编辑你的调试配置:
eclipse > run > debug configurations > launch action (do nothing) > then F11 like normal
I confirmed it worked by writing a small file to the SD card
我通过将一个小文件写入 SD 卡来确认它有效
回答by Bouchehboun Saad
Simple Manifest working in all version :
Simple Manifest 适用于所有版本:
<receiver
android:name=".Receiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
回答by Edison
Are you trying it on a API>=12 device/emulator? This broadcast will not be sent on prior cases as it is API 12. If you need your app to receive this for Pre-ICS and the old honey comb devices,
您是否在 API>=12 设备/模拟器上尝试过?此广播不会在以前的情况下发送,因为它是 API 12。如果您需要您的应用程序为 Pre-ICS 和旧的蜂窝设备接收此广播,
try:
尝试:
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
if (!intent.getData().getSchemeSpecificPart()
.equals(context.getPackageName())) {
return;
}
}
回答by Omid Mehdizadeh
Actually, your app will start twice when you install your apk. Once for each receiver that you have set.
实际上,当您安装 apk 时,您的应用程序将启动两次。对于您设置的每个接收器一次。
When you are Listening to android.intent.action.PACKAGE_REPLACED
then you need to check for the package-name in the intent.getData()
当您正在收听时,android.intent.action.PACKAGE_REPLACED
您需要检查包名intent.getData()
Note that intent.getData()
will be Null when it is from
android.intent.action.MY_PACKAGE_REPLACED
请注意, intent.getData()
当它来自
android.intent.action.MY_PACKAGE_REPLACED
I think using one of them is enough.
我认为使用其中之一就足够了。
回答by Sam
I ran into this problem when I was building and installing my app from Android Studio.
我在从 Android Studio 构建和安装我的应用程序时遇到了这个问题。
- When doing normal build & run (without debugging), I fixed the problem by turning off Instant Run.
- When doing a build & run with debugging, I couldn't find a way to fix the problem.
- 在进行正常的构建和运行(无需调试)时,我通过关闭 Instant Run 解决了这个问题。
- 在使用调试进行构建和运行时,我找不到解决问题的方法。
回答by Rasel
You need to add data scheme to the intent filter like below
您需要将数据方案添加到意图过滤器中,如下所示
<receiver android:name=".MyEventReceiver" >
<intent-filter android:priority="1000" >
<action android:name="android.intent.action.ACTION_MY_PACKAGE_REPLACED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>