Skip to content

Instantly share code, notes, and snippets.

@volodia-chornenkyy
Created April 1, 2019 21:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save volodia-chornenkyy/0613727510ba88da80465cf5440522b6 to your computer and use it in GitHub Desktop.
Save volodia-chornenkyy/0613727510ba88da80465cf5440522b6 to your computer and use it in GitHub Desktop.
Handling of multiple FirebaseMessagingService
public class OwnPushService extends FirebaseMessagingService {
private List<FirebaseMessagingService> messagingServices = new ArrayList<>(2);
public GCPushService() {
messagingServices.add(new AirshipFirebaseMessagingService());
messagingServices.add(new TLFirebaseMessagingService());
}
@Override
public void onNewToken(String s) {
delegate(service -> {
injectContext(service);
service.onNewToken(s);
});
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
delegate(service -> {
injectContext(service);
service.onMessageReceived(remoteMessage);
});
}
private void delegate(GCAction1<FirebaseMessagingService> action) {
for (FirebaseMessagingService service : messagingServices) {
action.run(service);
}
}
private void injectContext(FirebaseMessagingService service) {
// tested on emulator with Android Q (Dev Preview 1)
// Accessing hidden field Landroid/content/ContextWrapper;->mBase:Landroid/content/Context; (greylist, reflection)
//
// https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces
// https://android.googlesource.com/platform/frameworks/base/+/pie-release/config/hiddenapi-light-greylist.txt
setField(service, "mBase", this);
}
private boolean setField(Object targetObject, String fieldName, Object fieldValue) {
Field field;
try {
field = targetObject.getClass().getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
field = null;
}
Class superClass = targetObject.getClass().getSuperclass();
while (field == null && superClass != null) {
try {
field = superClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
superClass = superClass.getSuperclass();
}
}
if (field == null) {
return false;
}
field.setAccessible(true);
try {
field.set(targetObject, fieldValue);
return true;
} catch (IllegalAccessException e) {
return false;
}
}
interface GCAction1<T> {
void run(T t);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment