[英]GCM conflict between Android App and Android Library
我正在建立一个使用GCM的图书馆。 我正在用也实现GCM的示例应用程序进行测试。
我对两个都使用了相同的实现,只是每个实现都有自己的发送者ID
这就是我为用于测试库的示例应用程序编写的内容。 我还为库编写了相同的内容,但为服务使用了不同的名称:
<!-- GCM -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.instabug" />
</intent-filter>
</receiver>
<service
android:name=".SampleInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service
android:name=".SampleGcmRegistrationIntentService"
android:exported="false"/>
<service
android:name=".SampleGcmListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
我的问题是,每当我向库发送推式通知时,App接收器始终会捕获该通知。 库接收器什么也不做。
有没有办法解决这个问题?
据我了解,您有两个服务具有相同的意图过滤器。 在这种情况下,Android将选择优先级较高的服务(前景)。 如果优先级相同-将随机选择,即只有一项服务将收到该意图。
对于您的情况,最好的解决方案是仅使用一种服务并根据GcmListenerService中onMessageReceived()
from
(senderId)参数进行GcmListenerService
。
我想办法做到这一点。 在我的Android库中,我给GcmListenerService
的意图过滤器GcmListenerService
了比Android应用程序中更高的优先级,以便该库首先接收和处理GCM消息。
<service
android:name=".SampleGcmListenerService"
android:exported="false">
<intent-filter priority="100">
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
当GCM消息到达库的GcmListenerService
,如果与库无关,则必须转发到android应用。 由于我正在制作一个将来任何人都可以使用的库。 我不知道在app模块中哪里可以找到GcmListenerService
。 我所能做的就是使用反射获取应用模块中的所有类,并查看哪一个具有GcmListenerService
作为超类,然后为该类启动GcmListenerService
服务。
这是我做的:
@Override
public void onMessageReceived(String from, Bundle data) {
if (!from.equalsIgnoreCase("51XXXXXXXX")) {
String[] classes = getClassesOfPackage(getPackageName());
for (int i = 0; i < classes.length; i++) {
String sClassName = classes[i];
try {
Class classToInvestigate = Class.forName(sClassName);
String superClassName = classToInvestigate.getSuperclass().getName();
if (superClassName.equalsIgnoreCase("com.google.android.gms.gcm.GcmListenerService")) {
//sending intent to the wakeful app's service
forwardGcmToApp(from, data, sClassName);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
//TODO: fire the polling service
String message = data.getString("message");
}
}
/**
* Called to get list of classes included in the current project
*
* @param packageName the name of application package
* @return array of classes' names
*/
private String[] getClassesOfPackage(String packageName) {
ArrayList<String> classes = new ArrayList<>();
try {
String packageCodePath = getPackageCodePath();
DexFile df = new DexFile(packageCodePath);
for (Enumeration<String> iter = df.entries(); iter.hasMoreElements(); ) {
String className = iter.nextElement();
if (className.contains(packageName)) {
classes.add(className);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return classes.toArray(new String[classes.size()]);
}
/**
* Called to forward Gcm content to the App {@link GcmListenerService}
*
* @param from Gcm sender ID
* @param data bundle received from Gcm
* @param className Class name that extends {@link GcmListenerService}
*/
private void forwardGcmToApp(String from, Bundle data, String className){
Intent intent = new Intent();
intent.setAction("com.google.android.c2dm.intent.RECEIVE");
data.putString("from", from);
data.putString("message_type", null);
intent.putExtras(data);
intent.setComponent(new ComponentName(getPackageName(), className));
GcmReceiver.startWakefulService(getApplicationContext(), intent);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.