我正在处理我的应用程序中的一些通知。我正在使用谷歌云消息传递。我的应用程序在这种模式下工作:我有一个实现 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
但我的顶部栏中没有任何信息。我怎么能这样做?应用程序必须正在运行才能看到此通知?即使应用程序没有运行,我也想获得通知。
编辑:我编辑了我的代码,但仍然没有收到消息。我收到收到消息的日志,但之后是释放唤醒锁并且我的消息没有出现。怎么了?