What is the best way to deal with the following situation: I have a IntentService which does synchronisation with the server (this is triggered by either an Activity coming to the foreground, or a GCM message, so onoy occasional). Sometimes there is a user action needed as a result, and the given command/request is part of the response XML.
There are basically two options, it is either a yes/no question, or a full Activity to for example select the desired language.
How can I do this, or what would be the best way? If I try to launch the Activity with the context of the IntentService nothing happens. I could write a abstract Activity, which I extends in all my Activities and sent a broadcast message which those receive and subsequent start the Activity form the activity which is active, but don't know if that is the best way to do it in Android.
Any suggestions would be appreciated!
[EDIT: as suggested some code]
public class SyncService extends IntentService{
public SyncService(){
super("SyncService");
}
@Override
protected void onHandleIntent(Intent intent) {
iDomsAndroidApp app = ((iDomsAndroidApp) getApplicationContext());
DataManager manager = app.getDataManager();
manager.updateData(this);
}
}
public class DataManager {
// For brevity, this is called with the DOM.Document with the actions to be preformed
private void checkForActions(Document doc, SyncUpdateInterface syncInterface){
NodeList objects = null;
NodeList rootNodes = doc.getElementsByTagName("actions");
for (int j = 0; j < rootNodes.getLength(); j++) {
Element rootElement = (Element) rootNodes.item(j);
if (!rootElement.getParentNode().getNodeName().equals("iDoms")) {
continue;
}
objects = ((Element) rootNodes.item(j)).getElementsByTagName("action");
break;
}
if(objects == null || objects.getLength() == 0){
Log.d(iDomsAndroidApp.TAG, "No actions");
return;
}
for (int j = 0; j < objects.getLength(); j++) {
Element element = (Element) objects.item(j);
String action = ((Element) element.getElementsByTagName("command").item(0)).getTextContent();
if(action == null) return;
Log.d(iDomsAndroidApp.TAG, "Action: " + action);
try{
if(action.equalsIgnoreCase("selectLanguage")){
if(syncInterface == null || syncInterface.getContext() == null) throw new Exception("No context, so cannot perform action");
iDomsAndroidApp app = ((iDomsAndroidApp) iDomsAndroidApp.getAppContext());
// The app.actionIntent is just a central function to pick the right intent for an action.
syncInterface.getContext().startActivity(app.actionIntent("settings", iDomsAndroidApp.context));
} else if (action.equalsIgnoreCase("markAllAsRead")) {
if(syncInterface == null | syncInterface.getContext() == null) throw new Exception("No context, so cannot perform action");
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(syncInterface.getContext());
alertDialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
// User clicked OK, so save the result somewhere
// or return them to the component that opened the dialog
iDomsAndroidApp app = ((iDomsAndroidApp) iDomsAndroidApp.getAppContext());
app.getDataManager().markAllAsRead(null);
}
});
alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
}
});
alertDialogBuilder.setTitle(iDomsAndroidApp.context.getString(R.string.markAllAsRead));
alertDialogBuilder.setMessage(iDomsAndroidApp.context.getString(R.string.markAllAsReadText));
alertDialogBuilder.show();
}
} catch (Exception e){
Log.w(iDomsAndroidApp.TAG, "Problem performing the action " + element.getTextContent(), e);
sentCrashReport("Problem performing the action " + element.getTextContent(), e);
}
}
}
I tried using the my SyncInterface, as it gives the context of the IntentService, but think it is a but clumsy and doesn't work:
public interface SyncUpdateInterface {
public void doProgress(String message, int increment, int total);
public void doProgress(String message, int increment);
public void doProgress(String message);
public Context getContext();
}
You might have to rethink your approach. The intentservice only lives for the duration of the onHandleIntent() method. That is to say, once the last line of code of the onHandleIntent() method is reached, the IntentService stops itself.
Try EventBus. It provides a solution to similar problems by making communication between components (Activities, Services, Standalone classes) of an application.
Use Gradle to import library
compile 'org.greenrobot:eventbus:3.1.1'
Define an event
public class MessageEvent { /* Additional fields if needed */ }
Launch Event using
EventBus.getDefault().post(new MessageEvent());
Register component to receive event
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
Receive launched even by declaring this method
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {/* Do something */};
For more information visit https://github.com/greenrobot/EventBus
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.