This is a actually a collage project. The requirements are:
Make an app that will change Android Profile to Ringer, Vibration and Silent using any two sensors (I used Proximity and Accelerometer).
Make sure the app runs in Background even after App is closed.
Continuously running sensors consumes too much battery, Do something about is so battery power can be saved as much as possible.
I already fulfilled NO: 1 and functioning as expected, Just 2 and 3 remains.
What will be the easiest way to run this code in Background: I have an idea like this:
I want to Start and Stop the Background service using the Two Buttons.
Here is the Code for NO: 1.
public class SensorActivity extends Activity implements SensorEventListener{
private SensorManager mSensorManager;
private Sensor proxSensor,accSensor;
private TextView serviceStatus,profileStatus;
private Button startService,endService;
private boolean isObjectInFront,isPhoneFacedDown;
private AudioManager audioManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sensor);
audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
proxSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
accSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
isObjectInFront = false;
isPhoneFacedDown = false;
serviceStatus = (TextView) findViewById(R.id.textView_serviceStatus);
profileStatus = (TextView) findViewById(R.id.textView_profileStatus);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, proxSensor, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, accSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
if(event.values[0] > 0){
isObjectInFront = false;
}
else {
isObjectInFront = true;
}
}
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
if(event.values[2] < 0){
isPhoneFacedDown = true;
}
else {
isPhoneFacedDown = false;
}
}
if(isObjectInFront && isPhoneFacedDown){
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
profileStatus.setText("Ringer Mode : Off\nVibration Mode: Off\nSilent Mode: On");
}
else {
if(isObjectInFront){
audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
profileStatus.setText("Ringer Mode : Off\nVibration Mode: On\nSilent Mode: Off");
}
else {
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
profileStatus.setText("Ringer Mode : On\nVibration Mode: Off\nSilent Mode: Off");
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
}
You definitely should use a Service.
The Android user interface is restricted to perform long running jobs to make user experience smoother. A typical long running tasks can be periodic downloading of data from internet, saving multiple records into database, perform file I/O, fetching your phone contacts list, etc. For such long running tasks, Service is the alternative.
A service is an application component used to perform long running tasks in the background.
A service doesn’t have any user interface and neither can it directly communicate to an activity.
A service can run in the background indefinitely, even if the components that started the service is destroyed.
Usually a service always performs a single operation and stops itself once intended task is complete.
A service runs in the main thread of the application instance. It doesn’t create its own thread. If your service is going to do any long running blocking operation, it might cause Application Not Responding (ANR). And hence, you should create a new thread within the service.
Example
Service class
public class HelloService extends Service {
private static final String TAG = "HelloService";
private boolean isRunning = false;
#Override
public void onCreate() {
Log.i(TAG, "Service onCreate");
isRunning = true;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand");
//Creating new thread for my service
//Always write your long running tasks in a separate thread, to avoid ANR
new Thread(new Runnable() {
#Override
public void run() {
//Your logic that service will perform will be placed here
//In this example we are just looping and waits for 1000 milliseconds in each loop.
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
if(isRunning){
Log.i(TAG, "Service running");
}
}
//Stop service once it finishes its task
stopSelf();
}
}).start();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
return null;
}
#Override
public void onDestroy() {
isRunning = false;
Log.i(TAG, "Service onDestroy");
}
}
Manifest declaration
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.javatechig.serviceexample" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".HelloActivity"
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 declared in manifest -->
<service android:name=".HelloService"
android:exported="false"/>
</application>
To start your service
Intent intent = new Intent(this, HelloService.class);
startService(intent);
Reference
Related
I have created an Enterprise mobility managament (EMM)app. When i launched it a few years ago my customer base probably had Android < 8 devices. I've recently had to update my app and the customer base are now using Android 11 devices.
The problem:
I have a BG service that constantly runs. It counts down from 500, then when it hits 0, it fires off a web service that updates states in the EMM portal. The portal is what the customers use to see their devices out in the field.
In the ondestroy method of my BG service, i send a broadcast that uses a receiver to relaunch the destroyed service, thus keeping it alive.
My customers need this service alive as it sends info like data usage and battery level info which could be safety critical in their industry.
What i have tried:
I understand that Android Doze puts app to sleep, i have tried using my solution to send a command to the device that whitelists it from Doze, this does not work.
I've tried using JobIntentService instead but this did not work either.
NB. my app is a device admin app, so does not need to be in the foregroud and actually shouldn't be. Device Admins are also exemp from Doze apparently.
The error:
Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=xxxxx/.ConnectivityService }: app is in background
What is the best way to keep this service running in the background on Android 11?
here is my code:
<service
android:name="xxx.ConnectivityService"
android:enabled="true"
android:permission="android.permission.BIND_JOB_SERVICE">
</service>
.
public class ConnectivityServiceRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e(ConnectivityServiceRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! ");
context.startService(new Intent(context, ConnectivityService.class));
//ConnectivityService.enqueueWork(context, new Intent());
}
}
.
public class ConnectivityService extends Service {
private static final String TAG = ConnectivityService.class.getSimpleName();
public int counter=0;
AppObj appobj;
public ConnectivityService(Context applicationContext) {
super();
Log.e(TAG, "inside ConnectivityService!");
}
public ConnectivityService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.e(TAG, "inside onStartCommand");
appobj = (AppObj)getApplication();
startTimer();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "ondestroy!");
Intent broadcastIntent = new Intent("xxx.ActivityRecognition.RestartConnectivityservice");
sendBroadcast(broadcastIntent);
stoptimertask();
}
private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() {
Log.e(TAG, "inside startTimer");
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, to wake up every 1 second
timer.schedule(timerTask, 1000, 1000); //
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
Log.e(TAG, "inside initializeTimerTask");
timerTask = new TimerTask() {
public void run() {
Log.e(TAG, "in timer ++++ "+ (counter++));
if(counter == 3600){
counter = 0;
appobj.webService.sendPulseToServer();
Intent myIntent = new Intent(getApplicationContext(), TrafficMonitorService.class);
myIntent.setAction("xxx.TrafficMonitorService");
getApplicationContext().startService(myIntent);
}
}
};
}
/**
* not needed
*/
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
.
<receiver
android:name="xxx.ConnectivityServiceRestarterBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:label="ConnectivityServiceRestartServiceWhenStopped">
<intent-filter>
<action android:name="xxx.ActivityRecognition.RestartConnectivityservice"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I'm creating a service which should work when the activity is in background as well as when the whole application is destroyed.
I'm calling location coordinates in the service at every 1 minute interval.
However, when I try to do so, the service shuts down automatically just after 12-15 minutes.
I want the service to work endlessly until and unless it is destroyed by the completion of activity on user interaction.
My service class is as follows:
public class SensorService extends Service {
public int counter=0;
public static final int NINTY_SECONDS = 90000;
public static Boolean isRunning = false;
public LocationManager mLocationManager;
public Get_Coordinates mLocationListener;
public GetSharedPreference sharedPreference;
#Override
public void onCreate() {
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mLocationListener = new Get_Coordinates(getApplicationContext());
sharedPreference = new GetSharedPreference(getApplicationContext());
startTimer();
super.onCreate();
}
public SensorService(Context applicationContext) {
super();
Log.i("HERE", "here I am!");
}
public SensorService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("EXIT", "ondestroy!");
Intent broadcastIntent = new Intent("com.android.startBgService");
broadcastIntent.putExtra("abc","abcd");
sendBroadcast(broadcastIntent);
stoptimertask();
}
private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, to wake up every 1 second
timer.schedule(timerTask, NINTY_SECONDS, NINTY_SECONDS); //
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
// Log.i("in Etro Sendor", "in timer ++++ "+ (counter++));
if (Check_Internet_Con.isConnectingToInternet(getApplicationContext())) {
if (!isRunning) {
startListening();
}
try {
if (sharedPreference.getActiveUserId() > 0) {
mLocationListener.getLocation();
mLocationListener.insertCoordinatesInSqlite();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
}
/**
* not needed
*/
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void startListening() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (mLocationManager.getAllProviders().contains(LocationManager.NETWORK_PROVIDER))
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListener, Looper.getMainLooper());
if (mLocationManager.getAllProviders().contains(LocationManager.GPS_PROVIDER))
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener,Looper.getMainLooper());
}
isRunning = true;
}
}
Here is my manifest
<service
android:name="com.lunetta.etro.e_tro.SensorService"
android:enabled="true"></service>
<service
android:name="com.lunetta.etro.e_tro.SecondService"
android:enabled="true" >
</service>
<receiver
android:name=".SensorRestarterBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped">
<intent-filter>
<action android:name="com.android.startBgService" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
And Here is SensorRestarterBroadcastReceiver class
public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
context.startService(new Intent(context, SensorService.class));
}
}
https://developer.android.com/guide/components/bound-services.html
"A bound service typically lives only while it serves another application component and does not run in the background indefinitely."
To make it run indefinitely, you need to bind the service to a UI component that exists indefinitely. You can use an Android Notification. This is a foreground service.
https://developer.android.com/guide/components/services.html#Foreground
Yes it will stop working, check out the new Docs put up by Google, It has changed completely how location works for battery performance, and yes it having a big deal effect on performance i have changed my completely for the very specific task. Also stop using other repos that do claim that they work are wrong
Check the new updated docs by google
https://developer.android.com/training/building-location.html
The best way I implemented your same requirement is and is live in over about 60k devices and working flawlessly is With depending on Version of Android API using JobService with 23 and higher and lower with Background service. Have use LocationProvider API and Location provider Client API accordingly.
with personal experience i will say this The old style of code use to drain the device battery in few hours, now my code is hardly making a dent, its consuming only like 15 percent overnight overall usage. thats a big change in consumption.
I am trying to create an application that tracks the orientation of the device for a certain amount of time using a service. when the orientation changes, the device makes a sound. This is working perfectly as long as the device is on. As soon as i lock the device or the screen turns off, i dont hear the sounds (which i want to).
My service code is
public class RakatTrackingService extends Service implements SensorEventListener {
private SharedPreferences sharedPref;
private long[] sessionComposition = new long[4];
private String position="none", lastPosition ="none";
private SensorManager sensorManager;
private Sensor accelerometer;
private PowerManager.WakeLock wakeLock;
public RakatTrackingService()
{
}
public RakatTrackingService(long[] sessionComposition) {
this.sessionComposition = sessionComposition;
}
#Override
public void onCreate() {
super.onCreate();
SharedPreferences sharedPref = getSharedPreferences("rakatData",Context.MODE_PRIVATE);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null)
{
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
Toast.makeText(this, "sensor registered", Toast.LENGTH_LONG).show();
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onSensorChanged(SensorEvent event) {
lastPosition = position;
if(Math.abs(event.values[0]) > Math.abs(event.values[1]) && Math.abs(event.values[0]) > Math.abs(event.values[2]))
{
position="horizontal-side";
}
if(Math.abs(event.values[1]) > Math.abs(event.values[0]) && Math.abs(event.values[1]) > Math.abs(event.values[2]))
{
position="vertical";
}
if(Math.abs(event.values[2]) > Math.abs(event.values[0]) && Math.abs(event.values[2]) > Math.abs(event.values[1]))
{
position="horizontal";
}
System.out.println(position);
if(!lastPosition.equalsIgnoreCase(position))
{
MediaPlayer mp = MediaPlayer.create(this, R.raw.click);
mp.start();
mp.setLooping(false);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
PowerManager mgr = (PowerManager)getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wakeLock.acquire();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
wakeLock.release();
}
}
Please help me resolve this issue.
Simply you can't. Sensor listeners doesn't work then your screen is off. You need the app to be active for using it. You can try to acquire a PARTIAL_WAKE_LOCK or a SCREEN_DIM_WAKE_LOCK
So after some digging on the inet, i've come to a conclusion that the service is live but the accelerometer gets disabled when the screen is turned off. This property turns out to be device and brand specific. I am now using a screen dim wakelock to keep the screen on. As for the lock feature, im turning to notifying the user not to lock the screen while using the app. Its doable considering the nature of the app im making.
You can use a foreground service with a notification, however some sensors will get disabled after a while when the screen is off.
After some research, I concluded there is nth like screen saver in androd. But there are some similar like Live-Wallpapers in Launcher screen or lock Screen.
I attempted a small wayout using service.
In my Activity after inactive for certain time I started a service.
My service started twice after the inactivity.
I want the service start once and as well whole over my app.How to do that?
Here are the codes I used.
User Inactive:
serviceHandler = new Handler();
serviceRunnable = new Runnable() {
#Override
public void run() {
Log.e("run times","Myservice");
startService(new Intent(getBaseContext(), MyService.class));
serviceHandler.removeCallbacks(serviceRunnable);
}
};
#Override
public void onUserInteraction() {
super.onUserInteraction();
serviceHandler.removeCallbacks(serviceRunnable);
stopService(new Intent(getBaseContext(), MyService.class));
serviceHandler.postDelayed(serviceRunnable, 8000);
}
MyService:
public class MyService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(MyService.this, "Service Started", Toast.LENGTH_SHORT).show();
ArrayList<String> imagelist = new ArrayList<>();
imagelist.add("");
Intent i = new Intent(this, ScreenSaverActivity.class);
i.putExtra("imageList", imagelist);
i.putExtra("delay", 3000);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
}
}
ScreenSaver Activity is:
public class ScreenSaverActivity extends Activity {
ImageView imgScreenSaver;
LinearLayout screenSaverLayout;
Handler screenSaverHandler;
Runnable screenSaverRunnable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_saver);
screenSaverLayout = (LinearLayout) findViewById(R.id.layout_screen_saver);
imgScreenSaver = (ImageView) findViewById(R.id.img_screenSaver);
Bundle bundle = getIntent().getExtras();
repeatScreenSaver(bundle.getStringArrayList("imageList"), bundle.getInt("delay"));
// repeatScreenSaver("",bundle.getInt("delay"));
}
private void repeatScreenSaver(final ArrayList<String> imageList, final int milliseconds) {
screenSaverHandler = new Handler();
screenSaverRunnable = new Runnable() {
#Override
public void run() {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(imgScreenSaver.getLayoutParams());
Random random = new Random();
params.setMargins(random.nextInt(500), random.nextInt(500),
random.nextInt(200), random.nextInt(200));
imgScreenSaver.setLayoutParams(params);
Ion.with(ScreenSaverActivity.this)
.load(imageList.get(
new Random().nextInt(imageList.size()
)
)
)
.withBitmap()
.error(R.mipmap.ic_launcher)
.intoImageView(imgScreenSaver);
screenSaverHandler.postDelayed(this, milliseconds);
}
};
screenSaverHandler.postDelayed(screenSaverRunnable, milliseconds);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
screenSaverHandler.removeCallbacks(screenSaverRunnable);
finish();
return super.onKeyDown(keyCode, event);
}
And the screensaver layout is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/layout_screen_saver"
android:background="#a0000000">
<ImageView
android:id="#+id/img_screenSaver"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
I've added following code in manifest:
<service android:name=".service.MyService" />
as MyService is inside the package .service
I couldn't find any reliable answer but I got my solution within the application itself using reference to many answers for userInactivity, use of Application.class, currentAppInForeground() and many others. I've included the whole project for screenSaver itself here.
I used Application.class for it.
Here I first found a user inactivity via a thread which runs in Application.class
Then I kept a condition to show screen saver i.e
if(applicationIsInForeGround() && !screenSaverActive && !videoPlaying){
// start screen saver activity
}
The main drawback here is the thread runs even if the app is closed. It might stop when the app is force stopped or device is restarted or the app is uninstalled.
I am new in android. I am creating a Lock screen application. In my application, I want to disable all the outside keys like Home key, Back key.. I already disabled the Back key using:
#Override
public void onBackPressed() {
return;
// Do nothing!
}
But i referred a lot of sites and questions in Stack Overflow to disable the Home key in my app. But nothing worked.
My App working on API 16 .. Please help me. Any help would be appreciated.
Thanks a lot in advence
I recommend reading:
How-To Create a Working Kiosk Mode in Android
Disable the home button and detect when new applications are opened
Since Android 4 there is no effective method to deactivate the home
button. That is the reason why we need another little hack. In general
the idea is to detect when a new application is in foreground and
restart your activity immediately.
At first create a class called KioskService that extends Service and
add the following snippet:
public class KioskService extends Service {
private static final long INTERVAL = TimeUnit.SECONDS.toMillis(2); // periodic interval to check in seconds -> 2 seconds
private static final String TAG = KioskService.class.getSimpleName();
private static final String PREF_KIOSK_MODE = "pref_kiosk_mode";
private Thread t = null;
private Context ctx = null;
private boolean running = false;
#Override
public void onDestroy() {
Log.i(TAG, "Stopping service 'KioskService'");
running =false;
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Starting service 'KioskService'");
running = true;
ctx = this;
// start a thread that periodically checks if your app is in the foreground
t = new Thread(new Runnable() {
#Override
public void run() {
do {
handleKioskMode();
try {
Thread.sleep(INTERVAL);
} catch (InterruptedException e) {
Log.i(TAG, "Thread interrupted: 'KioskService'");
}
}while(running);
stopSelf();
}
});
t.start();
return Service.START_NOT_STICKY;
}
private void handleKioskMode() {
// is Kiosk Mode active?
if(isKioskModeActive()) {
// is App in background?
if(isInBackground()) {
restoreApp(); // restore!
}
}
}
private boolean isInBackground() {
ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
return (!ctx.getApplicationContext().getPackageName().equals(componentInfo.getPackageName()));
}
private void restoreApp() {
// Restart activity
Intent i = new Intent(ctx, MyActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(i);
}
public boolean isKioskModeActive(final Context context) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
return sp.getBoolean(PREF_KIOSK_MODE, false);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Add the following method in your AppContext class to start the service
via application context creation.
#Override
public void onCreate() {
super.onCreate();
instance = this;
registerKioskModeScreenOffReceiver();
startKioskService(); // add this
}
private void startKioskService() { // ... and this method
startService(new Intent(this, KioskService.class));
}
Last, add the service declaration and the permission for retrieving
the foreground process to the manifest:
<service android:name=".KioskService" android:exported="false"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
Basically, the thread checks every two seconds if your application is
running in foreground. If not, the thread will immediately recreate
your activity.