我正在使用ACTION_MY_PACKAGE_REPLACED在我的应用更新或树脂安装时接收。 我的问题是从未触发事件(我尝试过Eclipse和真实设备)。 这就是我的工作:
清单:
<receiver android:name=".MyEventReceiver" >
<intent-filter android:priority="1000" >
<action android:name="android.intent.action.ACTION_MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
代码:
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
}
}
}
这段代码很简单,实际上我使用了其他事件,比如BOOT_COMPLETED和其他事件,它们可以工作但是ACTION_MY_PACKAGE_REPLACED。 感谢。
答案 0 :(得分:22)
出于某种原因,谷歌开发人员(名为“Dianne Hackborn”)认为可以单独注册当前应用程序的PACKAGE_REPLACED意图(链接here)。
但是,我找不到任何正确的方法,所以我做了一个妥协:它将在可用时使用最新的API。
可悲的是,我无法找出无法调试的原因,但它确实有效(如果您愿意,可以写入日志)。
这是代码:
<强>清单:强>
<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 /值/ 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 /值-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 强>
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");
答案 1 :(得分:14)
由于明显的合并问题,accepted answer不再适用于Android Studio 1.0+,如here所示。完全基于android developer's answer,我通过以下实现解决了问题:
<强>的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:强>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="shouldUseActionPackageReplaced">true</bool>
<bool name="shouldUseActionMyPackageReplaced">false</bool>
</resources>
<强> /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:强>
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");
}
}
答案 2 :(得分:9)
从所有用户那里获取信息我可以通过这种方式解决我的问题。 所有这些都是正确的,没有什么要注意的地方:
在清单中:
<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>
代码:
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.
}
}
}
}
在我的Android版本(2.3 Gingerbread)中,我无法使用MY_PACKAGE_REPLACED,但我们使用PACKAGE_REPLACED解决了问题(会建议更换任何应用),但询问是否属于我们的应用:
if(intent.getData().getSchemeSpecificPart().equals(context.getPackageName()))
{
}
感谢所有
答案 3 :(得分:7)
我只想在这里添加自己的两便士,因为我在使用它并调试它时遇到了问题。我正在使用Lollipop设备:
这是我使用的代码:
<receiver android:name=".services.OnUpdateReceiver">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
要调试它,您需要确保已在手机上安装了更新,只需通过Eclipse调试就可以了,并且至少打开了一次应用程序,然后您就可以编辑调试配置了:
eclipse > run > debug configurations > launch action (do nothing) > then F11 like normal
我通过将一个小文件写入SD卡确认它有效
答案 4 :(得分:2)
您是在API&gt; = 12设备/模拟器上进行尝试吗?由于它是API 12,因此不会在先前的情况下发送此广播。如果您需要您的应用为Pre-ICS和旧蜂巢设备接收此广播,
尝试:
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
if (!intent.getData().getSchemeSpecificPart()
.equals(context.getPackageName())) {
return;
}
}
答案 5 :(得分:2)
简单清单在所有版本中工作:
<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>
答案 6 :(得分:1)
实际上,当您安装apk时,您的应用将启动两次。 对于您设置的每个接收器一次。
在收听CKQueryOperationMaximumResults
时,您需要检查android.intent.action.PACKAGE_REPLACED
中的程序包名称
请注意,intent.getData()
来自于时为Null
intent.getData()
我认为使用其中之一就足够了。
答案 7 :(得分:0)
从Android Studio构建和安装应用程序时遇到了这个问题。
答案 8 :(得分:-4)
您需要将数据方案添加到意图过滤器,如下所示
<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>