繁体   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