32

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で機能します。ありがとう。

4

9 に答える 9

25

何らかの理由で、グーグル開発者(「ダイアンハックボーン」という名前)は、現在のアプリのPACKAGE_REPLACEDインテントだけに登録できると考えています(アーカイブバージョンはこちら、元のリンクはこちら)。

ただし、正しく実行する方法が見つからないため、妥協しました。利用可能な場合は最新の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 / 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

<?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");

編集:今日のAndroidバージョンでは、minSdkを少なくとも14に設定する必要がある場合、これは必要ありません。実際、MY_PACKAGE_REPLACEDを使用するだけで、それだけです。ブール値などは必要ありません...

于 2014-02-02T12:28:18.693 に答える
15

ここに示すように、マニフェストマージの問題が原因で、受け入れられた回答はAndroidStudio1.0以降では機能しなくなります。完全にAndroid開発者の回答に基づいて、次の実装で問題を修正しました。

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");
    }
}
于 2015-01-03T22:11:51.953 に答える
12

すべてのユーザーから情報を入手することで、この方法で自分の状況を解決することができました。それらはすべて正しかったが、注意すべき点はほとんどなかった。

マニフェスト:

    <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()))
 {
 }

ありがとうございます

于 2012-10-01T16:21:32.560 に答える
8

これを機能させてデバッグするのに問題があったので、ここに自分の2ペンスの価値を追加したいと思います..私はLollipopデバイスを使用しています:

これは私が使用したコードです:

    <receiver android:name=".services.OnUpdateReceiver">
        <intent-filter>
            <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
        </intent-filter>
    </receiver>    

デバッグするには、Eclipseデバッグを介して更新を電話にインストールし、アプリを少なくとも1回開いたことを確認する必要があります。その後、デバッグ構成を編集するだけです。

eclipse > run > debug configurations > launch action (do nothing) > then F11 like normal

SDカードに小さなファイルを書き込んで動作することを確認しました

于 2015-01-03T15:58:05.743 に答える
3

すべてのバージョンで機能するシンプルなマニフェスト:

    <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>
于 2014-07-22T10:04:29.443 に答える
2

API> = 12デバイス/エミュレーターで試していますか?このブロードキャストはAPI12であるため、以前のケースでは送信されません。Pre-ICSおよび古いハニーコームデバイスでこれを受信するためにアプリが必要な場合は、

試す:

if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
  if (!intent.getData().getSchemeSpecificPart()
       .equals(context.getPackageName())) {
    return;
  }
}
于 2012-10-01T02:12:26.443 に答える
1

実際、apkをインストールすると、アプリが2回起動します。設定した受信機ごとに1回。

あなたが聞いているとき、あなたはandroid.intent.action.PACKAGE_REPLACEDパッケージ名をチェックする必要がありますintent.getData()

intent.getData()からの場合はNullになることに 注意してください android.intent.action.MY_PACKAGE_REPLACED

そのうちの1つを使用するだけで十分だと思います。

于 2019-02-16T10:13:06.803 に答える
0

Android Studioからアプリをビルドしてインストールしているときに、この問題が発生しました。

  • 通常のビルドと実行(デバッグなし)を実行するときに、インスタント実行をオフにすることで問題を修正しました。
  • デバッグを使用してビルドと実行を行うと、問題を修正する方法が見つかりませんでした。
于 2019-04-13T23:21:52.563 に答える
-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>
于 2012-10-01T03:35:21.560 に答える