Android 无法从gcm获取注册id

Android 无法从gcm获取注册id,android,google-cloud-messaging,Android,Google Cloud Messaging,我在用这个 获取推送通知的教程 我无法从gcm获取注册id,因为GCMinentService 类在mainActivity中的寄存器id变为null后运行 执行mainActivity时,注册id始终为空。之后 有时只有我从GCMinentService获得注册id 我正在使用根包中的所有gcm代码 下面我发布了与此相关的代码 MainActivity.java: GCMRegistrar.checkDevice(MainActivity.this); GCMRegistrar.c

我在用这个 获取推送通知的教程

  • 我无法从gcm获取注册id,因为GCMinentService 类在mainActivity中的寄存器id变为null后运行

  • 执行mainActivity时,注册id始终为空。之后 有时只有我从GCMinentService获得注册id

  • 我正在使用根包中的所有gcm代码

  • 下面我发布了与此相关的代码

  • MainActivity.java:

    GCMRegistrar.checkDevice(MainActivity.this);
    
        GCMRegistrar.checkManifest(MainActivity.this);
    
        lblMessage = (TextView) findViewById(R.id.lblMessage);
    
        registerReceiver(mHandleMessageReceiver,new IntentFilter(DISPLAY_MESSAGE_ACTION));
    
        Log.e("mHandleMessageReceiver", ""+mHandleMessageReceiver);
    
        // Get GCM registration id
        final String regId = GCMRegistrar.getRegistrationId(MainActivity.this);
    
        Log.e("CheckRegId", ""+regId);
    
    
        // Check if regid already presents
    
        if (regId.equals("")) {
        // Registration is not present, register now with GCM           
        GCMRegistrar.register(MainActivity.this, SENDER_ID);
    
        Log.e("RegIDNull", "RegIdNull");
    
        } else {
    
        // Device is already registered on GCM
    
        if (GCMRegistrar.isRegisteredOnServer(MainActivity.this)) {
    
        Toast.makeText(getApplicationContext(), "Already registered with GCM", Toast.LENGTH_LONG).show();
        } else {
    
    
        Log.e("HitAynscReg", "HitAynscReg");
    
    
        mRegisterTask = new AsyncTask<Void, Void, Void>() {
    
        @Override
        protected Void doInBackground(Void... params) {
    
        ServerUtilities.register(MainActivity.this, appVersionNameStr,regId, deviceUserId, getDeviceNameStr, "Android", androidVersionNameBuilder.toString(), 
                                                    String.valueOf(latitude), String.valueOf(longitude), address+", "+areaName+", "+city, userid );
    
    
        return null;
        }
    
        @Override
    
        protected void onPostExecute(Void result) {
        mRegisterTask = null;
    
        }
    
        };
        mRegisterTask.execute(null, null, null);
    
        }
        }
    
       <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
        <!-- GCM requires a Google account. -->
        <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    
        <!-- Keeps the processor from sleeping when a message is received. -->
        <uses-permission android:name="android.permission.WAKE_LOCK" />
    
        <!-- Creates a custom permission so only this app can receive its messages. -->
        <permission
            android:name="com.app.steve.permission.C2D_MESSAGE"
            android:protectionLevel="signature" />
    
        <uses-permission android:name="com.app.steve.permission.C2D_MESSAGE" />
    
        <!-- This app has permission to register and receive data message. -->
        <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    
        <!-- Network State Permissions to detect Internet status -->
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
        <!-- Permission to vibrate -->
        <uses-permission android:name="android.permission.VIBRATE" />
    
       <application
        android:name="com.golive.entertainment.volley.AppController"
        android:allowBackup="true"
        android:hardwareAccelerated="false"
        android:icon="@drawable/client_logo"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:theme="@style/AppTheme" >
    
         .......
         .......
         <activity
            android:name="com.app.steve.MainActivity"
            android:screenOrientation="portrait" >
        </activity>
    
    
          <receiver
                android:name="com.google.android.gcm.GCMBroadcastReceiver"
                android:permission="com.google.android.c2dm.permission.SEND" >
                <intent-filter>
    
                    <!-- Receives the actual messages. -->
                    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                    <!-- Receives the registration id. -->
                    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
    
                    <category android:name="com.app.steve" />
                </intent-filter>
            </receiver>
    
            <service android:name=".GCMIntentService" />
    
          </application>
    
    public class GCMIntentService extends GCMBaseIntentService {
    
        private static final String TAG = "GCMIntentService";
    
        public GCMIntentService() {
            super(SENDER_ID);
    
            Log.e("GCMIntentServiceConstructorCalling", "Test");
        }
    
        /**
         * Method called on device registered
         **/
        @Override
        protected void onRegistered(Context context, String registrationId) {
    
            Log.e("GCMIntentServiceRegID", ""+registrationId);      
    
            displayMessage(context, "Your device registred with GCM");
    
            ServerUtilities.register(GCMIntentService.this, MainActivity.appVersionNameStr,registrationId, MainActivity.deviceUserId, MainActivity.getDeviceNameStr, "Android", MainActivity.androidVersionNameBuilder.toString(), 
                    String.valueOf(MainActivity.latitude), String.valueOf(MainActivity.longitude), MainActivity.address+", "+MainActivity.areaName+", "+MainActivity.city, MainActivity.userid );
    
    
        }
    
    如果我在mainACtivity中的注册id代码之前运行GCMinentService,我可以得到预期的结果。任何人都知道如何解决此问题。

    您可以使用

    Google提供实例ID API来处理注册令牌的创建和更新。要使用此API,请在清单中包括InstanceIDListenerService:

    <service android:name="[.MyInstanceIDService]" android:exported="false">
      <intent-filter>
             <action android:name="com.google.android.gms.iid.InstanceID"/>
      </intent-filter>
    </service>
    
    }


    收到注册令牌后,请确保将其发送到服务器。

    将其添加到您的清单中

    <!-- [START gcm_receiver] -->
        <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="gcm.play.android.samples.com.gcmquickstart" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
            </intent-filter>
        </receiver>
        <!-- [END gcm_receiver] -->
    
        <!-- [START gcm_listener] -->
        <service
            android:name=".utils.gcm.ListenerServiceGCM"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>
        <!-- [END gcm_listener] -->
        <!-- [START instanceId_listener] -->
        <service
            android:name=".utils.gcm.InstanceIDListenerServiceGCM"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.gms.iid.InstanceID"/>
            </intent-filter>
        </service>
        <!-- [END instanceId_listener] -->
        <service
            android:name=".utils.gcm.RegistrationIntentServiceGCM"
            android:exported="false">
        </service>
    
        <service android:name=".notifications.NotifyService" />
    
        <receiver
            android:name=".notifications.OrderResponseReceiver"
            android:enabled="true"
            android:exported="false">
            <intent-filter>
                <action android:name="com.notif.test.action_accept" />
                <action android:name="com.notif.test.action_reject" />
            </intent-filter>
        </receiver>
    

    您需要在包本身中直接声明gcminentservice类,例如

    com.example.demoapp.GCMIntentService;
    
    如果在任何文件夹中声明了gcminentservice类,则不会获得注册id。

    以下是我在项目中完成的实现。
    
    Here is the implementation which I have done in my project.    
        GCMBroadcastReciever.java
    
            public class GCMBroadcastReciever extends WakefulBroadcastReceiver {
    
                @Override
                public void onReceive(Context context, Intent intent) {
                    // Attach component of GCMIntentService that will handle the intent in background thread
                    ComponentName comp = new ComponentName(context.getPackageName(),
                            GCMIntentServices.class.getName());
                    // Start the service, keeping the device awake while it is launching.
                    startWakefulService(context, (intent.setComponent(comp)));
                    setResultCode(Activity.RESULT_OK);
                }
            }
    
            GCMIntentService.java
    
    
            public class GCMIntentServices extends IntentService {
    
                public static final int NOTIFICATION_ID = 1000;
                NotificationManager mNotificationManager;
                NotificationCompat.Builder builder;
    
                public GCMIntentServices() {
                    super(GCMIntentServices.class.getName());
                }
    
                @Override
                protected void onHandleIntent(Intent intent) {
                    Bundle extras = intent.getExtras();
    
                    if (!extras.isEmpty()) {
    
                        // read extras as sent from server
                        String message = extras.getString("message");
                        String serverTime = extras.getString("timestamp");
                        sendNotification("Message: " + message + "\n" + "Server Time: "
                                + serverTime);
                    }
                    // Release the wake lock provided by the WakefulBroadcastReceiver.
                    GCMBroadcastReciever.completeWakefulIntent(intent);
                }
    
                private void sendNotification(String msg) {
                    mNotificationManager = (NotificationManager) 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_arrow_up_blue_soft)
                            .setContentTitle("Notification from GCM")
                            .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
                            .setContentText(msg);
    
                    mBuilder.setContentIntent(contentIntent);
                    mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
                }
            }
    
    
              private class GCMRegistrationTask extends AsyncTask<Void, Void, String> {
    
                    @Override
                    protected String doInBackground(Void... params) {
                        // TODO Auto-generated method stub
                        if (gcm == null) {
                            gcm = GoogleCloudMessaging.getInstance(getApplicationContext());
                        }
                        try {
                            regId = gcm.register(GlobalConfig.YOUR_SENDER_ID);
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
    
                        return regId;
                    }
    
                    @Override
                    protected void onPostExecute(String result) {
                        if (result != null) {
                            Log.e("reg", result);
    
                            GlobalCommonMethods.saveValueOnUserPrefernces(MainActivity.this, result, "reg_id");
            //                Toast.makeText(getApplicationContext(), "registered with GCM"+regId,
            //                        Toast.LENGTH_LONG).show();
            //                reg();
                        }
                    }
    
                }
    
    
        manifest.xml
    
           <receiver
                    android:name=".helperclass.GCMBroadcastReciever"
                    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.geeks.schoolmanagement"/>
                    </intent-filter>
                </receiver>
    
                <service android:name=".helperclass.GCMIntentServices"/>
                <!-- make sure to add google-play-services_lib from  project properties->android->library-->
                <meta-data
                    android:name="com.google.android.gms.version"
                    android:value="@integer/google_play_services_version" />
         <uses-permission android:name="android.permission.WAKE_LOCK"/>
            <!-- For vibrating device -->
            <uses-permission android:name="android.permission.VIBRATE"/>
            <!-- For receiving GCM messages -->
            <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
            <!-- For protecting GCM messages so that only your app can receive them -->
            <permission
                android:name="com.geeks.schoolmanagement.permission.C2D_MESSAGE"
                android:protectionLevel="signature" />
            <uses-permission android:name="com.geeks.schoolmanagement.permission.C2D_MESSAGE" />
    
    GCMBroadcastReciever.java 公共类GCMBroadcastReciever扩展WakefulBroadcastReceiver{ @凌驾 公共void onReceive(上下文、意图){ //附加将在后台线程中处理意图的GCMinentService组件 ComponentName comp=新的ComponentName(context.getPackageName(), gcminentservices.class.getName()); //启动服务,在设备启动时保持设备处于唤醒状态。 startWakefulService(上下文,(intent.setComponent(comp)); setResultCode(Activity.RESULT\u OK); } } gcminentservice.java 公共类GCMinentServices扩展了IntentService{ 公共静态最终整数通知\u ID=1000; 通知经理通知经理; 通知建筑商; 公共服务{ super(gcminentservices.class.getName()); } @凌驾 受保护的手部内容无效(意图){ Bundle extras=intent.getExtras(); 如果(!extras.isEmpty()){ //读取从服务器发送的附加内容 字符串消息=extras.getString(“消息”); String serverTime=extras.getString(“时间戳”); sendNotification(“消息:“+消息+”\n“+”服务器时间: +服务器时间); } //释放唤醒接收器提供的唤醒锁。 GCMBroadcastReciever.completeWakefulIntent(intent); } 私有void sendNotification(字符串msg){ mNotificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION\u服务); PendingEvent contentIntent=PendingEvent.getActivity(此,0, 新意图(this,MainActivity.class),0); NotificationCompat.Builder mBuilder=新建NotificationCompat.Builder( 此).setSmallIcon(R.drawable.ic\u箭头\u向上\u蓝色\u软) .setContentTitle(“GCM通知”) .setStyle(新通知compat.BigTextStyle().bigText(msg)) .setContentText(msg); mBuilder.setContentIntent(contentIntent); mNotificationManager.notify(NOTIFICATION_ID,mBuilder.build()); } } 专用类GCMRRegistrationTask扩展异步任务{ @凌驾 受保护字符串doInBackground(无效…参数){ //TODO自动生成的方法存根 如果(gcm==null){ gcm=GoogleCloudMessaging.getInstance(getApplicationContext()); } 试一试{ regId=gcm.register(GlobalConfig.YOUR\u SENDER\u ID); }捕获(IOE异常){ //TODO自动生成的捕捉块 e、 printStackTrace(); } 返回注册表; } @凌驾 受保护的void onPostExecute(字符串结果){ 如果(结果!=null){ Log.e(“reg”,结果); GlobalCommonMethods.SaveValueOnUserPreferences(MainActivity.this,结果“reg_id”); //Toast.makeText(getApplicationContext(),“已向GCM注册”+regId, //Toast.LENGTH_LONG).show(); //reg(); } } } 清单文件
    我通过在SplashScreenActivity.java类中添加以下行解决了这个问题:

     GCMRegistrar.register(MainActivity.this, SENDER_ID);
    
    单击登录按钮后,我将运行MainActivity.java中的GCM代码,以便获得注册id。因为我们可以有时间从GCM获取注册id。

    com.google.android.c2dm.intent.registration的意义是什么?
     GCMRegistrar.register(MainActivity.this, SENDER_ID);