GCMBaseIntentService - Wakelock reference is null - java

I'm getting this error on GCM and sometime I receive the message but no notification was generated. Could anyone help me to identify what's the problem?
Here's my code (some business logic code was removed for simplicity):
GcmBroadcastReceiver:
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
GcmIntentService:
public class GcmIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
public GcmIntentService() {
super(ConstantManager.SENDER_ID);
}
/**
* Method called on device registered
**/
#Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
}
/**
* Method called on device un registred
* */
#Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
}
/**
* Method called on Receiving a new message
* */
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("message");
String type = intent.getExtras().getString("type");
int eventId = 0;
generateNotification(context, message,2,eventId);
}
/**
* Method called on receiving a deleted message
* */
#Override
protected void onDeletedMessages(Context context, int total) {
Log.i(TAG, "Received deleted messages notification");
// notifies user
generateNotification(context, "Deleted Message",0,0);
}
/**
* Method called on Error
* */
#Override
public void onError(Context context, String errorId) {
Log.i(TAG, "Received error: " + errorId);
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
// log message
Log.i(TAG, "Received recoverable error: " + errorId);
return super.onRecoverableError(context, errorId);
}
/**
* Issues a notification to inform the user that server has sent a message.
*/
#SuppressWarnings("deprecation")
private static void generateNotification(Context context, String message,int type,int referId) {
int icon = R.drawable.logo_v2;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Log.i(TAG, "Generating Notification");
String title = context.getString(R.string.app_name);
if(GeneralManager.sessionManager.isLoggedIn())
{
if(type==2)
{
Log.i(TAG, "Type 2");
Intent notificationIntent = new Intent(context, PendingEventDetailsActivity.class);
SharedPreferences pref = context.getSharedPreferences(SessionManager.PREF_NAME, SessionManager.PRIVATE_MODE);
String userId = pref.getString(SessionManager.KEY_USER_ID,null);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
notificationIntent.putExtra("eventId", String.valueOf(referId));
notificationIntent.putExtra("userId", userId);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
else
{
Log.i(TAG, "Other type");
Intent notificationIntent = new Intent(context, WelcomeActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
notificationIntent.putExtra("notification", "true");
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
}
}
}

I know this answer is ver late,but hope it can help someone else.
This problem can be solved by two Methods :
Method 1 :
This problem is encountered when WakeLock is released incorrectly i.e. When library tries to release WakeLock that holds nothing (internal lock counter becomes negative).To avoid this you can add following line of code(catching the exception if the WakeLock is not active) on WakeLocker.release(); :
synchronized (LOCK) {
// sanity check for null as this is a public method
if (WakeLock != null) {
Log.v(TAG, "Releasing wakelocker");
try {
WakeLocker.release();
} catch (Throwable th) {
// ignoring this exception, probably wakeLock was already released
}
} else {
// should never happen during normal workflow
Log.e(TAG, "Reference of WakeLock is null");
}
}
Method 2 :
This is more convenient way of solving the problem, u can use WakeLocker.isHeld(); on WakeLocker.release(); i.e.
if (WakeLocker.isHeld())
WakeLocker.release();
Hope it helps anyone.

Related

Notification gcm

public class GcmIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
private static final String TAG = "GcmIntentService";
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GcmIntentService() {
super("GcmIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
/*
* Filter messages based on message type. Since it is likely that GCM
* will be extended in the future with new message types, just ignore
* any message types you're not interested in, or that you don't
* recognize.
*/
if (GoogleCloudMessaging.
MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_DELETED.equals(messageType)) {
sendNotification("Deleted messages on server: " +
extras.toString());
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_MESSAGE.equals(messageType)) {
// This loop represents the service doing some work.
for (int i=0; i<5; i++) {
Log.i(TAG, "Working... " + (i+1)
+ "/5 # " + SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work # " + SystemClock.elapsedRealtime());
// Post notification of received message.
sendNotification(extras.getString("Notice"));
Log.i(TAG, "Received: " + extras.toString());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, Notification.class),PendingIntent.FLAG_UPDATE_CURRENT );
//PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),
//0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
// .setSmallIcon(R.drawable.ic_stat_gcm)
.setContentTitle("MobileHealth")
.setSmallIcon(R.drawable.ic_launcher)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
Here is my code for notification. i am able to get the message using the ip address when i have first send the message but now when i am using a new ip address i am not able to get the message and in the log cat it displays Invalid app and invalid package name : perhaps you didnot include a pendingIntent in the extras

Android Status Bar Notification is not updating when app is closed

I have an app which shows battery charge and temperature in the status bar and notification bar. When the app is opened I can see the data updates in the status bar and notification. When I exit/close the app the status bar and notification is not updating its values. Why is the status bar and notification bar not updating when I close the app?
I use BroadcastReceiver to display the notification.
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
notificationMessage(context, intent);
}
private void notificationMessage(Context context, Intent intent){
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
int icon = R.drawable.battery_level_images;
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
float cTemperature = (float) intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1)/10;
float fTemperature = celsiusToFahrenheit(cTemperature);
float voltage = (float) intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1)/1000;
int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, -1);
String healthText = getHealthText(health);
Notification notification = new NotificationCompat.Builder(context)
.setContentTitle("" + level + "% | " + healthText)
.setContentText(cTemperature + "\u2103 | " + fTemperature + "\u2109 | " + voltage + "V")
.setSmallIcon(icon, level)
.setWhen(0)
.setProgress(100, level, false)
.setOngoing(true)
.setContentIntent(pendingIntent)
.build();
notificationManager.notify(0, notification);
}
In my main activity class I turn on the notification with a checkbox.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
............................
myReceiver = new MyReceiver();
ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
batteryStatus = this.registerReceiver(mBatteryInfoReceiver, ifilter);
....................
}
public void onToggleClicked(View view) {
// Is the toggle on?
boolean on = ((CheckBox) view).isChecked();
if (on) {
batteryStatus = this.registerReceiver(myReceiver, ifilter);
SavingData.setNotificationState(true);
} else {
try{
this.unregisterReceiver(myReceiver);
}catch (IllegalArgumentException iae){
iae.printStackTrace();
}
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
SavingData.setNotificationState(false);
}
}
Here is my BroadcastReceiver in my AndroidManifest.
<receiver android:name=".MyReceiver" />
Register your BroadcastReceiver in your service and run it in your background. Running your service all the time might drain users battery. Beware :)
Once your activity is destroyed, your BroadcastReceiver registered via registerReceiver() will go away as well. You probably have a warning or error in LogCat pointing this out to you. Once your BroadcastReceiver is gone, you will stop updating the Notification.

Repeating notification sound

Is it possible (and if yes how) to make push notification sound repeat until it's read? I am creating app that notifies user about new event in app, but user needs to read notification as soon as possible. When user "reads" notification it should stop ringing. Here's code:
public class GCMIntentService extends IntentService {
String mes;
HelperGlobals glob;
public GCMIntentService() {
super("GcmIntentService");
}
#SuppressLint("SimpleDateFormat")
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
glob = (HelperGlobals) getApplicationContext();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
// .... Doing work here
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
public void createPush(String title, String msg, Intent intent) {
Uri soundUri = Uri.parse("android.resource://example.project.com/" + R.raw.notification);
Context context = getApplicationContext();
Intent notificationIntent = new Intent(context, DoNothing.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification n = new Notification.Builder(this)
.setContentTitle(title)
.setContentText(msg)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true).build();
n.defaults |= Notification.DEFAULT_VIBRATE;
//n.defaults |= Notification.DEFAULT_SOUND;
n.sound = soundUri;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, n);
}
}
And BroadcastReceiver:
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("BukuLog", "Receiver");
// Explicitly specify that GcmMessageHandler will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GCMIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
like this:
Notification note = mBuilder.build();
//here
note.flags = Notification.FLAG_INSISTENT;
mNotificationManager.notify(1, note);
int FLAG_INSISTENT : Bit to be bitwise-ored into the flags field that if set, the audio will be repeated until the notification is cancelled or the notification window is opened.
follow android developer

Status bar notification click event Android for background foreground app state

on click of a status bar notification.
i want to check that if my app is in foreground state then only notification will cancel or if my app is in background state it will open my app.
i have managed my app state using this code in my application class
public static boolean isActivityVisible() {
return activityVisible;
}
public static void activityResumed() {
activityVisible = true;
}
public static void activityPaused() {
activityVisible = false;
}
private static boolean activityVisible;
and putting these for all my activities
#Override
protected void onResume() {
super.onResume();
MyApplication.activityResumed();
}
#Override
protected void onPause() {
super.onPause();
MyApplication.activityPaused();
}
for notification i am using this code
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification.Builder(context)
.setContentTitle(title).setContentText(message)
.setSmallIcon(R.drawable.ic_on).build();
Intent notificationIntent = new Intent(context,
AppStartActivty.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
where shod i put this condition to check that app state and notification click behaviour.
sorry for my bad inglish
You can check whether your app is in Background/foreground using below code.
ActivityManager activityManager = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
ArrayList<ActivityManager.RunningAppProcessInfo> appInfo = (ArrayList)activityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo app : appInfo) {
Log.d(TAG, "App: " + app.processName + " State: " + (app.importance == 100 ? "Foreground" : "Background"));
if (app.processName.equals(YourApp().getPackageName())) {
Log.d(TAG, app.processName);
if (app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
// Cancel notification
}
break;
}
}

Android Status Notifications

I have created a BackgroundService class which extends Service class.
I have a Timer which keeps track of the duration between checks. In the onCreate method I set it for 10 seconds, so the behavior I'm expecting is that it sends a status notification message every 10 seconds. The issue I'm having is that every 10 seconds, I hear the status notification "sound" as I enabled it, but I do not see the text reminder on the top of the screen, which only appears on the first notification service alert. Does anyone know how to fix this?
I attached a good deal of source for this class below: Thanks in Advance!
private Timer timer;
private TimerTask updateTask = new TimerTask() {
#Override
public void run() {
Log.i(TAG, "Timer task doing work!");
// Process junk here:
sendNotification("Please leave in 5 min!!!");
}
};
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.i(TAG, "Background Service creating");
timer = new Timer("DurationTimer");
timer.schedule(updateTask, 1000L, 10*1000L);
}
public void sendNotification(CharSequence message)
{
// Execute Check and Notify
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.simon;
CharSequence tickerText = message;
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Context context = getApplicationContext();
CharSequence contentTitle = "LEAVE NOW!";
CharSequence contentText = "LEAVE NOW!!";
Intent notificationIntent = new Intent(this, BackgroundService.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
int HELLO_ID = 1;
mNotificationManager.notify(HELLO_ID, notification);
}
Change the value of contentText with each iteration.
Example:
CharSequence contentText = "LEAVE NOW!! " + System.currentTimeMillis();
I think you will find that the message text changes constantly because you already have a Notification with the same ID as the Notification you wish to send. So what happens is that the text is simply changed.
Another way:
mNotificationManager.clear(HELLO_ID);
Do that before you create the new Notification.

Categories

Resources