2012-10-01 189 views
16

我正在使用ACTION_MY_PACKAGE_REPLACED來接收我的應用程序更新或resinstalled時。 我的問題是,事件從未觸發(我試過Eclipse和真正的設備)。 這是我做的:ACTION_MY_PACKAGE_REPLACED沒有收到

清單:

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

+2

你有兩個問題。你的動作名稱是錯誤的;它不應該包含'ACTION_'前綴。另外,'MY_PACKAGE_REPLACED'用於API 12+。 – Sam

回答

8

從所有用戶獲取信息我可以通過這種方式解決我的情況。 他們都是正確的,很少點要注意:

在清單:

<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薑餅)我無法使用MY_PACKAGE_REPLACED,但我們解決了使用PACKAGE_REPLACED(將通知任何應用程序已被替換),但詢問是否屬於我們的:

if(intent.getData().getSchemeSpecificPart().equals(context.getPackageName())) 
{ 
} 

感謝所有

2

您是否正在API> = 12設備/模擬器上嘗試它?此廣播將不會在之前的情況下被髮送,因爲它是API 12。如果您需要在您的應用程序接收此爲預ICS和老蜂巢設備,

嘗試:

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

謝謝。那麼,我也嘗試了ACTION_PACKAGE_REPLACED,但也沒有觸發任何。是的,仿真器和設備是薑餅。任何其他提示? – Ton

+0

你添加了接收器嗎?作爲 <動作android:name =「android.intent.action.PACKAGE_REPLACED」/>和 我使用這個爲我的幾個應用程序,他們適用於所有Android設備> 1.5 – Edison

-3

您需要將數據方案添加到意圖過濾器如下

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

根據[documentation](http://developer.android.com/reference/android/content/Intent.html#ACTION_MY_PACKAGE_REPLACED),常量「ACTION_MY_PACKAGE_REPLACED」的值是'android.intent.action.MY_PACKAGE_REPLACED'而沒有'ACTION_'部分。 – MaxChinni

+0

您應該使用Intent.ACTION_MY_PACKAGE_REPLACED,它等同於「android.intent.action.MY_PACKAGE_REPLACED」 – FabioC

19

由於某種原因,谷歌開發者(名爲「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

​​
+0

您需要將** android:debuggable =「true」**和** android:exported =「true」**添加到您的清單聲明以便能夠調試接收器。 例如'接收機android:debuggable =「true」android:exported =「true」android:name =「。OnUpgradeBroadcastReceiver」>' –

+0

,但它已經可以調試,因爲我已經從Eclipse中運行它...我認爲它是導出的,它是如何從系統中獲得意圖的......確定它修復了它?如果是這樣,那很奇怪。 –

+0

永遠不會知道' false',總是使用較短的' false' – cprcrack

0

簡單的清單工作:

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

工作,但這會導致您的應用程序每次喚醒任何(其他)應用程序在API 12或更大的設備 – Gavriel

4

我只想補充我自己的兩隻便士這裏,因爲我有問題得到這個工作和調試它..我正在使用棒棒糖設備:

這是我使用的代碼:

<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

這個答案是正確的! MY_PACKAGE_REPLACED之前不適用於我,但是我之前在 – Boy

12

accepted answer不與Android工作室工作了1.0+因爲清單合併問題,作爲s een 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"); 
    } 
} 
+0

之前嘗試了PACKAGE_REPLACED之後出現了_REMOVED_ 這裏有什麼不同之處呢?你剛剛添加「getApplicationContext」?另外,如果你發現了Android-Studio(或Android)的bug,你應該在這裏發佈它:https://code.google.com/p/android/issues/list –

+2

這不是一個bug,它只是新的清單合併不支持你在做什麼。你說什麼不同?您不能爲兩個不同的接收器使用相同的類。所以,如果你看看我的代碼,我在其中一個接收器中使用了一個內部靜態類,從而符合新的清單合併器,同時避免使用java文件執行相同的任務。除此之外,一切都是等價的,當然,我只是添加它,因爲StackOverflow中的答案應該是自包含的。 – cprcrack

+0

另外,如果您有興趣瞭解爲什麼您的解決方案現在無法在Android Studio上運行,請按照我提供的鏈接進行操作。同樣,如果您仍然無法看到有什麼不同,請查看代碼,甚至先嚐試一下您的代碼,然後使用Android Studio 1.0+,因爲我知道我無法更詳細地解釋它。 – cprcrack