JAC
JAC

Reputation: 601

BroadcastReceiver with IntentFilter for Intent.ACTION_PACKAGE_REPLACED not working within a service

I am trying to set up a service that checks when a new update of an activity is installed in a device. I have already done so within an application activity, declaring the Broadcastreceiver in the manifest and it works perfectly.

However, when I try to run that receiver within a Service and dynamically declare it, my onReceive never gets called. This is my Service code:

public class UpdateService extends Service {    
 private static String mPackage = "com.my.package";
 private static String mActivityName = "myActivity";
 private BroadcastReceiver mUpdateReceiver; 

 @Override
 public void onCreate() {
  super.onCreate();
  mUpdateReceiver = new BroadcastReceiver() {

   @Override
   public void onReceive(Context context, Intent intent) {
    Log.d("mTag","In the BroadcastReceiver onReceive()");
    if (intent.getAction().equalsIgnoreCase(Intent.ACTION_PACKAGE_REPLACED)) {
     // Log that a new update is has been found
     Log.d("mTag","New version of the app has been installed.");
     Log.d("mTag", "Intent data: " + intent.getDataString());
     Log.d("mTag","My package: " + mPackage);
    }
   }
  };

  Log.d("mTag","In the service onCreate() method.");
  IntentFilter filter = new IntentFilter();
  filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
  filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
  filter.addAction(Intent.ACTION_PACKAGE_ADDED);
  registerReceiver(mUpdateReceiver,filter);
 }

 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
  Log.d("mTag","UpdateService started");            
  return Service.START_STICKY;
 }

 @Override
 public void onDestroy() {
  super.onDestroy();
  unregisterReceiver(mUpdateReceiver);
  Log.d("mTag","Service destroyed");
 }

 @Override
 public IBinder onBind(Intent arg0) {
  return null;
 }
}

The Log in the Service onCreate() gets called, which tells me that the service is up and running. However, after installing and replacing some apps through the adb, none of the logs in the BroadcastReceiver the method onReceive() get called.

This is my MainActivity:

public class MainActivity extends Activity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  startService(new Intent(this, UpdateService.class));
 }
}

Do you guys have any ideas why the onReceive() does not get called?

Thank you.

I based my code in these two references:

Upvotes: 3

Views: 3045

Answers (2)

Sami Eltamawy
Sami Eltamawy

Reputation: 9999

If you are trying to listen to the ACTION_PACKAGE_REPLACED broadcast, this cannot be done from service. Most probably, the replacement will happen when your application is closed. That`s why you will not listen to it.

You should register from the Manifest to let your OS know that you want to listen to this Intent then Create a class that extentsBroadcastReceiver` as the following:

Manifest:

 <receiver android:name="PackageChangeReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.PACKAGE_REPLACED" />
            <data android:scheme="package" />
        </intent-filter>
    </receiver>

Receiver:

public class PackageChangeReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED) && intent.getDataString().contains(context.getPackageName())) {
        Log.d("Tag", "Package has been replaced");
        Log.d("Tag", "Intent data: " + intent.getDataString());
        Log.d("Tag", "Action: " + intent.getAction());
    }
}
}

I have checked if intent.getDataString().contains(context.getPackageName()) to make sure that the replacement of the package is mine not any other application.

Upvotes: 2

Changwei Yao
Changwei Yao

Reputation: 13101

you should add the data schema to your IntentFilter.

 IntentFilter filter = new IntentFilter();
  filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
  filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
  filter.addAction(Intent.ACTION_PACKAGE_ADDED);

  filter.addDataScheme("package");

  registerReceiver(mUpdateReceiver,filter);

Upvotes: 6

Related Questions