如何将 C2DM 消息显示为推送通知(在 GCMIntentService 类的 onMessage() 函数中接收)

Posted

技术标签:

【中文标题】如何将 C2DM 消息显示为推送通知(在 GCMIntentService 类的 onMessage() 函数中接收)【英文标题】:How to display C2DM message as a push notification (recived on onMessage() function of GCMIntentService class) 【发布时间】:2015-02-19 06:14:03 【问题描述】:

大家好,我根据提供的教程在我的应用程序中实现了 C@DM http://avilyne.com/?p=267.It 有效,但我的问题是我只在我的活动中收到设置在文本视图上的消息。但即使应用程序不工作,我也希望它在应用程序之外,当我点击它时,我想从中提取一个数字并且想要启动一个特定的活动(不是家庭活动),然后在按下它时回到家庭活动。

我的 GCMIntentService 类是这样的(我在项目中添加了 gcm.jar)

package com.lejin.myapp;

/**

 */

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.google.android.gcm.GCMBaseIntentService;

public class GCMIntentService extends GCMBaseIntentService 

    private static final String PROJECT_ID = "76973814590";

    private static final String TAG = "GCMIntentService";

    public GCMIntentService()
    
        super(PROJECT_ID);
        Log.d(TAG, "GCMIntentService init");
    


    @Override
    protected void onError(Context ctx, String sError) 
        // TODO Auto-generated method stub
        Log.d(TAG, "Error: " + sError);

    

    @Override
    protected void onMessage(Context ctx, Intent intent) 

        Log.d(TAG, "Message Received");

        String message = intent.getStringExtra("message");

        sendGCMIntent(ctx, message);

    


    private void sendGCMIntent(Context ctx, String message) 

        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction("GCM_RECEIVED_ACTION");

        broadcastIntent.putExtra("gcm", message);

        ctx.sendBroadcast(broadcastIntent);

    


    @Override
    protected void onRegistered(Context ctx, String regId) 
        // TODO Auto-generated method stub
        // send regId to your server
        Log.d(TAG, regId);

    

    @Override
    protected void onUnregistered(Context ctx, String regId) 
        // TODO Auto-generated method stub
        // send notification to your server to remove that regId

    

我在我的活动中使用广播接收器收到了该消息

 package com.lejin.myapp;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gcm.GCMRegistrar;


public class MainActivity extends Activity 

    // This is the project id generated from the Google console when
    // you defined a Google APIs project.
    private static final String PROJECT_ID = "76973814590";

    // This tag is used in Log.x() calls
    private static final String TAG = "MainActivity";

    // This string will hold the lengthy registration id that comes
    // from GCMRegistrar.register()
    private String regId = "";

    // These strings are hopefully self-explanatory
    private String registrationStatus = "Not yet registered";
    private String broadcastMessage = "No broadcast message";

    // This intent filter will be set to filter on the string "GCM_RECEIVED_ACTION"
    IntentFilter gcmFilter;

    // textviews used to show the status of our app's registration, and the latest
    // broadcast message.
    TextView tvRegStatusResult;
    TextView tvBroadcastMessage;

    // This broadcastreceiver instance will receive messages broadcast
    // with the action "GCM_RECEIVED_ACTION" via the gcmFilter

    // A BroadcastReceiver must override the onReceive() event.
    private BroadcastReceiver gcmReceiver = new BroadcastReceiver() 

        @Override
        public void onReceive(Context context, Intent intent) 

            broadcastMessage = intent.getExtras().getString("gcm");

            if (broadcastMessage != null) 
                // display our received message
                tvBroadcastMessage.setText(broadcastMessage);
            
        
    ;

    // Reminder that the onCreate() method is not just called when an app is first opened,
    // but, among other occasions, is called when the device changes orientation.

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvBroadcastMessage = (TextView) findViewById(R.id.tv_message);
        tvRegStatusResult = (TextView) findViewById(R.id.tv_reg_status_result);

        // Create our IntentFilter, which will be used in conjunction with a
        // broadcast receiver.
        gcmFilter = new IntentFilter();
        gcmFilter.addAction("GCM_RECEIVED_ACTION");

        registerClient();
    

    // This registerClient() method checks the current device, checks the
    // manifest for the appropriate rights, and then retrieves a registration id
    // from the GCM cloud.  If there is no registration id, GCMRegistrar will
    // register this device for the specified project, which will return a
    // registration id.
    public void registerClient() 

        try 
            // Check that the device supports GCM (should be in a try / catch)
            GCMRegistrar.checkDevice(this);

            // Check the manifest to be sure this app has all the required
            // permissions.
            GCMRegistrar.checkManifest(this);

            // Get the existing registration id, if it exists.
            regId = GCMRegistrar.getRegistrationId(this);

            if (regId.equals("")) 

                registrationStatus = "Registering...";

                tvRegStatusResult.setText(registrationStatus);

                // register this device for this project
                GCMRegistrar.register(this, PROJECT_ID);
                regId = GCMRegistrar.getRegistrationId(this);
                Toast.makeText(getApplicationContext(),regId,Toast.LENGTH_LONG).show();
                registrationStatus = "Registration Acquired";

                // This is actually a dummy function.  At this point, one
                // would send the registration id, and other identifying
                // information to your server, which should save the id
                // for use when broadc
                // asting messages.
                sendRegistrationToServer();

             else 

                registrationStatus = "Already registered";

            


         catch (Exception e) 

            e.printStackTrace();
            registrationStatus = e.getMessage();

        

        Log.d(TAG, registrationStatus);
        tvRegStatusResult.setText(registrationStatus);

        // This is part of our CHEAT.  For this demo, you'll need to
        // capture this registration id so it can be used in our demo web
        // service.
        Toast.makeText(getApplicationContext(),regId,Toast.LENGTH_LONG).show();
        Log.d(TAG, regId);

    

    private void sendRegistrationToServer() 
        // This is an empty placeholder for an asynchronous task to post the
        // registration
        // id and any other identifying information to your server.
    

    // If the user changes the orientation of his phone, the current activity
    // is destroyed, and then re-created.  This means that our broadcast message
    // will get wiped out during re-orientation.
    // So, we save the broadcastmessage during an onSaveInstanceState()
    // event, which is called prior to the destruction of the activity.

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) 
            return true;
        

        return super.onOptionsItemSelected(item);
    

    // If the user changes the orientation of his phone, the current activity
    // is destroyed, and then re-created.  This means that our broadcast message
    // will get wiped out during re-orientation.
    // So, we save the broadcastmessage during an onSaveInstanceState()
    // event, which is called prior to the destruction of the activity.
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) 

        super.onSaveInstanceState(savedInstanceState);

        savedInstanceState.putString("BroadcastMessage", broadcastMessage);

    

    // When an activity is re-created, the os generates an onRestoreInstanceState()
    // event, passing it a bundle that contains any values that you may have put
    // in during onSaveInstanceState()
    // We can use this mechanism to re-display our last broadcast message.

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) 

        super.onRestoreInstanceState(savedInstanceState);

        broadcastMessage = savedInstanceState.getString("BroadcastMessage");
        tvBroadcastMessage.setText(broadcastMessage);

    

    // If our activity is paused, it is important to UN-register any
    // broadcast receivers.
    @Override
    protected void onPause() 

        unregisterReceiver(gcmReceiver);
        super.onPause();
    

    // When an activity is resumed, be sure to register any
    // broadcast receivers with the appropriate intent
    @Override
    protected void onResume() 
        super.onResume();
        registerReceiver(gcmReceiver, gcmFilter);

    

    // There are no menus for this demo app.  This is just
    // boilerplate code.
    // NOTE the call to GCMRegistrar.onDestroy()
    @Override
    public void onDestroy() 

        GCMRegistrar.onDestroy(this);

        super.onDestroy();
    

我想将此消息显示为在什么应用程序或其他常见应用程序中显示的普通推送通知,并且需要基于此打开特定活动(不是家庭活动)

【问题讨论】:

【参考方案1】:

您需要做的是,修改您的onMessage 函数以便为您的应用创建通知(推送通知与应用通知是不同的概念),而不是调用sendGCMIntent

来自here,您应该执行以下操作:

NotificationCompat.Builder mBuilder =
    new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("My notification")
    .setContentText("Hello World!");
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, TheActivityYouWantToOpen.class);

// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MainActivity.class); //to allow you to use back button
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
    stackBuilder.getPendingIntent(
        0,
        PendingIntent.FLAG_UPDATE_CURRENT
    );
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// my_notification_idallows you to update the notification later on.
mNotificationManager.notify(my_notification_id, mBuilder.build());

通知 id 只是一个整数,您可以使用它来更新现有通知。

希望对你有帮助

【讨论】:

嗨 zozelfelfo,这很好用,谢谢。但是我的推送消息很大,它只显示一行,所以它可以在通知窗口中显示完整的消息。 在我发布的链接中,它还谈到了扩展通知以及如何处理兼容性(它们仅适用于 android 4.1+)

以上是关于如何将 C2DM 消息显示为推送通知(在 GCMIntentService 类的 onMessage() 函数中接收)的主要内容,如果未能解决你的问题,请参考以下文章

c2dm android推送通知每天广播量

适用于 Android 的位置感知推送通知

如何向 C2DM(Android 推送服务)发送批量请求?

android c2dm中的推送通知

如何捕捉 C2DM 通知来电话?

收到 C2DM 推送通知时更改活动行为