即使gcm服务器成功发送消息,也无法从服务器接收gcm通知

时间:2015-03-27 15:58:24

标签: android

I have developed my application server that sends the gcm message to the gcm server using http post. When i run my server it gives a response code of 200 that means that the message has been sent successfully by gcm server, but the notification is not displayed on the android device.

I get the registration id of the device successfully and also it is stored in mysql database using httppost correctly.


Here is my C2DMMessageReceiver:

它具有onReceive方法,可识别收到的消息。

package com.example.cloud2devicemessaging;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

public class C2DMMessageReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        String action = intent.getAction();
         Log.w("C2DM", "Message Receiver called");
            if ("com.google.android.c2dm.intent.RECEIVE".equals(action)) {
              Log.w("C2DM", "Received message");

              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 that handles the message received:

package com.example.cloud2devicemessaging;


import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.google.android.gcm.GCMBaseIntentService;

public class GCMIntentService extends GCMBaseIntentService {

    protected GCMIntentService(String senderId) {
        super("1087507874278");
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onError(Context arg0, String arg1) {
        // TODO Auto-generated method stub
        Log.d("Error", arg1);

    }

    @Override
    protected void onMessage(Context context, Intent intent) {

        // TODO Auto-generated method stub
        int icon = R.drawable.eplogo;
        long when = System.currentTimeMillis();
        String message=intent.getExtras().toString(); 

        NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = new Notification(icon, message, when);

        String title = "E-PASS APPLICATION";

        Intent notificationIntent = new Intent(context, resetpass.class);
        // set intent so it does not start a new activity
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
                Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent in =
                PendingIntent.getActivity(context,(int) (Math.random() * 100), notificationIntent, 0);
        notification.setLatestEventInfo(context, title, message, in);
        notification.flags |= Notification.FLAG_AUTO_CANCEL;


        notification.defaults |= Notification.DEFAULT_VIBRATE;
        notificationManager.notify(0, notification);     

    }

    @Override
    protected void onRegistered(Context arg0, String arg1) {
        // TODO Auto-generated method stub
     Log.i("Mobile device registered","Registration successful");
    }

    @Override
    protected void onUnregistered(Context arg0, String arg1) {
        // TODO Auto-generated method stub
 Log.i("Unregister","Mobile  device unregistered");
    }

}


This is the code of my application server that sends message using httppost:

package com.example.gcmserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;

public class Server {
    public static void main(String[] args) throws IOException {

        String url = "https://android.googleapis.com/gcm/send";

        DefaultHttpClient client = new DefaultHttpClient();
        client.getCredentialsProvider().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("username", "password"));
        client.addRequestInterceptor(new HttpRequestInterceptor() {


    @Override
    public void process(HttpRequest arg0, HttpContext context)
            throws HttpException, IOException {
        // TODO Auto-generated method stub
          AuthState state = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
             if (state.getAuthScheme() == null) {
                 BasicScheme scheme = new BasicScheme();
                 CredentialsProvider credentialsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
                 Credentials credentials = credentialsProvider.getCredentials(AuthScope.ANY);
                 if (credentials == null) {
                     throw new HttpException();
                 }
                 state.setAuthScope(AuthScope.ANY);
                 state.setAuthScheme(scheme);
                 state.setCredentials(credentials);
    }}
 }, 0); 








          HttpPost httppost = new HttpPost("https://android.googleapis.com/gcm/send");

          List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
          urlParameters.add(new BasicNameValuePair("data.registration id","APA91bGChJVdx2L1AUIJEVIBBVEkxEAk6zixj5V-L--fDGXudvrtl5gSQDgAP4iUJoMRq57sLSpGtsSQ5gnprX4McOPq7WxglKeQyTmaysVb0r-adOZ4tTjWG2MYwVEayFKy9Rwf1mloVt2jb-_izUdN-SfKvlpUpEYXNNT1987tYASKCcam16g"));




          urlParameters.add(new BasicNameValuePair("data.title", "e-pass application"));
          urlParameters.add(new BasicNameValuePair("data.message", "Your code is 13133"));


          httppost.setHeader("Authorization",
                  "key=AIzaSyDANlJHGPmzo1so_yyqkYZO7LSrQpnR7mk");
          httppost.setHeader("Content-Type",
                  "application/x-www-form-urlencoded;charset=UTF-8");

          httppost.setEntity(new UrlEncodedFormEntity(urlParameters, "UTF-8"));

          HttpResponse response = client.execute(httppost);
          System.out.println("Response Code : " 
                      + response.getStatusLine().getStatusCode());

          BufferedReader rd = new BufferedReader(
                  new InputStreamReader(response.getEntity().getContent()));

          StringBuffer result = new StringBuffer();
          String line = "";
          while ((line = rd.readLine()) != null) {
              result.append(line);
          }
}
}


And finally this is my manifest file in which i have added all the necessary permissions:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.cloud2devicemessaging"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
<permission 
    android:name="com.example.cloud2devicemessaging.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.SEND" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" 
        android:protectionLevel="signature"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="com.example.cloud2devicemessaging.permission.C2D_MESSAGE"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".C2DMRegistrationReceiver" 
            android:permission="com.google.android.c2dm.permission.SEND" >
  <intent-filter>

    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
    <category android:name="com.example.cloud2devicemessaging" />
  </intent-filter>
</receiver>
        <activity android:name="resetpass"></activity>
        <activity android:name="SendingMessage"></activity>


        <receiver
            android:name="com.google.android.gcm.GCMBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter >
                <action android:name="com.google.android.c2dm.intent.RECEIVE" >
                </action>

                <category android:name="om.example.cloud2devicemessaging" />
            </intent-filter>
        </receiver>
        <service android:name=".GCMIntentService" />


    </application>

</manifest>


Thanks in advance for the help

我一直试图解决错误,因为一周但无法解决。在google开发者控制台中,来自应用程序的请求数仍为0。

1 个答案:

答案 0 :(得分:0)

代码看起来不对,您应该遵循本指南:

https://developer.android.com/google/gcm/client.html

我认为你的GcmIntentReceiver错了,例如:

public class GcmIntentService extends IntentService {
    public static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;

    public GcmIntentService() {
        super("GcmIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        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
            /*
             * 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(5000);
                    } catch (InterruptedException e) {
                    }
                }
                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
                // Post notification of received message.
                sendNotification("Received: " + extras.toString());
                Log.i(TAG, "Received: " + extras.toString());
            }
        }
        // Release the wake lock provided by the WakefulBroadcastReceiver.
        GcmBroadcastReceiver.completeWakefulIntent(intent);
    }

    // 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) {
        mNotificationManager = (NotificationManager)
                this.getSystemService(Context.NOTIFICATION_SERVICE);

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

        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_stat_gcm)
        .setContentTitle("GCM Notification")
        .setStyle(new NotificationCompat.BigTextStyle()
        .bigText(msg))
        .setContentText(msg);

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

如果收到GCMmessage,您应该在logcat中看到trace。如果这不起作用,也许是它的APiKey问题,我在谷歌控制台Api中创建密钥时遇到了很多问题。在控制台中,保留ip为空的字段。