I can't receive notifications when screen is lock - java

I'm working with Firebase to send Push notification. When I have the app minimized and the screen lock and Data network on 3G, and batery at 90%, I can't receive notifications. I need to receive notifications while the screen is locked.
I noted this in the log at the moment to screen lock.
2019-06-13 16:40:35.901 2372-9542/? D/MC_BatteryStatsData: operate removing wakelock wake:com.exampleapp/.FCMListenerService
This is for a Moto C Android version 7.
I tried to add this permission to the manifest file.
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Disabled battery saver. It is in the menu Settings -> Battery.
And here is my FCMInstanceIDListenerService.java
public class FCMInstanceIDListenerService extends FirebaseInstanceIdService {
private static final String TAG = "MyInstanceIDLS";
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
MetodosRepo.setPreference(getBaseContext(), Globals.DEVICE_TOKEN, refreshedToken);
}
}
And the FMCListenerService.java
public class FCMListenerService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage message) {
Log.e(_TAG, "onMessageReceived");
}
}
I expect to receive a notification while the screen is locked.ยบ

From Android 8.0 they put a background execution limit and hence you are not receiving the push notification when your application is in the background.
I would like to suggest implementing a JobScheduler which will connect to your server to see if there is any pending notification and create the notification alert accordingly. Here is a sample project on how you can implement your JobScheduler.
However, Android takes care of the push notifications and you will receive a notification after 3-5 minutes I think (not almost instantly when the service is in the foreground).

Related

react native data only fcm on android: start foreground when app is killed

I'm building a react native app which should handle push notifications.
I'm using react-native-notifications to handle the notification logic, and notifee to show the received notifications. But I have a few problems.
There are 3 'states' in which the app is, when a notification should be handled: app in foreground, background or killed.
When the app is in foreground or in background, I can "catch" the notifications with the event handlers from react-native-notifications and based on the payload, create a notification with notifee to display.
The problem is when the app is killed.
I found a pull request of react-native-notifications (see PR here) that would "read" data-only messages on android when the app is killed.
This works, I console.log the output and it shows up in logcat.
My question now is: how can I create a custom notification with notifee when the app is killed? So no react native code can run?
In my index.js I have the following:
AppRegistry.registerHeadlessTask(
"JSNotifyWhenKilledTask",
() => {
return async (notificationBundle) => {
console.log('[JSNotifyWhenKilledTask] notificationBundle', notificationBundle);
}
}
);
the notification is shown in logcat, but now I want to add notifee to this to create a notification. But then I get the following error (in logcat):
android.app.BackgroundServiceStartNotAllowedException: Not allowed to start service Intent
The code that is a problem is this one:
private void notifyReceivedKilledToJS() {
Bundle bundle = new Bundle(mNotificationProps.asBundle());
Intent service = new Intent(mContext.getApplicationContext(), JSNotifyWhenKilledTask.class);
service.putExtras(bundle);
mContext.getApplicationContext().startService(service);
}
I modified the code to this, but now I get another error:
private void notifyReceivedKilledToJS() {
Bundle bundle = new Bundle(mNotificationProps.asBundle());
Intent service = new Intent(mContext.getApplicationContext(), JSNotifyWhenKilledTask.class);
service.putExtras(bundle);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mContext.startForegroundService(new Intent(mContext, JSNotifyWhenKilledTask.class));
} else {
mContext.startService(new Intent(mContext, JSNotifyWhenKilledTask.class));
}
}
android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false
I found this question on SO addressing this problem.
I changed the priority of the notification to "high", and now I get this final error:
android.app.ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground():
I'm guessing I should start this Service.startForeground() somewhere in my java code, but I really have no clue where.
Does anyone know a solution on how to "read" a data-only notification on android when the app is killed, and to run some JS code (notifee) to display a notification?
I'm not very good at java btw, any guidance would be welcome.

Is there possibility to "Auto-start" application when users become inactive?

I have to create an app, which detects user inactivity, and then start activity which displays some videos with WebView, and then when displaying with WebView is finished, it has to play videos from SDCard. I've already handled part with WebView and SDCard (with JavaScriptInterface etc.)
This application has to work with API 19 all the way to the newest one.
The question is - Is there a possibility to detect if user is inactive and start my application, or keep the app running in background, and then start activity in the foreground after the user becomes inactive for certain time?
I'm not trying to play ads, when user is not looking at his screen. Application is for my client, who have stores with all kind of electrical equipments, including smartphones. The goal is to play video presentations with hardware details specific for each smartphone (informations about processor, ram, camera, screen etc.).
In short: I have to make an app which is similar to "Demo Apps" created for example by Samsung (playing some kind of presentations on screen).
So far I've read and tested things like:
1) BroadcastReceiver with combination of ACTION_SCREEN_OFF / ACTION_SCREEN_ON events.
Receiver works properly, I can detect this event and then start activity, but... The screen is already off so i can't see the displayed activity - it's visible running in the foreground after unlocking the phone. Is there a way to unlock the phone when the event is received?
That's my code so far.
EventReceiver Class:
class EventReceiver: BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
StringBuilder().apply {
append("Action: ${intent.action}\n")
append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n")
toString().also { log ->
Log.d(TAG, log)
Toast.makeText(context, log, Toast.LENGTH_LONG).show()
}
}
if (intent.action == Intent.ACTION_SCREEN_OFF) {
val i = Intent(context, MainActivity::class.java)
context.startActivity(i)
}
}
}
MainActivity Class:
val br : BroadcastReceiver = EventReceiver()
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply {
addAction(Intent.ACTION_SCREEN_OFF)
addAction(Intent.ACTION_SCREEN_ON)
addAction(Intent.ACTION_BOOT_COMPLETED)
}
2) Foreground Services - I read that this is a great way to make some asyc stuff in the background and show notifications to user. Is there a way to start the activity with it?
3) Job Scheduler
4) Daydream / Dream Service - it actually works great with almost every API and manufacturer, but.. there's no way to set the app as Screen Saver on Huawei/Honor smartphones, at least from phone settings, I've read that this is possible with ADB etc. but this is not an option that I can use here.
It seems that none of these fullfill my expectations.

How To Run A Code or Full App on Background

my App get a Notification when i get time Like Alarm i Just want to Run my app on Background to Can Push my Notification when time come
i was Try to Search about that Problem and ask on Many Android Groups and i Use then a Thread but Nothing work
if (level==100){
Thread T1 = new Thread(new Runnable() {
#Override
public void run() {
// PushNotification Method
PushNotification();
}
});
T1.start();
}
The Code only Run when App Open but When Close the App the Code Not work
If you're trying to receive notifications from GCM, then create a WakefulBroadcastReceiver that can be used to receive the notification and handle it appropriately.
On the other hand, if you're trying to send a normal notification from within your app, then create your own background Service that can be used to send the notification. Here's a link to a similar SO answer that you can use for reference.

BLE Scan not working in Background with Scanfilters in android pie?

