簡體   English   中英

在Android中未收到推送通知

[英]Push Notification not Received in android

我是推送通知的新手,我正嘗試將推送通知發送到已注冊到GCM服務的特定設備。 我根據此示例實現了我的應用,並在程序中進行了相應的修改。 但是,我無法在設備上接收推送通知。

這是我的代碼:

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>

我在收到通知時遇到問題。 服務器端代碼正常工作。

我的原木貓說:

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

主要的問題是,如果設備具有示例應用程序,它將在該應用程序而不是我的自定義應用程序中獲得通知。 如果我刪除該應用程序,則不會收到任何通知。 所以我很困惑,通知必須在我的應用程序中接收,而不是在androidhive應用程序中接收,但是推送通知顯示在androidhive應用程序中。 請幫我解決這個問題。 提前致謝。

您的清單中存在一些錯誤,這些錯誤只會在舊版Android上引起問題:

您的包裝名稱為com.markattendence.markattendence

因此,您應該更改此設置:

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

對此:

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

和這個:

<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>

對此:

<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>

用於將推送發送到特定設備。 首先,您需要從FCM中選擇令牌:

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

然后,此唯一令牌用於從服務器發布請求發送推送請求。 請找到發布請求的標題以及所需的正文結構。

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

注意:標頭中只能使用這些值。 在這里,“服務器密鑰”是您從FCM控制台提供的瀏覽器密鑰。

推送請求主體

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

這是服務器端的實現,肯定可以正常工作。 正如我們在最后測試的那樣。 該應用程序甚至關閉時,您也會收到推送。

如果您可以發送通知並配置GCM,則問題應該出在網絡上。 嘗試查看您的端口是否未被阻止進行通知(我有類似的問題-在解鎖收到通知的端口后,我可以發送但無法接收通知)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM