how to stop displaying apps in active application window in android - java

I made an app as a service which runs in background. This app is basically a battery alarm. It works fine but the only problem is that when this service is running it also displays this app in the active application task manager. So when I exit this app it stops that service as well. So what I want is to only stop this service when the user unchecks the box in the app settings. If it is checked then it should not be stopped even if it is closed in active application task manager.
How can I stop showing my app in task manager?
I think I should provide code over here This is my service class
public class BatteryService extends Service {
Notify notification = new Notify();
BatteryAlarm alarm = new BatteryAlarm();
private MediaPlayer mMediaPlayer;
boolean flag = false;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
//method to start service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
notification.initNotification(this, false);
this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
//Broadcast receiver to get battery info
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context c, Intent i) {
//notification.initNotification(c);
int level = i.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int plugged = i.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
SharedPreferences getAlarm = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String alarms = getAlarm.getString("ringtones", "content://media/internal/audio/media/45"); // /system/media/audio/ringtones/ANDROMEDA.ogg , content://media/internal/audio/media/45
Uri uri = Uri.parse(alarms);
if(plugged == 2) {
if(level == 100) {
if(uri != null) {
if(flag == false) {
playAlarm(c, uri);
notification.initNotification(c, true);
Toast.makeText(c, "Battery charge is completed. Unplug your mobile phone!", Toast.LENGTH_LONG).show();
flag = true;
}
}
}
} else if (plugged == 0) {
if(uri != null) {
stopAlarm();
}
notification.cancelNotification(c);
//Toast.makeText(c, "Mobile is unplugged", Toast.LENGTH_LONG).show();
}
}
};
//play alarm method
private void playAlarm(Context c, Uri uri) {
mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(getBaseContext(), uri);
final AudioManager audioManager = (AudioManager) c.getSystemService(Context.AUDIO_SERVICE);
if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mMediaPlayer.prepare();
mMediaPlayer.start();
}
} catch (Exception ex) {
ex.printStackTrace();
onDestroy();
}
}
//method to stop playing alarm
private void stopAlarm() {
mMediaPlayer.stop();
flag = false;
}
//method to stop service
public void onDestroy() {
super.onDestroy();
notification.cancelNotification(this);
unregisterReceiver(this.mBatInfoReceiver);
stopAlarm();
Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
}
}
This is my main activity
public class BatteryNotify extends PreferenceActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.xml.prefs);
addPreferencesFromResource(R.xml.prefs);
SharedPreferences getCB = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean cb = getCB.getBoolean("checkbox", true);
final CheckBoxPreference checkboxPref = (CheckBoxPreference) getPreferenceManager().findPreference("checkbox");
if(cb == true) {
startService(new Intent(getBaseContext(), BatteryService.class));
} else if(cb == false) {
stopService(new Intent(getBaseContext(), BatteryService.class));
}
checkboxPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
if(newValue.toString().equals("true")) {
startService(new Intent(getBaseContext(), BatteryService.class));
} else {
stopService(new Intent(getBaseContext(), BatteryService.class));
}
return true;
}
});
}
}
and here is my menifest file
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".BatteryNotify"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".BatteryService"></service>
</application>

The best way to do this would be to create a BroadcastReceiver, register it in the manifest with the appropriate intent-filters and when it receives one it starts the Service or Activity to perform whatever task you need.
EDIT:
Create your BroadcastReceiver as a separate class and register it in the manifest. When it receives a battery event, create a PendingIntent to start the Service. That way it doesn't matter if your app isn't running. It will be started for you.

How can I stop showing my app in task manager?
You can't, for obvious security reasons.

Related

AIDL Client does not bind to remote service

I am trying to run a simple multiplication with a remote service. I have AIDL server file declaring and defining methods. In AIDL, i have copied the same AIDL file as server under the server's package name.
I have given the action for the intent filter of server's service.
Still my AIDL client code is not connecting to the service.
AIDLServer:
Manifest
<service
android:name=".CalService"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="mutliply"/>
</intent-filter>
</service>
ICalService.aidl
interface ICalService {
String getMessage(String name);
int getResult(int val1, int val2);
}
CalService.java
public class CalService extends Service {
public CalService() {
}
private final ICalService.Stub binder = new ICalService.Stub() {
#Override
public String getMessage(String name) throws RemoteException {
return "Hello " + name + ". The result is: ";
}
#Override
public int getResult(int val1, int val2) throws RemoteException {
return val1 * val2;
}
};
#Nullable
#Override
public IBinder onBind(Intent intent) {
return binder;
}
}
AIDLCLient:
MainActivity.java
#Override
protected void onStart() {
super.onStart();
editName = (EditText) findViewById(R.id.editName);
editVal1 = (EditText) findViewById(R.id.editVal1);
editVal2 = (EditText) findViewById(R.id.editVal2);
resultView = (TextView) findViewById(R.id.resultView);
if(calService == null) {
Log.v("CALSERVICE", "cal service null");
Intent it = new Intent("multiply");
it.setPackage("com.example.aidlserver");
if(getBaseContext().getApplicationContext().bindService(
it, connection, Context.BIND_AUTO_CREATE
) == true){
Log.v("Bind", "Bind service Succeeded");
} else {
Log.v("Bind", "Bind service failed");
}
} else {
Log.v("Cal", "Cal Service not null");
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
public void mutiply(View v) {
switch (v.getId()) {
case R.id.btnCal:
int num1 = Integer.parseInt(editVal1.getText().toString());
int num2 = Integer.parseInt(editVal2.getText().toString());
try {
int result = calService.getResult(num1, num2);
String msg = calService.getMessage(editName.getText().toString());
resultView.setText(msg + result);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
private ServiceConnection connection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("onServiceConnected", "Connected");
calService = ICalService.Stub.asInterface(service);
Toast.makeText(getApplicationContext(), "Service Connected",
Toast.LENGTH_SHORT).show();
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.d("onServiceDisconnected", "Disconnected");
calService = null;
Toast.makeText(getApplicationContext(), "Service Disconnected",
Toast.LENGTH_SHORT).show();
}
};
The code shows its an implicit intent used while bindService call.
Intent it = new Intent("multiply");
it.setPackage("com.example.aidlserver");
If you are above API level 21, you must update your code with an explicit intent. Please update your code with setClassName() API to make the bind service call with an explicit intent.
Intent it = new Intent("multiply");
it.setClassName("com.example.aidlserver","com.example.aidlserver.CalService");
if(getBaseContext().getApplicationContext().bindService(it, connection, Context.BIND_AUTO_CREATE) == true){
Log.v("Bind", "Bind service Succeeded");
} else {
Log.v("Bind", "Bind service failed");
}
Please note the following:
Caution: To ensure that your app is secure, always use an explicit
intent when starting a Service and don't declare intent filters for
your services. Using an implicit intent to start a service is a
security hazard because you cannot be certain of the service that
responds to the intent, and the user cannot see which service starts.
Beginning with Android 5.0 (API level 21), the system throws an
exception if you call bindService() with an implicit intent.
Ref: https://developer.android.com/guide/components/services
Also check this too,
"To receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter"
<category android:name="android.intent.category.DEFAULT"/>
https://developer.android.com/guide/components/intents-filters#Receiving
All you need is to add in client app Manifest, where you want tu bind 3rd party app Service. With the same package name you set in the Intent:
val intent = Intent("example_action")
intent.`package` = "your package name"
bindService(intent, connection, Context.BIND_AUTO_CREATE)
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.asvid.services.client">
<queries>
<package android:name="io.github.asvid.services.server" />
</queries>
...
</manifest>
Alternatively you can stay with compileSdk 29 but I don’t recommend that :)

How to stop JobService Scheduled to when app is removed from background?

Currently i am working with an application and my app has a feature that the user will be able to click on a Navigate button and my app will start the Google Map. Till now it's fine and i have done it. But the fact where i am stuck is that i want my app to perform some tasks. To achieve that i have used JobService and scheduled it to run after every 5 seconds even when the app is in background.
When the user presses the back button then inside onDestroy method i have cancelled the scheduler. But when the app is removed from the background by sliding or pressing the cross icon the JobService keeps running as the onDestroy method can be called or not by the os when it is removed from the background. How can i stop the scheduled job when the app is removed from the background?
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="javarank.com.serviceinbackground">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyJobService" android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE" />
</application>
</manifest>
MyJobService class
public class MyJobService extends JobService {
#Override
public boolean onStartJob(final JobParameters jobParameters) {
Toast.makeText(getApplicationContext(), "Doing job", Toast.LENGTH_SHORT).show();
jobFinished(jobParameters, true);
return false;
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
return false;
}
}
Here is my MainActivity
public class MainActivity extends AppCompatActivity {
private static final int JOB_ID = 1;
private JobInfo jobInfo;
private JobScheduler scheduler;
private Button navigateButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ComponentName componentName = new ComponentName(this, MyJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, componentName);
builder.setPeriodic(5000);
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
// if true this job exists even after a system reboot...
builder.setPersisted(false);
jobInfo = builder.build();
scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
scheduler.schedule(jobInfo);
navigateButton = (Button) findViewById(R.id.navigate_button);
navigateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
StringBuffer url = new StringBuffer("https://www.google.com/maps/dir/?api=1");
url.append("&origin=23.755736,90.374627");
url.append("&destination=23.754047,90.371682");
url.append("&travelmode=driving");
Uri gmmIntentUri = Uri.parse(url.toString());
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
}
});
}
#Override
protected void onDestroy() {
Toast.makeText(getApplicationContext(), "Destroy called.", Toast.LENGTH_SHORT).show();
scheduler.cancel(JOB_ID);
super.onDestroy();
}
}
I think you need to override following onStop() method and put stopService() command to stop the JobService.
#Override
protected void onStop() {
// A service can be "started" and/or "bound". In this case, it's "started" by this Activity
// and "bound" to the JobScheduler (also called "Scheduled" by the JobScheduler). This call
// to stopService() won't prevent scheduled jobs to be processed. However, failing
// to call stopService() would keep it alive indefinitely.
stopService(new Intent(this, MyJobService.class));
super.onStop();
}
You can create a new service like
MyService.java
public class MyService extends Service {
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
//stop you jobservice from here
stopSelf();
}
}
and start it from MainActivity.java
startService(new Intent(MainActivity.this,MyService.class));
Android> 7 automatically saves battery power. You must turn on the application's battery saving stop feature.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent();
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
}
}
add this to AndroidManifest.xml
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
I faced this issue, but I found that after schedule job service, it can't be canceled (From view).
So I turned to stop it inside the job service by calling onStopJob(params)
and it worked.

My Service does not stop when the screen is OFF

I'm developing an application, which has only one Service running in the background. I want this Service to run only when the user uses his phone, ie when the phone is unlocked, the Service records the sensor data and when the screen is locked the Service stops, But the problem is that my Service continues to record data even when the screen is off.
I have the following code and I do not see where the problem is!
public class ScreenReceiver extends BroadcastReceiver {
private boolean wasScreenOn = true;
#Override
public void onReceive(Context context, Intent intent) {
System.out.println(intent.getAction());
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)){
wasScreenOn = true;
}else{
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
wasScreenOn = true;
}else{
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
System.out.println(intent.getAction());
wasScreenOn = false;
}
}
}
Intent intent1 = new Intent(context, MyService.class);
intent1.putExtra("statut", wasScreenOn);
context.startService(intent1);
}
}
Code in the manifest
<receiver android:name=".ScreenReceiver">
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT"/>
</intent-filter>
</receiver>
<service
android:name=".MyService"
android:enabled="true" />
And in my service I call the receiver
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
boolean screenOn = intent.getBooleanExtra("statut", true);
System.out.println("statut********************************************************"+screenOn);
if(!screenOn){
System.out.println("END********************************************************");
try {
unregisterReceiver(mReceiver);
}catch(IllegalArgumentException e){}
SM.unregisterListener(this, Accelerometre);
SM.unregisterListener(this, Gyroscope);
SM.unregisterListener(this, Gravity);
stopSelf();
}
return START_STICKY;
}
Thank you!
Firstly, declare a method in ScreenReceiver.java:
private static boolean isServiceWorking(Context context, String serviceClassName) {
ActivityManager myManager=(ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ArrayList<ActivityManager.RunningServiceInfo> runningService =
(ArrayList<ActivityManager.RunningServiceInfo>) myManager.getRunningServices(30);
for(int i = 0 ; i<runningService.size();i++) {
if(runningService.get(i).service.getClassName().equals(serviceClassName)) {
return true;
}
}
return false;
}
It can judge a service alive or not.Then change the code:
Intent intent1 = new Intent(context, MyService.class);
intent1.putExtra("statut", wasScreenOn);
context.startService(intent1);
to:
Intent intent1 = new Intent(context, MyService.class);
intent1.putExtra("statut", wasScreenOn);
if (wasScreenOn) {// if screen on
if (!isServiceWorking(context, MyService.class.getName())) {// the service is not working
context.startService(intent1); // start the service
}
} else {// if screen off
if (isServiceWorking(context, MyService.class.getName())) {// the service is working
context.stopService(intent1); // stop the service
}
}
I hope it can help you.

How to start a service even if user force close it?

i want to start my service even if user force stop the app or some other app force stop my app.
Here is my code.
#Override
public void onDestroy() {
super.onDestroy();
stopLocationUpdates();
AlarmManager alarmMgr = (AlarmManager)this.getSystemService(this.ALARM_SERVICE);
Intent i = new Intent(this, LocationUpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, i, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10, pendingIntent);
}
I start service in onDestroy().This code will work for me if any one have more efficient way to do this please comment on it.
#Override
public void onDestroy() {
super.onDestroy();
startLocationUpdateService();
}
First of all, it is really very bad pattern to run service forcefully against
the user's willingness.
Anyways, you can restart it by using a BroadcastReceiver which handles the
broadcast sent from onDestroy() of your service.
StickyService.java
public class StickyService extends Service
{
private static final String TAG = "StickyService";
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
sendBroadcast(new Intent("YouWillNeverKillMe"));
}
}
RestartServiceReceiver.java
public class RestartServiceReceiver extends BroadcastReceiver
{
private static final String TAG = "RestartServiceReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "onReceive");
context.startService(new Intent(context.getApplicationContext(),
StickyService.class));
}
}
Declare the components in manifest file
<service android:name=".StickyService" >
</service>
<receiver android:name=".RestartServiceReceiver" >
<intent-filter>
<action android:name="YouWillNeverKillMe" >
</action>
</intent-filter>
</receiver>
Start the StickyService in a Component (i.e. Application, Activity, Fragment):
startService(new Intent(this, StickyService.class));

