GCM消息不会在Android 2.3.6为v,但在Android 4.X第五工作收到罚款 [英] GCM messages are not received on android 2.3.6 v but working fine on android 4.X v

查看:258
本文介绍了GCM消息不会在Android 2.3.6为v,但在Android 4.X第五工作收到罚款的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的GCM客户端能够在所有版本的注册,但消息在的Andr​​oid 4.x版以上的版本,而不是在Android 2.3.6 收到。我已经提前做了很多的变化,但我不明白这个问题了,请帮助我,谢谢。

清单文件code

 <?XML版本=1.0编码=UTF-8&GT?;
<清单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    包=com.democlientapp
    安卓版code =1
    机器人:=的versionName1.0>    <用途-SDK
        安卓的minSdkVersion =8
        机器人:targetSdkVersion =19/>
    <使用许可权的android:NAME =android.permission.INTERNET对/>
    <使用许可权的android:NAME =android.permission.GET_ACCOUNTS/>
    <使用许可权的android:NAME =android.permission.WAKE_LOCK/>    <使用许可权的android:NAME =android.permission.C2D_MESSAGE/>
    <使用许可权的android:NAME =com.google.android.c2dm.permission.RECEIVE/>    <允许机器人:名字=com.democlientapp.permission.C2D_MESSAGE
        安卓的ProtectionLevel =签名/>
    <使用许可权的android:NAME =com.democlientapp.permission.C2D_MESSAGE/>    <应用
        机器人:allowBackup =真
        机器人:图标=@绘制/ ic_launcher
        机器人:标签=@字符串/ APP_NAME
        机器人:主题=@风格/ AppTheme>        <元数据机器人:名字=com.google.android.gms.version
               机器人:值=@整数/ GOOGLE_PLAY_SERVICES_VERSION/>        <活动机器人:名字=com.google.android.gms.ads.AdActivity
             android:configChanges=\"keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize\"/>        <活动
            机器人:名字=com.democlientapp.RegisterActivity
            机器人:标签=@字符串/ APP_NAME>
            &所述;意图滤光器>
                <作用机器人:名字=android.intent.action.MAIN/>                <类机器人:名字=android.intent.category.LAUNCHER/>
            &所述; /意图滤光器>
        < /活性GT;
        <活动
            机器人:名字=com.democlientapp.MainActivity
            机器人:标签=@字符串/ APP_NAME>        < /活性GT;
         <接收
            机器人:名字=com.democlientapp.GcmBroadcastReceiver
            机器人:权限=com.google.android.c2dm.permission.SEND>
              &所述;意图滤光器>
                <作用机器人:名字=com.google.android.c2dm.intent.RECEIVE/>
               <作用机器人:名字=com.google.android.c2dm.intent.REGISTRATION/>                <类机器人:名字=com.democlientapp/>
            &所述; /意图滤光器>
        < /接收器>
        <服务机器人:名字=com.democlientapp.GcmIntentService/>
    < /用途>< /清单>

GCMBrodcastReceiver.java

 包com.democlientapp;进口android.app.Activity;
进口android.content.ComponentName;
进口android.content.Context;
进口android.content.Intent;
进口android.support.v4.content.WakefulBroadcastReceiver;
进口android.util.Log;公共类GcmBroadcastReceiver扩展WakefulBroadcastReceiver {
    @覆盖
    公共无效的onReceive(上下文的背景下,意图意图){
        Log.i(标签,**************** GcmBroadcastReceiver.java OK *************);
        //明确指定GcmIntentService将处理这个意图。
        组件名补偿=新的组件名(context.getPackageName()
                GcmIntentService.class.getName());
        //启动该服务,保持清醒的设备,而它正在启动。
        startWakefulService(上下文,(intent.setComponent(化合物)));
        的setResult code(Activity.RESULT_OK);    }
}

GCMIntentService.java

 包com.democlientapp;进口android.app.IntentService;
进口android.app.NotificationManager;
进口android.app.PendingIntent;
进口android.content.Context;
进口android.content.Intent;
进口android.content.Shared preferences;
进口android.content.Shared preferences.Editor;
进口android.os.Bundle;
进口android.os.SystemClock;
进口android.support.v4.app.NotificationCompat;
进口android.util.Log;进口com.google.android.gms.gcm.GoogleCloudMessaging;公共类GcmIntentService扩展IntentService {
    公共静态INT NOTIFICATION_ID = 1;
    私人NotificationManager mNotificationManager;
    NotificationCompat.Builder建设者;
    字符串标记=标记;
    共享preferences SP;
    StringBuffer的SB;    公共GcmIntentService(){        超级(GcmIntentService);
    }    @覆盖
    保护无效onHandleIntent(意向意图){
        Log.i(TG,意图sservice ******************);
        字符串extras1 = intent.getExtras()的getString(数据)。
        //Log.i(\"tag,串演员:+ extras1.toString());
        捆绑额外= intent.getExtras();
        //Log.i(\"tag,捆绑演员:+临时演员);        Google云端通讯GCM = GoogleCloudMessaging.getInstance(本);
        //该getMessageType()意图参数必须是您收到的意图
        //你的广播接收器。
        字符串为messageType = gcm.getMessageType(意向);        如果(!extras.isEmpty()){//具有unparcelling捆绑的效果
               Log.i(标签,进);
            / *
             *根据消息类型过滤消息。因为它是可能的GCM
             *将在未来新的消息类型进行扩展,只是忽略
             *任何消息类型你不感兴趣,或者你不
             *辨认。
             * /
            如果(Google云端通讯。
                    MESSAGE_TYPE_SEND_ERROR.equals(为messageType)){
                sendNotification的(发送错误:+ extras.toString());
            }否则如果(Google云端通讯。
                    MESSAGE_TYPE_DELETED.equals(为messageType)){
                sendNotification的(在服务器上删除的邮件:+
                        extras.toString());
            //如果是一个普通GCM消息,做了一些工作。
            }否则如果(Google云端通讯。
                    MESSAGE_TYPE_MESSAGE.equals(为messageType)){
                //这个循环再presents服务做了一些工作。
                的for(int i = 0;我小于5;我++){
                    Log.i(TAG,工作......+(I + 1)
                            +/ 5 @+ SystemClock.elapsedRealtime());
                    尝试{
                        视频下载(1000);
                    }赶上(InterruptedException的E){
                    }
                }
                Log.i(TAG,已完成的工作@+ SystemClock.elapsedRealtime());
                Log.i(TAG,收到:+ extras.toString());
                接收到的消息的//发布通知。
                sendNotification时(收到:+临时演员);            }
        }
        //Log.i(TAGReceived11111111111111111111);
        // sendNotification时(收稿日期:registeration+临时演员);
        //释放该WakefulBroadcastReceiver提供的唤醒锁。
        //Log.i(TAGReceived22222222222222222222222);
        GcmBroadcastReceiver.completeWakefulIntent(意向);
        //Log.i(TAGReceived3333333333333333);
    }    //消息放入一个通知,并张贴。
    //这只是一个简单的,你可以选择用做例子
    //一个GCM消息。
    私人无效sendNotification时(弦乐味精){
        Log.i(标签,GcmBroadcastReceiver.java发送通知);
        //存储信息共享preference
        StoreMsg(MSG);        mNotificationManager =(NotificationManager)
                this.getSystemService(Context.NOTIFICATION_SERVICE);        的PendingIntent contentIntent = PendingIntent.getActivity(在此,0,新意图(此,MainActivity.class),0);        NotificationCompat.Builder mBuilder =
                新NotificationCompat.Builder(本)
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle(间谍通知)
        .setStyle(新NotificationCompat.BigTextStyle()
        .bigText(MSG))
        .setContentText(MSG);        mBuilder.setContentIntent(co​​ntentIntent);
        mNotificationManager.notify(NOTIFICATION_ID,mBuilder.build());
        //mNotificationManager.no
        // NOTIFICATION_ID ++;
    }    公共无效StoreMsg(字符串消息)
    {
        字符串名称=我的preFS
         SP = this.getShared preferences(姓名,Context.MODE_PRIVATE);
          SB =新的StringBuffer();
         字符串毫克= sp.getString(信息,假);         如果(mg.equals(假)){
         //sb.append(mg);
         sb.append(MSG);
         }
         其他{
             sb.append(毫克+\\ n ****************);
             sb.append(\\ n+味精);         }        Log.i(标签,storemsg是:+ SB);
        编辑编辑= sp.edit();
         editor.putString(消息,sb.toString());
         //Log.i(\"tag\",\"Gcmintentservice.java,MESSAGES存储共享preferences);
         editor.commit();
         //Log.i(\"tag,registeractivity.java,OnClick方法的客户端的用户名存在于DB);    }
    公众的getMsg字符串(){
        字符串名称=我的preFS
         SP = this.getShared preferences(姓名,Context.MODE_PRIVATE);
        字符串prefName = sp.getString(信息,假);
        Log.i(标签,storemsg是:+ SB);
        返回prefName;    }
}


解决方案

如果您使用的是产品的口味,也许你有同样的问题比我找到了。

我发现,使用与diferent的applicationID口味的时候,那么你的包的权限和类别AndroidManifest文件是不正确的。
这不要紧为Android 5.x的,但对于Android 2.3的原因是,广播接收器将永远不会被调用。

我找到的解决方案是使用gradle这个的<一个href=\"http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger#TOC-Placeholder-support\"相对=nofollow>占位符支持。使用的 $ {}的applicationID 问题已解决了所有的Andr​​oid版本。

的build.gradle

  productFlavors {
    督促{
        的applicationIDcom.democlientapp
    }
    开发{
        的applicationIDcom.democlientapp.dev
    }
}

的Andr​​oidManifest.xml

 &LT;?XML版本=1.0编码=UTF-8&GT?;
&LT;清单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    包=com.democlientapp
    安卓版code =1
    机器人:=的versionName1.0&GT;    &LT;用途-SDK
        安卓的minSdkVersion =8
        机器人:targetSdkVersion =19/&GT;
    &LT;使用许可权的android:NAME =android.permission.INTERNET对/&GT;
    &LT;使用许可权的android:NAME =android.permission.GET_ACCOUNTS/&GT;
    &LT;使用许可权的android:NAME =android.permission.WAKE_LOCK/&GT;    &LT;使用许可权的android:NAME =android.permission.C2D_MESSAGE/&GT;
    &LT;使用许可权的android:NAME =com.google.android.c2dm.permission.RECEIVE/&GT;    &LT;允许机器人:名字=$ {}的applicationID .permission.C2D_MESSAGE
        安卓的ProtectionLevel =签名/&GT;
    &LT;使用许可权的android:NAME =$ {}的applicationID .permission.C2D_MESSAGE/&GT;    &lt;应用
        机器人:allowBackup =真
        机器人:图标=@绘制/ ic_launcher
        机器人:标签=@字符串/ APP_NAME
        机器人:主题=@风格/ AppTheme&GT;        &LT;元数据机器人:名字=com.google.android.gms.version
               机器人:值=@整数/ GOOGLE_PLAY_SERVICES_VERSION/&GT;        &LT;活动机器人:名字=com.google.android.gms.ads.AdActivity
             android:configChanges=\"keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize\"/>        &LT;活动
            机器人:名字=com.democlientapp.RegisterActivity
            机器人:标签=@字符串/ APP_NAME&GT;
            &所述;意图滤光器&gt;
                &lt;作用机器人:名字=android.intent.action.MAIN/&GT;                &LT;类机器人:名字=android.intent.category.LAUNCHER/&GT;
            &所述; /意图滤光器&gt;
        &LT; /活性GT;
        &LT;活动
            机器人:名字=com.democlientapp.MainActivity
            机器人:标签=@字符串/ APP_NAME&GT;        &LT; /活性GT;
         &lt;接收
            机器人:名字=com.democlientapp.GcmBroadcastReceiver
            机器人:权限=com.google.android.c2dm.permission.SEND&GT;
              &所述;意图滤光器&gt;
                &lt;作用机器人:名字=com.google.android.c2dm.intent.RECEIVE/&GT;
               &lt;作用机器人:名字=com.google.android.c2dm.intent.REGISTRATION/&GT;                &LT;类机器人:名字=$ {}的applicationID/&GT;
            &所述; /意图滤光器&gt;
        &LT; /接收器&GT;        &LT;服务机器人:名字=com.democlientapp.GcmIntentService/&GT;
    &LT; /用途&gt;&LT; /清单&GT;

My GCM client is able to register on all versions but messages are received on android above 4.x versions, not on android 2.3.6. I have made many changes but I cannot figure this problem out please help me, thanks in advance.

manifest file code

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.democlientapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />


    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <uses-permission android:name="android.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <permission android:name="com.democlientapp.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.democlientapp.permission.C2D_MESSAGE" />



    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <meta-data android:name="com.google.android.gms.version"
               android:value="@integer/google_play_services_version"/>

        <activity android:name="com.google.android.gms.ads.AdActivity"
             android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>



        <activity
            android:name="com.democlientapp.RegisterActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.democlientapp.MainActivity"
            android:label="@string/app_name" >

        </activity>
         <receiver
            android:name="com.democlientapp.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
              <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
               <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="com.democlientapp" />
            </intent-filter>
        </receiver>  




        <service android:name="com.democlientapp.GcmIntentService" />
    </application>

</manifest>

GCMBrodcastReceiver.java

package com.democlientapp;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("tag", "****************GcmBroadcastReceiver.java ok*************");
        // Explicitly specify that GcmIntentService will handle the intent.
        ComponentName comp = new ComponentName(context.getPackageName(),
                GcmIntentService.class.getName());
        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);

    }


}

GCMIntentService.java

package com.democlientapp;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;

public class GcmIntentService extends IntentService {
    public static  int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;
    String TAG="tag";
    SharedPreferences sp;
    StringBuffer sb;

    public GcmIntentService() {

        super("GcmIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i("tg", "intent sservice******************");
        String extras1 = intent.getExtras().getString("data");
        //Log.i("tag", "string extras :"+extras1.toString());
        Bundle extras=intent.getExtras();
        //Log.i("tag", "bundle extras :"+extras);

        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        // The getMessageType() intent parameter must be the intent you received
        // in your BroadcastReceiver.
        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {  // has effect of unparcelling Bundle
               Log.i("tag", "entered");
            /*
             * Filter messages based on message type. Since it is likely that GCM
             * will be extended in the future with new message types, just ignore
             * any message types you're not interested in, or that you don't
             * recognize.
             */
            if (GoogleCloudMessaging.
                    MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
                sendNotification("Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.
                    MESSAGE_TYPE_DELETED.equals(messageType)) {
                sendNotification("Deleted messages on server: " +
                        extras.toString());
            // If it's a regular GCM message, do some work.
            } else if (GoogleCloudMessaging.
                    MESSAGE_TYPE_MESSAGE.equals(messageType)) {
                // This loop represents the service doing some work.
                for (int i=0; i<5; i++) {
                    Log.i(TAG, "Working... " + (i+1)
                            + "/5 @ " + SystemClock.elapsedRealtime());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                }
                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
                Log.i(TAG, "Received: " + extras.toString());
                // Post notification of received message.
                sendNotification("Received: " + extras);

            }
        }
        //Log.i(TAG, "Received11111111111111111111");
        //sendNotification("Received: registeration "+extras);
        // Release the wake lock provided by the WakefulBroadcastReceiver.
        //Log.i(TAG, "Received22222222222222222222222");
        GcmBroadcastReceiver.completeWakefulIntent(intent);
        //Log.i(TAG, "Received3333333333333333");
    }

    // Put the message into a notification and post it.
    // This is just one simple example of what you might choose to do with
    // a GCM message.
    private void sendNotification(String msg) {
        Log.i("tag","GcmBroadcastReceiver.java send notification");
        //storing message in shared preference
        StoreMsg(msg);



        mNotificationManager = (NotificationManager)
                this.getSystemService(Context.NOTIFICATION_SERVICE);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);

        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle("Spy notification")
        .setStyle(new NotificationCompat.BigTextStyle()
        .bigText(msg))
        .setContentText(msg);

        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
        //mNotificationManager.no
        //NOTIFICATION_ID++;
    }

    public void StoreMsg(String Msg)
    {
        String  name="MyPrefs";
         sp = this.getSharedPreferences(name, Context.MODE_PRIVATE);
          sb=new StringBuffer();
         String mg = sp.getString("MESSAGES", "false");

         if (mg.equals("false")) {
         //sb.append(mg);
         sb.append(Msg);
         }
         else{
             sb.append(mg+"\n****************");
             sb.append("\n"+Msg);

         }

        Log.i("tag", "storemsg is: "+sb);
        Editor editor = sp.edit();
         editor.putString("MESSAGES",sb.toString());
         //Log.i("tag","Gcmintentservice.java,MESSAGES storing SharedPreferences");
         editor.commit();
         //Log.i("tag", "registeractivity.java, onclick method client username exists in DB");



    }
    public String getMsg(){
        String  name="MyPrefs";
         sp = this.getSharedPreferences(name, Context.MODE_PRIVATE);
        String prefName = sp.getString("MESSAGES", "false");
        Log.i("tag", "storemsg is: "+sb);
        return prefName;

    }
}

解决方案

If you are using product flavors maybe you have the same problem than I found.

I found that when using flavors with diferent applicationId, then your package in the AndroidManifest file for the permission and the category is not correct. And this does not matter for Android 5.x, but for Android 2.3 causes that the broadcast receiver will never be called.

The solution I found is use the gradle's placeholder support. Using ${applicationId} the issue is resolved for all the Android versions.

build.gradle:

productFlavors {
    prod {
        applicationId 'com.democlientapp'
    }
    dev {
        applicationId 'com.democlientapp.dev'
    }
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.democlientapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />


    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <uses-permission android:name="android.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <permission android:name="${applicationId}.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />



    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <meta-data android:name="com.google.android.gms.version"
               android:value="@integer/google_play_services_version"/>

        <activity android:name="com.google.android.gms.ads.AdActivity"
             android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>



        <activity
            android:name="com.democlientapp.RegisterActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.democlientapp.MainActivity"
            android:label="@string/app_name" >

        </activity>
         <receiver
            android:name="com.democlientapp.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
              <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
               <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="${applicationId}" />
            </intent-filter>
        </receiver>    

        <service android:name="com.democlientapp.GcmIntentService" />
    </application>

</manifest>

这篇关于GCM消息不会在Android 2.3.6为v,但在Android 4.X第五工作收到罚款的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