paul_schaefer
paul_schaefer

Reputation: 431

Call activity method from intent service

There are many questions on how to invoke an activity method from a service using a broadcast receiver or an interface. But the examples often differs from my case.

I have an activity that sends a registration request to a server. This server sends it's requested answer via google cloud messaging (GCM). To receive the answer I use a service.

My manifest:

<!-- receiver to handle GCM messages -->
<receiver
   android:name="com.google.android.gcm.GCMBroadcastReceiver"
   android:permission="com.google.android.c2dm.permission.SEND" >
   <intent-filter>
      <!-- Receives the actual messages. -->
      <action android:name="com.google.android.c2dm.intent.RECEIVE" />
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
      <category android:name="com.example.myapp" />
   </intent-filter>
</receiver>
<service android:name=".GCMIntentService" />

In my activity, I have a switch. If the user checks the switch the registration process starts and I disable the switch, so the user could not change the switch state during the registration process. After a certain time (about 5 Min) the server sends the answer.

Depending on the answer, I want to set the state of the switch (checked or unchecked) and enable the switch again.

My question is now, how can I achieve this behaviour? How can I invoke a method in the activity?

The next problem is that the user probably closes the app because the request needs some time. How can I achieve, that the method will be executed even if the activity was closed?

Regarding the questions, I have read in the forum I would use a LocalBroadcastReceiver. Would this receiver work, if the app was closed? Or if it is closed, would it bring the activity to the front (I don't want this)?

Upvotes: 0

Views: 1107

Answers (2)

Tixeon
Tixeon

Reputation: 930

The easiest way i can think for your problem is to use LocalBroadcastManger. In my current project, there is beacon impl... Whenever i receive signal from beacon in background service, I broadcast intent to activity.

AndroidManifest.xml

<service
      android:exported="true"
      android:name="com.yourpackage.ServiceName"/>

In your service

 Intent i = new Intent();
 i.setAction(BeaconHelper.ACTION_BEACON_TRIGGER);
 i.putExtra("data", "my_data");
 LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i)

In your activity's onCreate() or onResume()

registerReceiver(mReceiver,new IntentFilter(BeaconHelper.ACTION_BEACON_TRIGGER));

MyReceiver.java

 public class MyReceiver extends BroadcastReceiver {

    MyReceiver() {
       
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive() called with: context = [" + context + "], intent = [" + intent + "]");

        try {
            switch (intent.getAction()){
                case BeaconHelper.ACTION_BEACON_TRIGGER:
                        //here is my beacon impl
                   break;

                default:
                    break;

            }
        } catch (JSONException | NullPointerException e) {
            e.printStackTrace();
        }
    }

    
}     

LocalBroadcastManager only work if your activity and service in same process. If you had put process as <service process=":myprocess"/> inside manifest, it won't probably work.

Make sure you unregister after activity got destroyed . :-) .

Upvotes: 0

Nir Duan
Nir Duan

Reputation: 6392

You can do some work-arounds to achieve this by re-create your Activity again but this wouldn't be best practice (And also complicated to code).
I would use SharedPreferences, which is a simple to use data file that you can read from anywhere inside your app (e.g your receiver or your activity).
Inside the Receiver -

// PREFS_FILE_NAME - a static String variable like: 
public static final String PREFS_FILE_NAME = "MyPrefsFile";
SharedPreferences.Editor editor = getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE).edit();
 editor.putBoolean("mySwitchOn", true);
 editor.commit();

Inside the Activity -

public static final String PREFS_FILE_NAME = "MyPrefsFile";
SharedPreferences prefs = getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE);    
  Boolean mSwitchOn = prefs.getBoolean("mySwitchOn", true);//"True is the default value if no value was found.
  //Do what you need with mSwitchOn
}

Upvotes: 1

Related Questions