0

我正在处理我的应用程序中的一些通知。我正在使用谷歌云消息传递。我的应用程序在这种模式下工作:我有一个实现 GCM 的小应用程序,这个小应用程序只运行其他应用程序。但是我想当我有这个应用程序的一些新更新时,在顶部栏中显示新信息已添加到网络服务的通知。这是我的代码:

public class MainActivity extends Activity {

    private final static int APPLICATION_ID = 5;
    private boolean isInstalled = false;
    PackageManager pm;
    final String appName = "com.example.test";
    // Replace the xxx with the project id generated from the Google console when
    // you defined a Google APIs project.
    private static final String PROJECT_ID = "410016639123";

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



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActivityManager aManager = (ActivityManager) this.getSystemService( ACTIVITY_SERVICE );
        List<RunningAppProcessInfo> processInfo = aManager.getRunningAppProcesses();

        for(int i = 0; i < processInfo.size(); i++){
            if(processInfo.get(i).processName.equals(appName)) {
                aManager.restartPackage("com.example.test.MainActivity"); 
            }
        } 

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

        registerClient();
        if(!checkInstalled()){

            try {
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id="+appName)));
            } catch (android.content.ActivityNotFoundException anfe) {
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id="+appName)));
            }

        }else{
            Log.v("app", "App is installed");
        }

        Intent intent = pm.getLaunchIntentForPackage(appName);
        CopyAssets();
        if(intent != null) {
            intent.putExtra("application_id", APPLICATION_ID); 
            intent.putExtra("ApiKey", regId);
            //getApplicationContext().startActivity(intent);
            startActivityForResult(intent, Intent.FLAG_ACTIVITY_NO_HISTORY);
            finish();
        }
    }
    public void registerClient() {

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

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

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

            if (regId.equals("")) {

                registrationStatus = "Registering...";


                // register this device for this project
                GCMRegistrar.register(this, PROJECT_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";

            }


        } catch (Exception e) {

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

        }

        Log.d(TAG, 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.
        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.
    }
    private static boolean checkFsWritable() {
        // Create a temporary file to see whether a volume is really writeable.
        // It's important not to put it in the root directory which may have a
        // limit on the number of files.
        String directoryName = Environment.getExternalStorageDirectory().toString() + "/DCIM";
        File directory = new File(directoryName);
        if (!directory.isDirectory()) {
            if (!directory.mkdirs()) {
                return false;
            }
        }
        return directory.canWrite();
    }

    /**
     * copies all assets (icons, terms document) to the sdcard if they are missing. 
     */


    private void copyFile(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while((read = in.read(buffer)) != -1){
          out.write(buffer, 0, read);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    private boolean checkInstalled(){
        try
        {
             pm.getPackageInfo(appName, PackageManager.GET_ACTIVITIES);
             isInstalled = true;
        }
        catch (PackageManager.NameNotFoundException e)
        {
             isInstalled = false;
        }
        return isInstalled;
    }
    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");

    }

    // 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(getApplicationContext());

        super.onDestroy();
    }

}

和 GCM 类:

public class GCMIntentService extends GCMBaseIntentService {
private static final int NOTIFY_ME_ID=1;
  private int count=0;
  private NotificationManager mgr=null;
private static final String PROJECT_ID = "410016639568";

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");
    generateNotification(ctx, intent.getStringExtra("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

}
private static void generateNotification(Context context, String message) {
    long when = System.currentTimeMillis();
    NotificationManager notificationManager = (NotificationManager) context
            .getSystemService(Context.NOTIFICATION_SERVICE);
    Notification notification = new Notification(R.drawable.ic_launcher,
            message, when);
    String title = context.getString(R.string.app_name);
    Intent notificationIntent = new Intent(context,
            MainActivity.class);
    // set intent so it does not start a new activity
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
            | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent intent = PendingIntent.getActivity(context, 0,
            notificationIntent, 0);
    notification.setLatestEventInfo(context, title, message, intent);
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notificationManager.notify(0, notification);
}

}

我收到消息:

12-21 08:20:18.709: V/app(4682): App is installed
12-21 08:20:18.919: E/tag(4682): Files/terms.pdf
12-21 08:34:29.239: V/GCMBroadcastReceiver(4682): onReceive: com.google.android.c2dm.intent.RECEIVE
12-21 08:34:29.239: V/GCMBroadcastReceiver(4682): GCM IntentService class: pl.spot.rudolfmuller.GCMIntentService
12-21 08:34:29.244: V/GCMBaseIntentService(4682): Acquiring wakelock
12-21 08:34:29.264: V/GCMBaseIntentService(4682): Intent service name: GCMIntentService-410016639568-1
12-21 08:34:29.264: D/GCMIntentService(4682): GCMIntentService init
12-21 08:34:29.269: D/GCMIntentService(4682): Message Received
12-21 08:34:29.269: V/GCMBaseIntentService(4682): Releasing wakelock
12-21 08:34:45.324: V/GCMBroadcastReceiver(4682): onReceive: com.google.android.c2dm.intent.RECEIVE
12-21 08:34:45.324: V/GCMBroadcastReceiver(4682): GCM IntentService class: pl.spot.rudolfmuller.GCMIntentService
12-21 08:34:45.324: V/GCMBaseIntentService(4682): Acquiring wakelock
12-21 08:34:45.339: V/GCMBaseIntentService(4682): Intent service name: GCMIntentService-410016639568-2
12-21 08:34:45.339: D/GCMIntentService(4682): GCMIntentService init
12-21 08:34:45.344: D/GCMIntentService(4682): Message Received
12-21 08:34:45.344: V/GCMBaseIntentService(4682): Releasing wakelock

但我的顶部栏中没有任何信息。我怎么能这样做?应用程序必须正在运行才能看到此通知?即使应用程序没有运行,我也想获得通知。

编辑:我编辑了我的代码,但仍然没有收到消息。我收到收到消息的日志,但之后是释放唤醒锁并且我的消息没有出现。怎么了?

4

1 回答 1

2

BroadcastReceiver 上的 Android 文档:

注意:如果在 Activity.onResume() 实现中注册接收器,则应在 Activity.onPause() 中取消注册。(暂停时您不会收到意图,这将减少不必要的系统开销)。

因此,当您的应用程序未运行或暂停时,将不会生成通知。然而; 如果您在类的onMessage方法中生成通知,GCMIntentService即使您的应用程序未运行,它也会生成,因为该类是service在您的应用程序后台运行的。

如果你制作一个单独的 BroadcastReceiver 类,你可以在你AndroidManifest.xml的下面声明它:

<receiver android:name="yourpackage.yourclassname" >
    <intent-filter>
        <action android:name="GCM_RECEIVED_ACTION" />
    </intent-filter>
</receiver>
于 2012-12-21T08:20:38.297 回答