I am using blescan with scanfilters to detect beacons it's working very fine in foreground and background up to oreo version but when it comes to android pie it's not able to send pending broadcast in background.
ScanSettings settings = (new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)).build();
final List<ScanFilter> scanFilters = new ArrayList<>();
scanFilters.add(getScanFilter());
BluetoothAdapter bluetoothAdapter;
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
Intent intent = new Intent(this.getApplicationContext(), MyBroadcastReceiver.class);
intent.putExtra("o-scan", true);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
bluetoothAdapter.getBluetoothLeScanner().startScan(scanFilters, settings, pendingIntent);
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int bleCallbackType = intent.getIntExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, -1);
if (bleCallbackType != -1) {
Log.d(TAG, "Passive background scan callback type: "+bleCallbackType);
ArrayList<ScanResult> scanResults = intent.getParcelableArrayListExtra(
BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT);
// Do something with your ScanResult list here.
// These contain the data of your matching BLE advertising packets
}
}
}
Android 9 introduces several behavior changes, such as limiting background apps' access to device sensors and Wi-Fi scans.
These changes affect all apps running on Android 9, regardless of target SDK version.
Sensors that use the continuous reporting mode, such as accelerometers and gyroscopes, don't receive events.
Android 9 Limited access to sensors in background:
Android 9 limits the ability for background apps to access user input and sensor data. If your app is running in the background on a device running Android 9, the system applies the following restrictions to your app:
Sensors that use the continuous reporting mode, such as accelerometers and gyroscopes, don't receive events.
Sensors that use the on-change or one-shot reporting modes don't receive events.
Solution:
If your app needs to detect sensor events on devices running Android 9 while the app is in the background, use a foreground service.
I an example test Android app using Oreo (API 26) and the the code above (slightly modified) to detect beacons. I am using the Pixel 3 XL (with Pie).
I think that the hard part about this is to know for sure if the code in onRecieve() in MyBroadcastReceiver is actually being run upon detection of a beacon when the device is running on battery only (disconnected from Android-studio and Logcat (USB)).
Using Volley (com.android.volley) to submit a HTTP request to a local http server, I was able to demonstrate that it works as documented - ie. I am able to receive the http request when beacon(s) are detected. However, Volley only sends these these requests when Android is awake or when it periodically wakes up and connects to the network - which in my simple tests was about every 15 minutes (plus some variation), but I did get all the beacon ScanResults on my HTTP server, just in delayed up to 15 minutes. I was even able to remove the app from the list of running apps (you know; swiping up to remove the app) and still see that the onRecieve() in MyBroadcastReceiver was receiving BLE ScanResults.
How do you know that the onRecieve() in MyBroadcastReceiver is being killed? I am very interested to know how you know this.

Android GCM: different way of handling push depending on whether the app is visible or not

I've got a couple of activities and an intent service which handles GCM incoming messages.
Right now for every push, I'm sending a Notification, and after the user clicks it, he is redirected to appropriate screen.
I would like to alter this behavior that if the app is visible (any activity is in the foreground), instead of the notification a dialog message is shown (with appropriate action).
Any idea how to implement it?
I have 2 ideas but none of them is perfect:
Keep track of every activity in the application, if the activity is visible, don't show notification, but sent an intent to the activity (not nice solution)
register/unregister the second broadcast receiver in each activity's onResume/onPause, "catch" the incoming GCM broadcast (I'm not sure if it is possible).
Any other solutions?
A possible solution (idea 1):
To detect whether your app is running back- or foreground, you can simply set a boolean in onPause/onResume:
#Override
protected void onResume() {
super.onResume();
runningOnBackground = false;
}
#Override
protected void onPause() {
super.onPause();
runningOnBackground = true;
}
When you start a new intent from an notification this method gets called: (if you are using singleTop), with the boolean you can determine what to do in the onNewIntent method.
#Override
protected void onNewIntent (Intent intent){
if(runningOnBackground){
//do this
}
else{
//do that
}
}
Hope it helps!
I didn't test it, but the docs say you can get the number of running activities per each task.
Try to find your application's task among currently running tasks:
ActivityManager acitivityManager = (ActivityManager)
context.getSystemService(Context.ACTIVITY_SERVICE);
// Get the top of running tasks, limit by 100
List<RunningTaskInfo> tasks = acitivityManager.getRunningTasks(100);
for (RunningTaskInfo taskInfo : tasks) {
if (YOUR_PACKAGE_NAME.equals(taskInfo.baseActivity.getPackageName())) {
if (taskInfo.numRunning > 0) {
// Show dialog
} else {
// Show notification
}
break;
}
}
Google added a note on getRunningTasks():
Note: this method is only intended for debugging and presenting task management user interfaces. This should never be used for core logic in an application, such as deciding between different behaviors based on the information found here. Such uses are not supported, and will likely break in the future. For example, if multiple applications can be actively running at the same time, assumptions made about the meaning of the data here for purposes of control flow will be incorrect.
So use it at your own risk.
Also check if GCM broadcasts are ordered. If so, you can "override" your default BroadcastReceiver with the other ones in each Activity. Just play with the priority of IntentFilters. When the BroadcastReceiver with higher priority receives the message, it can abort it's further propagation. For your application this means that when some Activity is running, it registers the receiver which shows the dialog and aborts broadcast. If no activity is active, then your default receiver shows the notification.

Categories