简体   繁体   English

在Android中未收到推送通知

[英]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. 我是推送通知的新手,我正尝试将推送通知发送到已注册到GCM服务的特定设备。 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 的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. 所以我很困惑,通知必须在我的应用程序中接收,而不是在androidhive应用程序中接收,但是推送通知显示在androidhive应用程序中。 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 : 您的清单中存在一些错误,这些错误只会在旧版Android上引起问题:

Your packagge name is com.markattendence.markattendence . 您的包装名称为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 : 首先,您需要从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. 在这里,“服务器密钥”是您从FCM控制台提供的浏览器密钥。

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. 如果您可以发送通知并配置GCM,则问题应该出在网络上。 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). 尝试查看您的端口是否未被阻止进行通知(我有类似的问题-在解锁收到通知的端口后,我可以发送但无法接收通知)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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