[英]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.