Подтвердить что ты не робот

ACTION_MY_PACKAGE_REPLACED не получен

Я использую 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. Спасибо.

4b9b3361

Ответ 1

Получение информации от всех пользователей, которые я мог решить эту ситуацию таким образом. Все они были правы, с небольшим количеством замечаний:

В манифесте:

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

Спасибо всем

Ответ 2

по какой-то причине разработчик google (названный "Dianne Hackborn" ) считает, что можно зарегистрировать только намерение 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/значение/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");

Ответ 3

принятый ответ больше не работает с Android Studio 1.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");
    }
}

Ответ 4

Я просто хочу добавить свои собственные две пенсы, потому что у меня были проблемы с тем, чтобы это работало и отлаживало его. Я использую устройство 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-карту.

Ответ 5

Вы пытаетесь использовать его на устройстве API/эмулятора API >= 12? Эта передача не будет отправляться по предыдущим делам, так как это API 12. Если вам нужно ваше приложение для получения этого для Pre-ICS и старых устройств для расчёта меда,

попробовать:

if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
  if (!intent.getData().getSchemeSpecificPart()
       .equals(context.getPackageName())) {
    return;
  }
}

Ответ 6

Простой манифест работает во всех версиях:

    <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>

Ответ 7

На самом деле ваше приложение запустится дважды, когда вы установите apk. Один раз для каждого установленного вами приемника.

Когда вы слушаете android.intent.action.PACKAGE_REPLACED вам необходимо проверить имя пакета в intent.getData()

Обратите внимание, что intent.getData() будет иметь значение Null, если оно от android.intent.action.MY_PACKAGE_REPLACED

Я думаю, что использование одного из них достаточно.

Ответ 8

Я столкнулся с этой проблемой, когда собирал и устанавливал свое приложение из Android Studio.

  • При обычной сборке и запуске (без отладки) я исправил проблему, отключив Instant Run.
  • Выполняя сборку и запуск с отладкой, я не мог найти способ исправить проблему.

Ответ 9

Вам нужно добавить схему данных в фильтр намерений, как показано ниже

<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>