remove need for subclassing MessageSendingService and related, instead use meta-data in manifest

This commit is contained in:
Fredrik Teschke
2014-10-04 19:09:10 +02:00
parent 3a5952b1a0
commit 256224ec10
7 changed files with 69 additions and 39 deletions
@@ -17,7 +17,7 @@ import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.FileHandlerUtils;
import com.sap.sailing.android.shared.util.SharedAppConstants;
public abstract class MessagePersistenceManager {
public class MessagePersistenceManager {
private final static String TAG = MessagePersistenceManager.class.getName();
@@ -25,10 +25,13 @@ public abstract class MessagePersistenceManager {
protected Context context;
protected List<String> persistedMessages;
private final MessageRestorer messageRestorer;
public MessagePersistenceManager(Context context) {
public MessagePersistenceManager(Context context, MessageRestorer messageRestorer) {
this.context = context;
persistedMessages = new ArrayList<String>();
this.messageRestorer = messageRestorer;
initializeFileAndPersistedMessages();
}
@@ -106,7 +109,9 @@ public abstract class MessagePersistenceManager {
return persistedMessages;
}
protected abstract void restoreMessage(Intent messageIntent);
public static interface MessageRestorer {
void restoreMessage(Context context, Intent messageIntent);
}
public List<Intent> restoreMessages() {
List<Intent> delayedIntents = new ArrayList<Intent>();
@@ -134,7 +139,7 @@ public abstract class MessagePersistenceManager {
Intent messageIntent = MessageSendingService.createMessageIntent(context, url, callbackPayload,
null, payload, callbackClass);
restoreMessage(messageIntent);
messageRestorer.restoreMessage(context, messageIntent);
if (messageIntent != null) {
delayedIntents.add(messageIntent);
@@ -9,30 +9,54 @@ import java.util.List;
import java.util.Set;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.services.sending.MessagePersistenceManager.MessageRestorer;
import com.sap.sailing.android.shared.services.sending.MessageSenderTask.MessageSendingListener;
import com.sap.sailing.android.shared.util.SharedAppConstants;
import com.sap.sailing.android.shared.util.SharedAppPreferences;
/*
* Sending a message to the webservice
/**
* Service that handles sending messages to a webservice. Deals with an offline setting
* by buffering the messages in a file, so that they can be sent when the connection is
* re-established.<br>
*
* Usage:
* <b>Use in the following way:</b> Add the service declaration to your {@code AndroidManifest.xml},
* and also specify your class implementing the {@link MessagePersistenceManager.MessageRestorer}
* as a meta-data tag with the key {@code com.sap.sailing.android.shared.services.sending.messageRestorer}.
* For example:
* <pre>{@code
* <service
* android:name="com.sap.sailing.android.shared.services.sending.MessageSendingService"
* android:exported="false" >
* <intent-filter>
* <action android:name="com.sap.sailing.android.shared.action.sendSavedIntents" />
* <action android:name="com.sap.sailing.android.shared.action.sendMessage" />
* </intent-filter>
* <meta-data android:name="com.sap.sailing.android.shared.services.sending.messageRestorer"
* android:value="com.sap.sailing.racecommittee.app.services.sending.EventRestorer" />
* </service>
* }</pre>
*
* Sending a message example:
* <pre>{@code
* Intent i = new Intent(SharedAppConstants.SEND_MESSAGE_ACTION);
* i.putExtra(SharedAppConstants.PAYLOAD, JsonUtils.getObjectAsString('someEventObject'));
* i.putExtra(SharedAppConstants.CALLBACK_PAYLOAD, 'raceuuid');
* context.startService(i);
* }</pre>
*/
public abstract class MessageSendingService extends Service implements MessageSendingListener {
public class MessageSendingService extends Service implements MessageSendingListener {
protected final static String TAG = MessageSendingService.class.getName();
@@ -119,7 +143,25 @@ public abstract class MessageSendingService extends Service implements MessageSe
return null;
}
protected abstract MessagePersistenceManager getPersistenceManager();
private MessagePersistenceManager getPersistenceManager() {
ComponentName thisService = new ComponentName(this, this.getClass());
try {
Bundle data = getPackageManager().getServiceInfo(thisService, PackageManager.GET_META_DATA).metaData;
String className = data.getString("com.sap.sailing.android.shared.services.sending.messageRestorer");
Class<?> clazz = Class.forName(className);
if (! MessageRestorer.class.isAssignableFrom(clazz)) {
throw new Exception("Class does not conform to expected type.");
}
@SuppressWarnings("unchecked") //checked above
Class<MessageRestorer> castedClass = (Class<MessageRestorer>) clazz;
MessageRestorer restorer = castedClass.getConstructor().newInstance();
return new MessagePersistenceManager(this, restorer);
} catch (Exception e) {
ExLog.e(TAG, "Could not find message persistence manager. See documentation of MessageSendingService"
+ "on how to register the persistence manager through the manifest. Error Message: " + e.getMessage());
return null;
}
}
/*
* (non-Javadoc)
@@ -84,12 +84,14 @@
</intent-filter>
</service>
<service
android:name=".services.sending.EventSendingService"
android:name="com.sap.sailing.android.shared.services.sending.MessageSendingService"
android:exported="false" >
<intent-filter>
<action android:name="com.sap.sailing.android.shared.action.sendSavedIntents" />
<action android:name="com.sap.sailing.android.shared.action.sendMessage" />
</intent-filter>
<meta-data android:name="com.sap.sailing.android.shared.services.sending.messageRestorer"
android:value="com.sap.sailing.racecommittee.app.services.sending.EventRestorer" />
</service>
<receiver android:name=".receiver.ConnectivityChangedReceiver" >
@@ -16,6 +16,7 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.services.sending.MessageSendingService;
import com.sap.sailing.android.shared.services.sending.MessageSendingService.MessageSendingBinder;
import com.sap.sailing.android.shared.services.sending.ServerReplyCallback;
@@ -24,8 +25,6 @@ import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.racecommittee.app.data.DataManager;
import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.racecommittee.app.services.sending.EventSendingService;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.racelog.impl.RaceLogEventDeserializer;
@@ -97,7 +96,7 @@ public class RaceLogEventsCallback implements ServerReplyCallback {
}
EventSendingConnection connection = new EventSendingConnection(context, eventsToAdd, raceLog);
if (context.bindService(new Intent(context, EventSendingService.class), connection,
if (context.bindService(new Intent(context, MessageSendingService.class), connection,
Context.BIND_AUTO_CREATE)) {
// execution deferred until service is bound
ExLog.i(TAG, "Waiting for sending service to be bound.");
@@ -7,29 +7,25 @@ import org.json.simple.parser.ParseException;
import android.content.Context;
import android.content.Intent;
import com.sap.sailing.android.shared.services.sending.MessagePersistenceManager;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.services.sending.MessagePersistenceManager.MessageRestorer;
import com.sap.sailing.android.shared.util.SharedAppConstants;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.racecommittee.app.data.DataManager;
import com.sap.sailing.racecommittee.app.data.DataStore;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.racelog.impl.RaceLogEventDeserializer;
public class EventPersistenceManager extends MessagePersistenceManager {
public EventPersistenceManager(Context context) {
super(context);
}
private final static String TAG = EventPersistenceManager.class.getName();
public class EventRestorer implements MessageRestorer {
private final static String TAG = EventRestorer.class.getName();
@Override
protected void restoreMessage(Intent messageIntent) {
public void restoreMessage(Context context, Intent messageIntent) {
String raceId = messageIntent.getExtras().getString(SharedAppConstants.CALLBACK_PAYLOAD);
String serializedEventAsJson = messageIntent.getExtras().getString(SharedAppConstants.PAYLOAD);
ExLog.i(TAG, String.format("Trying to re-add event to race log of race %s.", raceId));
DataStore store = DataManager.create(this.context).getDataStore();
DataStore store = DataManager.create(context).getDataStore();
if (!store.hasRace(raceId)) {
ExLog.w(TAG, String.format("There is no race %s.", raceId));
return;
@@ -1,13 +0,0 @@
package com.sap.sailing.racecommittee.app.services.sending;
import com.sap.sailing.android.shared.services.sending.MessagePersistenceManager;
import com.sap.sailing.android.shared.services.sending.MessageSendingService;
public class EventSendingService extends MessageSendingService {
@Override
protected MessagePersistenceManager getPersistenceManager() {
return new EventPersistenceManager(this);
}
}
@@ -13,6 +13,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.services.sending.MessageSendingService;
import com.sap.sailing.android.shared.services.sending.MessageSendingService.MessageSendingBinder;
import com.sap.sailing.android.shared.services.sending.MessageSendingService.MessageSendingServiceLogger;
@@ -20,8 +21,6 @@ import com.sap.sailing.racecommittee.app.AppPreferences;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.RaceApplication;
import com.sap.sailing.racecommittee.app.data.InMemoryDataStore;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.racecommittee.app.services.sending.EventSendingService;
/**
* Base activity for all race committee cockpit activities enabling basic menu functionality.
@@ -136,7 +135,7 @@ public abstract class BaseActivity extends LoggableActivity {
public void onStart() {
super.onStart();
Intent intent = new Intent(this, EventSendingService.class);
Intent intent = new Intent(this, MessageSendingService.class);
bindService(intent, sendingServiceConnection, Context.BIND_AUTO_CREATE);
}