I am working at some notifications in my app. I am using google cloud messaging. My app working in this schema: I have a small app which has implemented GCM and this small app only run other app. But I want to when I have some new update for this app, in top bar show notification that new info is added on web service. This is my code:
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();
}
}
and GCM class:
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);
}
}
I get message:
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
but I don’tget any info in my top bar. How I can do that? Application must be running to see this notyfications? I want to get notyfications even app is not running.
EDIT: I edited my code but still don’t get message. I get log that Message Received, but after that is Releasing wakelock and My message doesn’t appear. What is wrong?
The Android documentation on BroadcastReceiver:
So when your app is not running or is paused, the notification won’t be generated. However; if you generate the notification in the
onMessagemethod of yourGCMIntentServiceclass it will be generated even when your app is not running because that class is aservicewhich runs in the background of your app.If you make a seperate BroadcastReceiver class you can declare it in your
AndroidManifest.xmlas following: