GCM通知接收器/令牌注册

时间:2016-06-15 19:40:39

标签: java android amazon-web-services push-notification google-cloud-messaging

编辑:想出来 - 见下面的答案

我尝试生成注册令牌,将它们存储在服务器中,然后使用令牌发送推送通知。此时,我已成功发送并存储了注册令牌,并且正在从网络API发送通知,但它们并未到达我的设备。我想知道是否/我应该用R.string.gcm_defaultSenderId代替什么(即来自GCM的发件人密钥?)我包括我的代码注册代码以及下面的通知监听器。

public class GCMRegistrationIntentService extends IntentService {

//Constants for success and errors
public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
public static final String REGISTRATION_ERROR = "RegistrationError";

private Context context;
private String sessionGUID = "";
private String userGUID = "";

//Class constructor
public GCMRegistrationIntentService() {
    super("");
}

@Override
protected void onHandleIntent(Intent intent) {
    context = getApplicationContext();
    sessionGUID = RequestQueueSingleton.getInstance(context).getSessionGUID();
    userGUID = RequestQueueSingleton.getInstance(context).getUserGUID();
    //Registering gcm to the device
    registerGCM();

}

//Registers the device to Google Cloud messaging and calls makeAPICall to send the registration
//token to the server
private void registerGCM() {
    //Registration complete intent initially null
    Intent registrationComplete;

    //declare a token, try to find it with a successful registration
    String token;
    try {
        //Creating an instanceid
        InstanceID instanceID = InstanceID.getInstance(this);

        //Getting the token from the instance id
        token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
                GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

        //Display the token, need to send to server
        Log.w("GCMRegIntentService", "token:" + token);

        String android_id = Settings.Secure.getString(context.getContentResolver(),
                Settings.Secure.ANDROID_ID);
        int osTypeCode = Constants.OST_ANDROID;
        JSONObject parms = new JSONObject();
        try {
            parms.put("deviceID", android_id);
            parms.put("OSTypeCode", osTypeCode);
            parms.put("token", token);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        Transporter oTransporter = new Transporter(Constants.TransporterSubjectUSER,
                Constants.REGISTER_NOTIFICATION_TOKEN, "", parms, userGUID, sessionGUID);
        oTransporter.makeAPICall(getApplicationContext(), "");

        //on registration complete. creating intent with success
        registrationComplete = new Intent(REGISTRATION_SUCCESS);

        //Putting the token to the intent
        registrationComplete.putExtra("token", token);
    } catch (Exception e) {
        //If any error occurred
        Log.w("GCMRegIntentService", "Registration error");
        registrationComplete = new Intent(REGISTRATION_ERROR);
    }

    //Sending the broadcast that registration is completed
    LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);

}
}

听众服务:

   public class GCMPushReceiverService extends GcmListenerService {

private static final String TAG = "GCMPushReceiverService";

//with every new message
@Override
public void onMessageReceived(String from, Bundle data){
    System.out.println("WE'VE RECIEVED A MESSAGE");
    String message = data.getString("message");
    Log.d(TAG, "From: " + from);
    Log.d(TAG, "Message: " + message);
    sendNotification(message);
}

private void sendNotification(String message) {
    Intent intent = new Intent(this, LogInPage.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    int requestCode = 0;
    PendingIntent pendingIntent =
            PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
    Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this);
    noBuilder.setContentTitle("title");
    noBuilder.setContentText(message);
    noBuilder.setContentIntent(pendingIntent);
    noBuilder.setSound(sound);
    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(0, noBuilder.build()); //0 = ID of notification
}
 }

最后,由于它可能有一些帮助,信息传输/网络类:

public class Transporter {
private String subject;
private String request;
private String key;
private Date lastUpdateDate;
private boolean forceLoad = false;
private Date requestDate;
private Date responseDate;
private int status;
private String statusMsg = "";
private String tempKey = "";

private JSONObject additionalInfo = null;
private JSONObject parameters;

public static String sessionGUID = "";
public static String userGUID = "";

public static String SERVER = Constants.qa_api;

//transporter object to interact with the server, containing information about the request
//made by the user
public  Transporter(String pSubject, String pRequest, String  pKey,
                               JSONObject parms, String userGUID, String sessionGUID)
{
    subject = pSubject;
    request = pRequest;
    key = pKey;
    parameters = parms;
    setUserGUID(userGUID);
    setSessionGUID(sessionGUID);
}

//implements an API call for a given transporter, takes 2 arguments:
//the application context (call getApplicationContext() whenever it's called)
//and a String that represents the field that we are trying to update (if there is one)
//i.e. if we are calling getUserFromSession(), we want the user guid so jsonID = "userGUID"
public void makeAPICall(final Context context, final String jsonID) {

    RequestQueue mRequestQueue =
            RequestQueueSingleton.getInstance(context).getRequestQueue();
    String targetURL = getServerURL() + "/Transporter.aspx";

    StringRequest postRequest = new StringRequest(Request.Method.POST, targetURL,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    String parseXML= parseXML(response);
                    System.out.println("response: " + parseXML);

                    JSONObject lastResponseContent = null;
                    try {
                        lastResponseContent = new JSONObject(parseXML);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    try {
                        if (lastResponseContent != null && !jsonID.equals("")) {
                            String info = lastResponseContent.getString(jsonID);
                            if (jsonID.equals("userGUID")) {
                                userGUID = info;
                                RequestQueueSingleton.getInstance(context).setUserGUID(userGUID);
                            }
                        }
                        //put other things in here to pull whatever info
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    }) {
        @Override
        public byte[] getBody() throws AuthFailureError {
            String body = getXML(subject,
                    request, "",
                    sessionGUID, userGUID,  null, parameters);
            return body.getBytes();
        }
    };
    postRequest.setTag("POST");
    mRequestQueue.add(postRequest);
}

2 个答案:

答案 0 :(得分:0)

您需要将帖子发送到网址“https://android.googleapis.com/gcm/send”:

private void sendGCM() {

    StringRequest strReq = new StringRequest(Request.Method.POST,
            "https://android.googleapis.com/gcm/send", new Response.Listener<String>() {

        @Override
        public void onResponse(String response) {

        }
    }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            NetworkResponse networkResponse = error.networkResponse;
            Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse);
            Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }) {

        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<>();
            params.put("data", "message that you send");
            params.put("to", "token gcm");

            Log.e(TAG, "params: " + params.toString());
            return params;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String,String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            headers.put("Authorization", "key="google key");
            return headers;
        }

    };
}

答案 1 :(得分:0)

所以Volley调用是非顺序的,所以第一次调用(获取userGUID)在第二次调用之前没有返回(注册通知),所以当令牌注册“成功”时,没有相应的用户信息,因此它不知道如何/在何处发送推送通知。为了解决这个问题,我在makeAPICall类中创建了一个特例,它创建了另一个StringRequest,它首先基本上执行了正常的getUserFromSession,然后使用新的userGUID信息以递归方式调用MakeAPICall。为了避免无限循环,我使用了if else语句:(如果userGUID == null || userGUID.equals(“”))然后我做了递归调用,所以当第一次调用返回条件总是为false时它会只进行一次递归调用。这个答案可能有点夸张,但关键的用处是使用onResponse为顺序请求进行另一次Volley调用。请参阅:Volley - serial requests instead of parallel?Does Volley library handles all the request sequentially