2013-05-06 155 views
0

這是我的客戶端代碼。當我在應用程序內部時,消息和通知運行良好,但當我離開應用程序時,應用程序內的消息不顯示,但通知有效。什麼是錯誤?先謝謝了當我離開應用程序時沒有收到GCM消息

package com.example.androidgcmclient; 

import android.os.Bundle; 
import android.app.Activity; 
import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
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.view.Menu; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.google.android.gcm.GCMRegistrar; 
import android.app.Activity; 
import android.view.Menu; 

public class MainActivity extends Activity { 

    // Replace the xxx with the project id generated from the Google console when 
    // you defined a Google APIs project. 
    private static final String SENDER_ID = "my_sender_id"; 

    // 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); 
       Log.d(TAG, "message received"); 


      } 
     } 
    }; 

    // 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 
    public 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, SENDER_ID); 
       regId = GCMRegistrar.getRegistrationId(this); 

       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 broadcasting messages. 
       sendRegistrationToServer(); 

      } else { 

       registrationStatus = "Already registered "+GCMRegistrar.getRegistrationId(this); 

      /*  GCMRegistrar.unregister(this); regId=""; 
       Toast.makeText(getApplicationContext(), "Unregistered", Toast.LENGTH_LONG).show();*/ 

      } 


     } catch (Exception e) { 

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

     } 

     Log.d(TAG, registrationStatus); 
     tvRegStatusResult.setText(registrationStatus); 
     Toast.makeText(getApplicationContext(), "reg acq "+regId, Toast.LENGTH_LONG).show(); 

     // 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. 
     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 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. 
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.activity_main, menu); 
     return true; 
    } 

    // NOTE the call to GCMRegistrar.onDestroy() 
    @Override 
    public void onDestroy() { 

     GCMRegistrar.onDestroy(this); 

     super.onDestroy(); 
    } 

} 

而且GCMIntentService類

package com.example.androidgcmclient; 

import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.Toast; 
import android.support.v4.app.NotificationCompat.Builder; 
import com.google.android.gcm.GCMBaseIntentService; 

public class GCMIntentService extends GCMBaseIntentService { 

    private static final String SENDER_ID = "my_sender_id"; 

    private static final String TAG = "GCMIntentService"; 

    public GCMIntentService() 
    { 
     super(SENDER_ID); 
     Log.d(TAG, "GCMIntentService init"); 
    } 


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

     Log.d(getClass().getSimpleName(), "onError: " + sError); 

    } 

    @Override 
    protected void onMessage(Context context, Intent intent) { 

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

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

     NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
     android.app.Notification notification = new android.app.Notification(
       R.drawable.ic_launcher, message, 
       System.currentTimeMillis()); 

     Intent notificationIntent = new Intent(context, MainActivity.class); 
     PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, 
       notificationIntent, 0); 

     notification.setLatestEventInfo(context, 
       "Webexpenses Claim Report", message, pendingIntent); 
     notificationManager.notify(10001, notification); 


     sendGCMIntent(context, message); 

     Log.d(getClass().getSimpleName(), "Message Received"); 


    } 


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

     Log.d(getClass().getSimpleName(), "onRegistered: " + regId); 
     Toast.makeText(this, regId, Toast.LENGTH_LONG).show(); 

    } 

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

     Log.d(getClass().getSimpleName(), "onUnregistered: " + regId); 

    } 

    @Override 
    protected boolean onRecoverableError(Context ctxt, String errorMsg) { 
     Log.d(getClass().getSimpleName(), "onRecoverableError: " + errorMsg); 

     return(true); 
    } 

} 

的Android清單文件

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

    <uses-sdk 
     android:minSdkVersion="8" 
     android:targetSdkVersion="17" /> 

    <permission 
     android:name="com.example.androidgcmclient.permission.C2D_MESSAGE" 
     android:protectionLevel="signature" /> 

    <uses-permission android:name="com.example.androidgcmclient.permission.C2D_MESSAGE" /> 

    <!-- receives GCM messages --> 
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
    <!-- GCM connects to Google services --> 
    <uses-permission android:name="android.permission.INTERNET" /> 

    <!-- GCM requires a Google account --> 
    <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 

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

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

    <!-- wake the processor if a GCM message is received --> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name="com.example.androidgcmclient.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> 

     <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" > 
      <intent-filter> 
       <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
       <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
       <category android:name="com.example.androidgcmclient" /> 
      </intent-filter> 
     </receiver> 
     <service 
      android:name=".GCMIntentService"> 
     </service> 


    </application> 

</manifest> 
+0

你可以請張貼你的應用程序的清單文件? – 2013-05-07 08:11:45

+0

是啊,我已經貼 – Sakthimuthiah 2013-05-07 08:29:38

+1

看看[http://stackoverflow.com/questions/8077571/how-to-run-activity-in-background-in-android][1] [1 ]:http://stackoverflow.com/questions/8077571/how-to-run-activity-in-background-in-android – JimTim 2013-06-14 08:41:02

回答

1

你不應該有活動裏面的GCM代碼。聲明一個GCMIntentService,即使你的應用程序沒有運行,這也會被觸發。從那裏你可以發起你想要的任何活動。

​​

+0

我已經在應用程序中的GCM代碼。但是當我不在應用程序中時,消息並沒有進入應用程序。請幫忙。我用GCM代碼編輯我的問題 – Sakthimuthiah 2013-05-07 07:37:35

0

你需要的,如果你想讓它當你的應用程序不運行是入店來定義你的清單接收器。

<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" > 
    <intent-filter> 
     <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
     <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
     <category android:name="my_app_package" /> 
    </intent-filter> 
</receiver> 

您需要嚴格按照說明here

+0

我已經在我的應用程序中添加了所有這些東西。但是當我不在應用程序中時,消息不會顯示在應用程序中。幫我 – Sakthimuthiah 2013-05-07 07:38:43

相關問題