简体   繁体   中英

Push Notification not Received in android

I am new to push notifications and I'm trying to send a push notification to a particular device which has already been registered to GCM service. I implemented my app according to this example and modified accordingly in my program. However, I am not able to receive push notifications on the device.

Here is my code:

package com.markattendence.activites;

import static com.markattendence.activites.CommonUtilities.DISPLAY_MESSAGE_ACTION;
import static com.markattendence.activites.CommonUtilities.EXTRA_MESSAGE;
import static com.markattendence.activites.CommonUtilities.SENDER_ID;

import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gcm.GCMRegistrar;
import com.markattendence.activites.MainActivity.YourAsyncTaskLogin;
import com.markattendence.markattendence.R;

public class NotificationActivity extends Activity {
// label to display gcm messages
TextView lblMessage;

// Asyntask
AsyncTask<Void, Void, Void> mRegisterTask;

// Alert dialog manager
AlertDialogManager alert = new AlertDialogManager();

// Connection detector
ConnectionDetector cd;

private String userFName;

private String latitude;

private String longitude;
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_FNAME = "fname";
private static String KEY_EMAIL = "email";
private static String KEY_LNAME = "lname";

UserFunctions userFunction;
private JSONObject json;

public static String name;
public static String email;

SharedPreferences prefs;
public static final String MyPREFERENCES = "MyPrefs";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_notification);

    cd = new ConnectionDetector(getApplicationContext());
    prefs = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);

    if (prefs.contains("message")) {
        lblMessage.setText(prefs.getString("message", ""));

    }

    // Check if Internet present
    if (!cd.isConnectingToInternet()) {
        // Internet Connection is not present
        alert.showAlertDialog(NotificationActivity.this,
                "Internet Connection Error",
                "Please connect to working Internet connection", false);
        // stop executing code by return
        return;
    }

    // Getting name, email from intent
    Intent i = getIntent();

    name = i.getStringExtra("uFName");
    userFName = i.getStringExtra("uFName");
    email = i.getStringExtra("email");
    latitude = i.getStringExtra("latitude");
    longitude = i.getStringExtra("longitude");

    // Make sure the device has the proper dependencies.
    GCMRegistrar.checkDevice(this);

    // Make sure the manifest was properly set - comment out this line
    // while developing the app, then uncomment it when it's ready.
    GCMRegistrar.checkManifest(this);

    lblMessage = (TextView) findViewById(R.id.lblMessage);

    registerReceiver(mHandleMessageReceiver, new IntentFilter(
            DISPLAY_MESSAGE_ACTION));

    // Get GCM registration id
    final String regId = GCMRegistrar.getRegistrationId(this);

    // Check if regid already presents
    if (regId.equals("")) {
        // Registration is not present, register now with GCM
        GCMRegistrar.register(this, SENDER_ID);
    } else {
        // Device is already registered on GCM
        if (GCMRegistrar.isRegisteredOnServer(this)) {
            // Skips registration.
            Toast.makeText(getApplicationContext(),
                    "Already registered with GCM", Toast.LENGTH_LONG)
                    .show();
        } else {
            // Try to register again, but not in the UI thread.
            // It's also necessary to cancel the thread onDestroy(),
            // hence the use of AsyncTask instead of a raw thread.
            final Context context = this;
            mRegisterTask = new AsyncTask<Void, Void, Void>() {

                @Override
                protected Void doInBackground(Void... params) {
                    // Register on our server
                    // On server creates a new user
                    ServerUtilities.register(context, name, email, regId);
                    return null;
                }

                @Override
                protected void onPostExecute(Void result) {
                    mRegisterTask = null;
                }

            };
            mRegisterTask.execute(null, null, null);
        }
    }
    if(name != null){
    userFunction = new UserFunctions();
    new YourAsyncTaskLogin().execute();
    }
}

/**
 * Receiving push messages
 * */
private final WakefulBroadcastReceiver mHandleMessageReceiver = new WakefulBroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent 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);

        String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
        // Waking up mobile if it is sleeping
        WakeLocker.acquire(getApplicationContext());

        /**
         * Take appropriate action on this message depending upon your app
         * requirement For now i am just displaying it on the screen
         * */

        // Showing received message
        lblMessage.append(newMessage + "\n");
        Toast.makeText(getApplicationContext(),
                "New Message: asd" + newMessage, Toast.LENGTH_LONG).show();

        prefs = context.getSharedPreferences(MyPREFERENCES,
                Context.MODE_PRIVATE);
        Editor editor = prefs.edit();
        editor.putString("message", lblMessage.getText().toString());
        editor.commit();
        // Releasing wake lock
        WakeLocker.release();
    }
};

@Override
protected void onDestroy() {
    if (mRegisterTask != null) {
        mRegisterTask.cancel(true);
    }
    try {
        unregisterReceiver(mHandleMessageReceiver);
        GCMRegistrar.onDestroy(this);
    } catch (Exception e) {
        Log.e("UnRegister Receiver Error", "> " + e.getMessage());
    }
    super.onDestroy();
}

class YourAsyncTaskLogin extends AsyncTask<Void, Void, Void> {

    private ProgressDialog _ProgressDialog;
    private String userId;

