Interruption in android service - android

I have an android service that gets the location every so often and sends a notification. Despite the configuration that I do so that it does not optimize the battery in terminals Huawei and Xiaomi, in so oreo and foot I stop the service when I use the GPS of other apps or make phone calls. It also does not restart even when you have OnStarCommand () START_STICKY. Is there any way to restart this service automatically after these cuts? I have read that these brands have a very aggressive policy regarding battery saving, and I do not know if the shots go around.
Code notification:
private Notification getNotification() {
Intent intent = new Intent(this, LocationUpdatesService.class);
text = Utils.dameCoordenadas(mLocation);
// Extra to help us figure out if we arrived in onStartCommand via the notification or not.
intent.putExtra(EXTRA_STARTED_FROM_NOTIFICATION, true);
// The PendingIntent that leads to a call to onStartCommand() in this service.
PendingIntent servicePendingIntent = PendingIntent.getService(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// The PendingIntent to launch activity.
PendingIntent activityPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.addAction(R.drawable.ic_launch, getString(R.string.launch_activity),
activityPendingIntent)
.addAction(R.drawable.ic_cancel, getString(R.string.remove_location_updates),
servicePendingIntent)
.setContentText(text)
.setContentTitle(Utils.dameTituloNotificacionLocalizacion(this))
.setOngoing(true)
.setPriority(Notification.PRIORITY_HIGH)
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker(text)
.setWhen(System.currentTimeMillis());
// Set the Channel ID for Android O.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(CHANNEL_ID); // Channel ID
}
return builder.build();}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service started");
boolean startedFromNotification = intent.getBooleanExtra(EXTRA_STARTED_FROM_NOTIFICATION,
false);
if (startedFromNotification) {
removeLocationUpdates();
stopSelf();
}
return START_STICKY;}

Here Getting Location you can find the best code for location updates for oreo and above devices and it is working in all type of devices like mi, vivo and nokia.
Try this and any problem you have then mention in comments

Related

android: how to handle taps on foreground notifications

I have a foreground Service that displays a persistent notification like so:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
createNotificationChannel(); // Creating channel for API 26+
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("This is my service")
.setContentText("Tap to open configuration")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(contentIntent)
.setOngoing(true)
.build();
startForeground(SERVICE_NOTIFICATION_ID, notification);
return Service.START_STICKY;
}
Currently, tapping on this notification opens the app just like if I press the app icon. No extra info is passed. I need to tell if the app was opened from the notification and not from the app icon.
Now, The docs say I can start some other activity, but my app is a React Native app, and I only have one real activity: MainActivity. The rest is in JS.
I'm assuming I need to create a BroadcastReceiver and somehow listen to intents that get sent while the user pushes the button. Or maybe I can handle intents in my MainActivity or some Service and emit events to JS from there. I am a bit lost. What's the best way to go about this?
You can try to add an extra flag to the notificationIntent like this:
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.putExtra("FROM_NOTIFICATION", true);
Then you can retrieve that flag in MainActivity.onCreate() like this:
isFromNotification = getIntent().getBooleanExtra("FROM_NOTIFICATION", false);
Also you may need to change the flag PendingIntent.FLAG_CANCEL_CURRENT to PendingIntent.FLAG_UPDATE_CURRENT.

Trying to run application in the background (Minimized/Screen Locked/Removed from running application)

I am writing an android application which will trigger the SMS once a missed call is detected. So far I am able to detect missed call and send the SMS to the caller.
If I run my app, (Turned on the SWITCH (like a smart switch) that checks for the ringing call and detects missed call), and then someone is calling and if it is a missed call, the SMS is fired correctly.
If I minimize my app (Do not lock phone) and open Instagram/Other app, then also SMS is going to caller.
BUT,
when my app (Smart switch to enable this feature is ON), but I close my app, no SMS sent.
when my app is minimized (Screen Locked), no message fired. (Smart switch ON)
when my app is opened (Screen locked), no message fired. (Smart switch ON)
I am new to android. Please help me, I want to keep my app running if my SMART SWITCH is on, the my app will continue to monitor missed call and fire SMS to caller irrespective of APP in background or not, screen locked or not as long as my Smart switch is ON.
I tried to start a service and it worked, for background to work, we need a foreground.
public class myservices extends Service
{
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Intent notificationIntent = new Intent(this, MainActivity.class); //To open the MainActivity onClick
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Intent busy = new Intent(this, InterceptCall.class);
Intent driving = new Intent(this, InterceptCall.class);
Intent meeting = new Intent(this, InterceptCall.class);
busy.putExtra("mode","busy");
driving.putExtra("mode", "driving");
meeting.putExtra("mode", "meeting");
PendingIntent busyIntent = PendingIntent.getBroadcast(this, 1, busy, PendingIntent.FLAG_UPDATE_CURRENT); //For mini icon in notification bar
PendingIntent drivingIntent = PendingIntent.getBroadcast(this, 2, driving, PendingIntent.FLAG_UPDATE_CURRENT); //For mini icon in notification bar
PendingIntent meetingIntent = PendingIntent.getBroadcast(this, 3, meeting, PendingIntent.FLAG_UPDATE_CURRENT); //For mini icon in notification bar
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Smart Mode is on ")
.setContentText("Drag down to display modes.")
.setContentIntent(pendingIntent)
.setColor(Color.MAGENTA)
.setSmallIcon(R.drawable.pingedlogo)
.addAction(R.mipmap.ic_launcher, "Busy", busyIntent)
.addAction(R.mipmap.ic_launcher, "Driving", drivingIntent)
.addAction(R.mipmap.ic_launcher, "Meeting", meetingIntent)
.build();
startForeground(1, notification);
return START_NOT_STICKY;
}
The first you need to have the permission about task
<uses-permission android:name="android.permission.WAKE_LOCK" />
Code example
Thread(Runnable {
// a potentially time consuming task
val bitmap = processBitMap("image.png")
imageView.post {
imageView.setImageBitmap(bitmap)
}
}).start()
Also you need to
I recommend to look up the next page
https://developer.android.com/guide/components/processes-and-threads
Services overview
This is how I solved it.
public class myservices extends Service
{
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Intent notificationIntent = new Intent(this, MainActivity.class); //To open the MainActivity onClick
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Intent busy = new Intent(this, InterceptCall.class);
Intent driving = new Intent(this, InterceptCall.class);
Intent meeting = new Intent(this, InterceptCall.class);
busy.putExtra("mode","busy");
driving.putExtra("mode", "driving");
meeting.putExtra("mode", "meeting");
PendingIntent busyIntent = PendingIntent.getBroadcast(this, 1, busy, PendingIntent.FLAG_UPDATE_CURRENT); //For mini icon in notification bar
PendingIntent drivingIntent = PendingIntent.getBroadcast(this, 2, driving, PendingIntent.FLAG_UPDATE_CURRENT); //For mini icon in notification bar
PendingIntent meetingIntent = PendingIntent.getBroadcast(this, 3, meeting, PendingIntent.FLAG_UPDATE_CURRENT); //For mini icon in notification bar
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Smart Mode is on ")
.setContentText("Drag down to display modes.")
.setContentIntent(pendingIntent)
.setColor(Color.MAGENTA)
.setSmallIcon(R.drawable.pingedlogo)
.addAction(R.mipmap.ic_launcher, "Busy", busyIntent)
.addAction(R.mipmap.ic_launcher, "Driving", drivingIntent)
.addAction(R.mipmap.ic_launcher, "Meeting", meetingIntent)
.build();
startForeground(1, notification);
return START_NOT_STICKY;
}

Removing buttons from foreground service notification

I have used foreground service but when the app is in bg, it shows task Completed which I dont want. How can I remove it? If this line (.addAction(R.drawable.ic_cancel, getString(R.string.remove_location_updates),
servicePendingIntent)) is removed, the bg service doesn't work. If this code is used: '.setContentIntent(servicePendingIntent)', when I click in the noti, the app doesn't open, noti closed and service stops. How can I solve it? Thanks in advance
private Notification getNotification() {
Intent intent = new Intent(this, LocationUpdatesService.class);
CharSequence text = Utils.getLocationText(mLocation);
// Extra to help us figure out if we arrived in onStartCommand via the notification or not.
intent.putExtra(EXTRA_STARTED_FROM_NOTIFICATION, true);
// The PendingIntent that leads to a call to onStartCommand() in this service.
PendingIntent servicePendingIntent = PendingIntent.getService(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent activityPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, LiveTrack.class), 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.addAction(R.drawable.ic_cancel, getString(R.string.remove_location_updates),
servicePendingIntent)
.setContentIntent(activityPendingIntent)
// .setContentIntent(servicePendingIntent)
.setContentText("App name")
.setContentTitle(Utils.getLocationTitle(this))
.setOngoing(true)
.setPriority(Notification.PRIORITY_HIGH)
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker(text)
.setWhen(System.currentTimeMillis());
// Set the Channel ID for Android O.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(CHANNEL_ID); // Channel ID
}
return builder.build();
}
private void onNewLocation(Location location) {
mLocation = location;
// Notify anyone listening for broadcasts about the new location.
Intent intent = new Intent(ACTION_BROADCAST);
intent.putExtra(EXTRA_LOCATION, location);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
// Update notification content if running as a foreground service.
if (serviceIsRunningInForeground(this)) {
mNotificationManager.notify(NOTIFICATION_ID, getNotification());
}
}
public boolean serviceIsRunningInForeground(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(
Integer.MAX_VALUE)) {
if (getClass().getName().equals(service.service.getClassName())) {
if (service.foreground) {
return true;
}
}
}
return false;
}
If you will look at official document, it says
For user-initiated work that need to run immediately and must execute
to completion, use a foreground service. Using a foreground service
tells the system that the app is doing something important and it
shouldn’t be killed. Foreground services are visible to users via a
non-dismissible notification in the notification tray.
Even in the services document it says
A foreground service performs some operation that is noticeable to the
user. For example, an audio app would use a foreground service to play
an audio track. Foreground services must display a Notification.
Foreground services continue running even when the user isn't
interacting with the app.
So it seems, there must be non-dismissible notification when you are using foreground services.

How to prevent android to stop a service with forground (for android version>O ) and notification

I want to take signal measurements. My app activity takes masurements (and provide charts) when is in foreground and at the onPause event I call and bind a service to take measurements (and store them in the database) in order to replace the activity.
However if the phone is unpluged the app stop taking measurements. I have study a lot of other posts and I have implemented in foreground with notification.
Here is a code sample from the Service
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent,START_STICKY,startId);
goForeground();
return Service.START_STICKY; }
private void goForeground() {
Log.i(TAG ,"goForeground");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Notification n = new Notification.Builder(this)
.setContentTitle("Measurements Service")
.setContentText("App still collects measurements.")
.setSmallIcon(R.drawable.myApp)
.setContentIntent(pendingIntent)
.setPriority(Notification.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.build();
NotificationManager notificationManger =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManger.notify(01, n);
startForeground(FOREGROUND_NOTIFICATION_ID, n);
}
and the MainActivity
Intent serviceIntent = new Intent(MainActivity.this, SnoopService.class);
if (SnoopService.isRunning()) {
Log.d(TAG, "Service is running");
doBindService(intent);
} else {
Log.d(TAG, "Service will run");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent);
} else
startService(intent);
doBindService(intent);
}
isBound = true;
}
Does anyone knows if I am doing something wrong?
I have test it with Samsung Galaxy S8.

NotificationCompat and setFullScreenIntent()

I was wondering if anyone has some experience with with this type of Notification.
In my use case I want to trigger a notification from my Service and than it should open a fullscreen video. The method setFullScreenIntent look just the right thing for this problem because in the documentation it writes:
An intent to launch instead of posting the notification to the status bar. Only for use with extremely high-priority notifications demanding the user's immediate attention, such as an incoming phone call or alarm clock that the user has explicitly set to a particular time.
So it says it works like an incoming phone call. That means even if my phone is asleep I should get to see the notification in full screen.
But in my case I just get the heads-up notification and if I click on it it opens the activity. Even thought in the docs they mention something about this behavior ...
On some platforms, the system UI may choose to display a heads-up notification, instead of launching this intent, while the user is using the device.
... I want to know how to automatically open the activity when the notification is triggered. Just like the incoming phone call screen.
This is my code from the service:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent("android.intent.category.LAUNCHER");
intent.setClassName("com.example.test",
"com.example.test.VideoActivity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(contentIntent)
.setContentTitle("Video")
.setContentText("Play video")
.setFullScreenIntent(contentIntent, true);
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
return Service.START_STICKY;
}
try to notify notification with setFullScreenIntent at onCreate
#Override
public int onCreate() {
Intent notificationIntent = new Intent("android.intent.category.LAUNCHER");
intent.setClassName("com.example.test",
"com.example.test.VideoActivity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(contentIntent)
.setContentTitle("Video")
.setContentText("Play video")
.setFullScreenIntent(contentIntent, true);
NotificationManager mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
}
Try removing
.setContentIntent(contentIntent)

Categories

Resources