Android: Repeat tasks in background. Does my approach is correct?

I read several threads about repeat asynchronous tasks in background, I first used this way: https://stackoverflow.com/a/6532298 but for some reasons, it seems that after sometime (several hours), it stopped.
So, now I am using this way, but I don't know if this is a good way to proceed:
BroadcastReceiver
public class RetrieveDataTaskBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences mSharedPreferences = context.getSharedPreferences(MY_PREF, 0);
int delayInMs = mSharedPreferences.getInt("set_delay_refresh", 20)*60*1000;
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, RetrieveDataService.class);
PendingIntent pi = PendingIntent.getService(context, 0, i, 0);
am.cancel(pi);
if (delayInMs > 0) {
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + delayInMs,
delayInMs, pi);
}
}
}
My service class:
public class RetrieveDataService extends Service implements OnRefreshInterface {
private Context context;
private PowerManager.WakeLock mWakeLock;
private static final String TAG = "REFRESH_SERVICE";
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void handleIntent(Intent intent) {
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.acquire();
//do the work
callAsynchronousTask();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleIntent(intent);
return START_NOT_STICKY;
}
public void onDestroy() {
super.onDestroy();
mWakeLock.release();
}
#Override
public void onCreate() {
super.onCreate();
context = this;
callAsynchronousTask();
}
public void callAsynchronousTask() {
//My asynchronous task => execute a class that extends AsyncTask
[...]
}
#Override
public void onRefreshInterface(int cb_val1, int cb_val2) {
//Callback when refresh is done
[...]
}
}
androidmanifest.xml:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<service
android:name="com.example.package.RetrieveDataService"
android:enabled="true"
android:label="Refresh Data">
</service>
<receiver
android:name="com.example.package.RetrieveDataTaskBroadcast"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
I also added a way to launch the service when the app starts:
MainActivity:
#Override
protected void onResume() {
super.onResume();
Thread t = new Thread(){
public void run(){
SharedPreferences mSharedPreferences = getSharedPreferences(PREF, 0);
int delayInMs = mSharedPreferences.getInt("set_delay_refresh", 20)*60*1000;
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(MainBaseActivity.this, RetrieveDataService.class);
PendingIntent pi = PendingIntent.getService(MainBaseActivity.this, 0, i, 0);
am.cancel(pi);
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + delayInMs,
delayInMs, pi);
}
};
t.start();
}
Thank you for your help and advice.
You dont need a service to launch the repeated task when the device starts. Your task will never run when the device is off.
You can set a repeating alarm using Alarm Manager.
If the trigger time you specify is in the past when the device was off, the alarm triggers immediately when the device turns on.
Check this - https://developer.android.com/training/scheduling/alarms.html

Categories

Resources