    @Override
    protected void onPreExecute() {
        // show your dialog here

        _ProgressDialog = ProgressDialog.show(NotificationActivity.this,
                "", "Loading", true);

    }

    @Override
    protected Void doInBackground(Void... params) {

        try {

            json = userFunction.sendMessage(userFName,
                    " has marked attendence of ", "CheckIN", latitude,
                    longitude);
            /*
             * HttpClient Client = new DefaultHttpClient(); String
             * SetServerString = "";
             * 
             * // Create Request to server and get response
             * 
             * HttpGet httpget = new HttpGet(
             * "http://wibman.com/pnt/send_message.php?message=" + name +
             * "checked in&Latitude=" + latitude + "&Longitude=" +
             * longitude); ResponseHandler<String> responseHandler = new
             * BasicResponseHandler(); SetServerString =
             * Client.execute(httpget, responseHandler);
             */

            // Show response on activity

            // content.setText(SetServerString);
        } catch (Exception ex) {
            ex.printStackTrace();
            // content.setText("Fail!");
        }
        return null;
    }

    protected void onPostExecute(Void result) {

        try {
            Log.e("aaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    json.getString(KEY_SUCCESS));
            if (json.getString(KEY_SUCCESS) != null) {
                // loginErrorMsg.setText("");
                String res = json.getString(KEY_SUCCESS);

                if (Integer.parseInt(res) == 1) {
                    /*userId = json.getString(KEY_UID);
                    userFName = json.getString(KEY_FNAME);

                    userFName.replace("\"", "");

                    userId.replace("\"", "");

                    Log.e("uid=aaa", userId);
                    Log.e("nameuser", userFName);*/

                    Intent dashboard = new Intent(getApplicationContext(),
                            MainActivity.class);

                    // Close all views before launching
                    // Dashboard
                    startActivity(dashboard);

                    // Close Login Screen
                    finish();

                } else {
                    // Error in login
                    // loginErrorMsg.setText("Incorrect username/password");

                    _ProgressDialog.cancel();

                    alert.showAlertDialog(NotificationActivity.this,
                            "Attendence Failed..",
                            "Mark Attendence Failed.", false);
                    // loginStatusTxtView.setText("Incorrect username/password");
                }

            } else {
                // Error in login
                // loginErrorMsg.setText("Incorrect username/password");

                _ProgressDialog.cancel();

                alert.showAlertDialog(NotificationActivity.this,
                        "Attendence Failed..", "Mark Attendence Failed.",
                        false);
                // loginStatusTxtView.setText("Incorrect username/password");
            }
        } catch (JSONException e) {
            e.printStackTrace();
            Log.e("error", e.getMessage());
        }

        _ProgressDialog.dismiss();

    }
}

 }

Manifest.xml

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

<uses-sdk
    android:minSdkVersion="10"
    android:targetSdkVersion="18" />

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- 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.markattendence.markattendence.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.markattendence.markattendence.permission.C2D_MESSAGE" />
<uses-permission android:name="com.markattendence.activites.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" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature
    android:name="android.hardware.camera.front"
    android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
    android:allowBackup="true"
    android:icon="@drawable/mmes_logo"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.markattendence.markattendence.MainActivity"
        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.markattendence.markattendence.MarkAttendenceActivity" >
    </activity>
    <activity android:name="com.markattendence.markattendence.NotificationActivity" >
    </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.markattendence.markattendence" />
        </intent-filter>
    </receiver>

    <service android:name="com.markattendence.markattendence.GCMIntentService" />
</application>

I am having a problem in receiving the notification. Server side code is working correctly.

My log cat says:

{"multicast_id":5884981605957538237,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1393495991926450%978fee92f9fd7ecd"}]}

The major problem is that, if device has the example app it get notification in that application rather than my customized application. And if I remove that application i don't get any notification. So i am confused that notification has to be received in my app rather than that of androidhive application but push notification is displayed in androidhive application. Please help me to solve this issue. Thanks in advance.

You have some errors in your manifest that only cause problems on old Android versions :

Your packagge name is com.markattendence.markattendence .

Therefore you should change this :

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

To this:

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

And this:

<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.markattendence.activites" />
    </intent-filter>
</receiver>

To this:

<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.markattendence.markattendence" />
    </intent-filter>
</receiver>

For sending the push to a specific device. First of all you need to pick the token from the FCM :

String token = FirebaseInstanceId.getInstance().getToken();

Then this unique token is used to send the push request from server post request. Please find the headers of the post request along with required structure of the body.

Headers

Content-Type     'application/json'
Authorization    'key=(server-key)'

Note: Not other than these values are allowed in headers. And here the 'server-key' is your browser key provide from FCM console.

Body For Push Request

{
  "data": {
    "NotificationDetailsID": 1131,
    "MessageGroup": "HR",
    "Message": "this is notification"
  },
  "to": "firebase-token-of-androidDevice"
}

This is the server side implementation and this will definitely work. As we have tested at our end. You will receive the push while the app is even closed.

IF you could send a notification and configure a GCM so the problem should be with network. Try to look if your ports are not blocked for notification (I had similar problem - I could send but not receive notification after unlocking ports I received notifications).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM