Reputation: 431
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
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
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