I'm building an App which does some communications with a server using GCM. It works all fine but one.
I've implemented an instant chat which sends notifications to the other android device that there is a new message.
If the other device clicks on the noti, it will enter the instant chat room to reply, or just see newly updated messages.
I'm doing this by comparing a flag from the server ; if the message is the first one to send and the app or device is sleeping, it will make a noti which can link to the new chat room.
If the message is from the currently running chat room, it will just update it.
But as you can easily see, it can't do anything if the device receiving the message is not awake.
So I want to tell if the device state is awake of not to decide whether the message is from a new chat room, or from a current one.
If it's from a new one(when the device is sleeping), it will display a noti which will lead to the newly made chat room, and if it's from the current chat room, it will just update the chat log.
I think you need to study PowerManager API for android.
PowerManager Link
From what i can tell you can use the method isInteractive() or isScreenOn() depending on what version of android your on(isScreenOn was deprecated in API level 20 and is replaced by isInteractive) to check if the screen is off.
But i will advise against using isScreenOn() there is no guarantee that the device will go to sleep after the screen is turned off. This is upto the OEM.
Best you can do is keep the device awake using Wakelock
Wakelock Link
I solved this issue by following this link.
How can I tell if Android app is running in the foreground?
by the answer of Gadenkan, I made an activityManager object to check if my app is running in the foreground.
So, if it is not running on the foreground, it will call the entire app to start from the main activity to the chat room.
If not, it will just tell the broadcastlistener to append new messages by the GCM.
Related
We have a Wear OS app, which relies heavily on Firebase messages. We send data only messages from pyfcm and we handle them inside onMessageReceived(). All messages are with high priority. This seems to be working properly for some time, which varies - can be between 10 minutes and few hours.
After some time we stop receiving messages. From the documentation I know that a high-prio data message should wake up the device even in Doze - unfortunately this is not happening.
What we believe it is happening is that FCM is de-prioritizing our notification because of low interaction pattern. The issue is that his is core functionality and we can't change that.
Any idea how we can overcome this issue?
I don't believe that the problem is that FCM is de-prioritizing your messages. The problem could be how your app is handled by Wear OS when in Doze mode.
A similar issue is present in android smartphones. They don't receive push notification from FCM when user swipes the app from the system tray because, due to brand specific battery saving reasons, the services needed to handle push notification (MessagingService and InstanceIDService) are not running in the background. To have an idea of the issue on smartphone see this: Firebase Github issue.
Probably after some time that your app is in background it gets killed by the OS in order to save battery, so then the services are not running and it doesn't receive notification anymore.
Anyway without some further explanation on how the app works and without any code I can only make a guess.
I have developed a device Admin app that applies policies to the device eg restrictions etc.
How my system works
The webapp sends a push notification to the device via FCM. I used to use GCM and a wakelock.(The latter worked fine). When the push notification comes through to the device, the firebase class that receives the push calls an IntentService. This IntentService then processes the message eg "MOBILEDATA_ON" and any data associated with the message. Once the message has been processed eg MOBILEDATA_ON, the service executes code that turns the mobile data on and then calls a webservice relaying the state back to the webapp.
I chose IntentService as it is Async and is capable of making http calls to relay the state back with no extra async code.
All this works fine when the device is awake, even if the app is in the background.
The problem
If the device is unplugged and untouched for a while, it goes into Doze/Standby mode. (it is an Android 6 device). This is normal behaviour, however if i send a push to the device, the device does receive it and executes the correct code to apply the functionality but unfortunately the webcall that relays the new state of the device is not executed.
so for example, if Bluetooth is switched off on my device and it is in doze mode, i can send a push which switched bluetooth on successfully but the webapp never receives the updated state.
I have set the priority to high in FCM when sending the push, and this why i do receive the push when the device is in Doze.
My app is a Device Admin app, the docs says
The app is an active device admin app (for example, a device policy
controller). Although they generally run in the background, device
admin apps never enter App Standby because they must remain available
to receive policy from a server at any time.
Optimizing for doze
Can anyone tell me why the webcalls are not executing sending the state back to server when in Doze/Standby mode?
[EDIT1]
I used the following code to create a wakelock. At first i acquired the lock in the IntentService, executed the functionality then released it all in the same service. This was good for most cases but some of my functionality includes finding device location via another IntentService called Tracking service.
The problem is that GPS could take say 20 seconds to find a lock by which time the original Intentservice has finished and the device went back to sleep.
To get around this i created 2 methods in the application Object to acquire and release the lock. this way, if the push is one for location i can do a check in the initial service(which normally releases it) to see if the push is a location one and not release it there. Instead the tracking service can make a call to the Application Object to release when GPS is found.
A partial wakelock didn't seem to work as intended so i found the following code that uses a full wakelock. This is depreated though. Is the an alternative to using FULL_WAKE_LOCK?
public void acquireWakeLock(){
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
"MyWakelockTag");
wakeLock.acquire();
Log.e(TAG, "just acquired wakelock");
}
public void releaseWakeLock(){
wakeLock.release();
Log.e(TAG, "just released wakelock");
}
thanks
Matt
I have an Android app, instant messaging is one of the key features. For implementing the IM feature, we use our push server based on websocket.
For my app, I have a PushService, in this service, I establish a websocket connection which connects to the push server and receive push message.
The code works well when app in foreground (i.e.: works well while user plays with the app), but when the app doesn't in foreground, it stop receiving push messages after a while (about 1 minute). Same issue when user turns off screen.
I have set a repeat task with AlarmManager, which checks the websocket connection status, if it is not in connected status, then re-try to connect so as to back to normal to receive push messages.
This works well below Android M, for example on the Android 5 phones, it seldom misses push messages. But on Android M / Android N, it doesn't work as good as on Android 5.x. I can confirm the service itself is keep running , check from the 'Running services'.
I've noticed that starts from Android M, Android introduces Doze and Standby mode, not sure if they are related, if yes, how can I make the app continue to work again? On my phone the WeChat and Skype Android App work well, what's the mechanism behind it? I know FCM is the best solution, but I cannot use that for customers in China, so I need a workaround.
Edit: I had proposed to use a foreground service but PM doesn't like the notification tray always being shown in the status bar he wants to keep it clean.
Any advice will be appreciated!
I don't know about WeChat or Skype communication, but i know the WhatsApp using you own service notification with the same tecnology of FCM.
They using the Jaber server with implements the XMPP communication protocols
link
I am struggling with android services. The purpose of app is to send text message using native system text application. The phone recieves phone numbers from Firebase and sends a message to all the numbers from the list via smsManager.sendTextMessage. I realized that few minutes after screen is locked the app stops running for no reason..
As I already said I tried to keep my app running in background with android services but it is not working. Is there any simple way to achieve this?
There are a number of way to make a Service work even when the device is in sleep mode. This depends on the feature you want to implement. As far as I have understood, mobile numbers will come from server and app will send messages to these numbers.
If you want to do it in a repeating manner, You can use AlarmManager to start the service from time to time, and fetch the numbers and send messages.
You can also use wacklock to keep the service running all the time, but this will be more battery draining.
I am creating a app in android 4.0.3 i.e ICS version, which connects to the server when client gets login into the app.I am trying to get status of an client when he gets online or offline through server & seen onto the app screen.I am unable to proceed. Can anyone say me:
Is it possible to get the status of an user through server?
1-- How to proceed for first step...?
2-- How should I get a response from the server that the client is connected & viewed to other client example - when we login into skype our status shows available with green radio button, In same way how can I get it.?
It ll be very help full, If anybody guide me.
Many Thanks..
I'm assuming you're trying to develop a chat app ?
If this is the case, try using an XMPP library. XMPP is widely used for chat apps, including Facebook chat (and Google talk I think) and there are plenty of open source libraries available.
Otherwise, if you only want real-time notifications as a part of a bigger picture, try using push notifications. Google supports Cloud to Device Messaging (C2DM) for android. It allows to have push notifications to a specific device without you having to deal with persistent connections, battery and CPU use .etc.
C2DM approach comes down to this. When a client connects to your server, get a list of his friends and their 'C2DM IDs' and fire a C2DM push to their devices. This push is delivered to your app, and you can respond to it by firing a notification, or update UI .etc. (Your app doesn't necessarily have to be running. Push notification is delivered via a specific broadcast, and your app can register a receiver for it to wake up.)
Keep in mind that there is a quota for C2DM messages per device, per app and also a limit for the payload per message. So you're not supposed to send massive files via this. Just a notification to your app, so it can call your server and get an updated list, instead of polling.
You can get more info on C2DM and code samples here. https://developers.google.com/android/c2dm/
Hope this helps.
You may have moved on, but I'm posting for anyone who would run into this one in the future.
Firebase is a good solution to use in this scenario, if the app is always running when you want communication to happen. (It will not wake up your app as C2DM/CDM does, unless you have a service running all the time and still wouldn't wake up if the device is asleep... AFAIK)
It may be useful for some scenarios, but may be not for a chat app as you want the device to wake up when a message arrives.
Note that they have limitations on the free subscription though.