I have facing problem in getting notification message from GCM Server.Device will get notification correctly when it not idle or in running state but when device goes idle for 10-15 minutes at that time device not able to get notification and also all registered devices are not gets notification from GCM server.How to resolve this problem?
Normally, your app need to wake when it sleeps.
Put this into your manifest file to wake your device when the message is received
<uses-permission android:name="android.permission.WAKE_LOCK" />
Add java class name WakeLocker.java
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context context) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, "WakeLock");
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
Call the above code in 'private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver()' that might be in your MainActivity.java
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
// Waking up mobile if it is sleeping
WakeLocker.acquire(getApplicationContext());
/**
* Take appropriate action on this message
* depending upon your app requirement
* For now i am just displaying it on the screen
* */
// Showing received message
lblMessage.append(newMessage + "\n");
Toast.makeText(getApplicationContext(), "New Message: " + newMessage, Toast.LENGTH_LONG).show();
// Releasing wake lock
WakeLocker.release();
}
};
Thank This source
Hope this helps
Related
I call my Service with alarm manager
like this:
alarmManage.setExact(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + getPoolingInterval(), pendingIntentPolling);
On my ServicePooling i reschedule it of the same way, and this ServicePooling call another service to send data on my service.
Intent serviceSocket = new Intent(this.context, SenderService.class);
this.context.startService(serviceSocket);
All works very well every minut i receive on my server a polling communication, but when my device are screen off and without USB plugged, this stop work.
This is a bad idea to use Service for AlarmManager nowadays. Use WakefulBroadcastReceiver instead. your device fall asleep then unplugged.
public class BRMine extends WakefulBroadcastReceiver {
public static final String INTENT_FILTER = "com.example.BRMine";
#Override
public void onReceive(Context ctx, Intent intent) {
// TODO Auto-generated method stub
OWakeLocker.acquire(ctx, _.indexNOTS);
ComponentName comp = new ComponentName(ctx.getPackageName(),
SMine.class.getName());
startWakefulService(ctx, intent.setComponent(comp));
}
}
where:
public class OWakeLocker {
private static PowerManager.WakeLock[] wakeLocks = new PowerManager.WakeLock[_.indexNOTS_MAX];//Services count
#SuppressWarnings("deprecation")
public static void acquire(Context ctx, int index) {
WakeLock wakeLock = wakeLocks[index];
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, _.APPNAME + Integer.toString(index));
if (wakeLock != null && wakeLock.isHeld()){
wakeLock.acquire();
}
}
public static void release(int index) {
WakeLock wakeLock = wakeLocks[index];
if (wakeLock != null)
wakeLock.release();
wakeLock = null;
}}
to start:
Intent intent = new Intent(BRMine.INTENT_FILTER);
PendingIntent pi = PendingIntent.getBroadcast(ctx, myintentalarm, intent, PendingIntent.FLAG_CANCEL_CURRENT):
am.setExact(AlarmManager.RTC_WAKEUP, nexttime, pi);
I solve my problem using a answer of Vyacheslav but wihtout AlarmManager because setExact didint work for me on idle and my android is a api lower then 23 (and don't have setExactAndAllowWhileIdle) i use a timertask on startapplication in my case works werry well, i just need this when my application are runnning.
I am using Paho Android Service for my project (app name is Sealer). (link)
I've tested it about 22 hours and the result has brought me a strange result.
It seems that my app keeps awake the CPU a very long time (~10,5 h).
I've searched in the source code by wakelock tag and found that the wakelock tag belongs to the AlarmPingSender class. Has anybody met this problem ever ?
I didn't modify the Android Service source code, it's the original.
I've attached some screenshots (Hangouts and Viber just for comparison).
Screenshots
EDIT 1.
There is a code snippet from my source code:
mqttOptions = new MqttConnectOptions();
mqttOptions.setCleanSession(false);
// defaultKeepAlive is 240
mqttOptions.setKeepAliveInterval(Constants.defaultKeepAlive);
EDIT 2
I think this is the relevant code from Android Service source code:
/*
* This class sends PingReq packet to MQTT broker
*/
class AlarmReceiver extends BroadcastReceiver {
private WakeLock wakelock;
private String wakeLockTag = MqttServiceConstants.PING_WAKELOCK
+ that.comms.getClient().getClientId();
#Override
public void onReceive(Context context, Intent intent) {
// According to the docs, "Alarm Manager holds a CPU wake lock as
// long as the alarm receiver's onReceive() method is executing.
// This guarantees that the phone will not sleep until you have
// finished handling the broadcast.", but this class still get
// a wake lock to wait for ping finished.
int count = intent.getIntExtra(Intent.EXTRA_ALARM_COUNT, -1);
Log.d(TAG, "Ping " + count + " times.");
Log.d(TAG, "Check time :" + System.currentTimeMillis());
IMqttToken token = comms.checkForActivity();
// No ping has been sent.
if (token == null) {
return;
}
// Assign new callback to token to execute code after PingResq
// arrives. Get another wakelock even receiver already has one,
// release it until ping response returns.
if (wakelock == null) {
PowerManager pm = (PowerManager) service
.getSystemService(Service.POWER_SERVICE);
wakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
wakeLockTag);
}
wakelock.acquire();
token.setActionCallback(new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.d(TAG, "Success. Release lock(" + wakeLockTag + "):"
+ System.currentTimeMillis());
//Release wakelock when it is done.
if(wakelock != null && wakelock.isHeld()){
wakelock.release();
}
}
#Override
public void onFailure(IMqttToken asyncActionToken,
Throwable exception) {
Log.d(TAG, "Failure. Release lock(" + wakeLockTag + "):"
+ System.currentTimeMillis());
//Release wakelock when it is done.
if(wakelock != null && wakelock.isHeld()){
wakelock.release();
}
}
});
}
}
It seems (at least according to the screenshots) that the wakelock somehow is 'stucked', doesn't released.
I have the same problem and created a bug report. Please have a look for further help: https://bugs.eclipse.org/bugs/show_bug.cgi?id=480134
The ping sender will need to wake up to send a ping at what ever keep alive period is configured. The app needs to wake to send the packet that keeps the connection alive. I've not played with the Paho Android service but you should be able to change this by adding the relevant values to the MQTTConnectOptions object passed to the MQTTAndoridClient.connect() method.
EDIT:
e.g.
MQTTConnectOptions opts = new MQTTConnectOptions();
opts.setConnectionTimeout(240000);
client.connect(opts);
I want my app to run in the background or after the phone has been put to sleep and when you near a certain latitude and longitude my app will immediately pop to the foreground. this must work no matter if it was from sleep or another app was in foreground.
I am using a service and a WakeLock. I am pretty sure the service is working but I don't know how to check because the debugger returns nothing if it is not in the foregrond. If it is working then my WakeLock is not working as anticipated.
public abstract class WakeLocker {
private static PowerManager.WakeLock fullWakeLock;
private static PowerManager.WakeLock partialWakeLock;
private static PowerManager pm;
public static void acquire(Context context) {
if (fullWakeLock != null) fullWakeLock.release();
if (partialWakeLock != null) partialWakeLock.release();
pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
fullWakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP), "Loneworker - FULL WAKE LOCK");
partialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Loneworker - PARTIAL WAKE LOCK");
partialWakeLock.acquire();
}
public static void release() {
if (fullWakeLock != null) {
fullWakeLock.release();
fullWakeLock = null;
}
if (partialWakeLock != null) {
partialWakeLock.release();
partialWakeLock = null;
}
}
public static void wakeDevice(Context context) {
fullWakeLock.acquire();
//KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
//KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG");
//keyguardLock.disableKeyguard();
}
public static boolean fullWakeLockActive() {
return fullWakeLock != null;
}
}
the fullWakeLock is being acquired here
if (makeUseOfNewLocation(location) < 20) {
if (WakeLocker.fullWakeLockActive())
WakeLocker.wakeDevice(allert.getMA());
if (callProgress.isOffHook()) {
new BlinkBack(allert.getMA());
}
The wake lock itself cannot wake the device from sleep or cause your so to come to the foreground. You would have to use location services or an alarm to wake the device up, then use your wake lock to keep the device awake and trigger a UI component of your app to the foreground.
i am using Samsung Galaxy Note. When my phone is in locked state, and when i click the power button i see the pattern unlocking screen. When new messages flow in, i just see a mail icon in the top status bar, but no other notifications in the screen. what needs to be done for that?
You have to wakeup the device when push message came.
onMesaage method of GCM service you have to call below code
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context ctx) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, MainActivity.APP_TAG);
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
See the below link
android AlarmManager not waking phone up
im receiving an intent in broadcast receiver and then i start service to do more work. now what if the device is sleep and this happen, do i have to get Wakelock (AlarmManger?), and why do i need it?
does my service will stop running if the device goes to sleep without getting a wakelock.
now what if the device is sleep and this happen, do i have to get Wakelock (AlarmManger?), and why do i need it?
If the device is asleep to begin with, you will not be "receiving an intent in broadcast receiver", because the device is asleep.
do i have to get Wakelock (AlarmManger?), and why do i need it?
You don't "need it", unless you want to ensure the device stays running while you complete some work.
does my service will stop running if the device goes to sleep without getting a wakelock.
Yes.
Looks like the Android's native WakefulBroadcastReceiver would be a perfect solution for you. Need to extend this rather than the regular BroadcastReceiver and start the service in the onReceive() in the "wakeful" manner:
startWakefulService(context, service);
and signal your work is done in the service's onHandleIntent(), calling
MyWakefulReceiver.completeWakefulIntent(intent);
public class WakeLockManager extends BroadcastReceiver {
private static WakeLock mWakeLock;
private String LCLT;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Consts.WAKELOCK_INTENT)) {
Log.v("wakelock", "GOT THE wakelock INTENT");
boolean on = intent.getExtras().getBoolean("on");
if (mWakeLock == null) {
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"Breeze WakeLock");
}
if (on) {
if (!mWakeLock.isHeld()) {
mWakeLock.acquire();
Log.v("wakelock", "acquiring wakelock");
}
} else {
if (mWakeLock.isHeld()) {
Log.v("wakelock", "releasing wakelock");
mWakeLock.release();
}
mWakeLock = null;
}
}
}
}
look at the above code ..put it in a separate class file and and in your manifest define it for some custom intent .... now that this class will respond to a custom intent ...just broadcast that intent and you can turn the wakelock on or off in your entire app since the wakelock is static..like this :
public void setWakeup(boolean status) {
Intent wakelock_Intent = new Intent(CUSTOM_INTENT);
wakelock_Intent.putExtra("on", status);
this.sendBroadcast(wakelock_Intent);
}
the above would be defined in your alarmmanager code so it schedules a call