簡體   English   中英

Android App和Android庫之間的GCM沖突

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM