Is It Possible To Run Service In Android Platform Continuously Even After Locking The Device?
Solution 1:
One approach could be for you to rely on the AlarmManager : once you subscribe to an AlarmManager the system itself runs your code at the interval you setup, even if your app is not active. Each time it runs you can decide to process some code... So you completely avoid the need to keep a service alive.
What you need is an Alarm class that will handle the AlarmManager intent.
Create your Alarm :
publicclassAlarmextendsBroadcastReceiver
{
privatestaticfinalStringTAG="Alarm";
@OverridepublicvoidonReceive(Context context, Intent intent)
{
PowerManagerpm= (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLockwl= pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
/***************
Here you can do your stuff...
This will be triggered every second.
Send data from here, or better: call an IntentService
that will take care of it.
****************/
wl.release();
}
publicvoidSetAlarm(Context context)
{
Intenti=newIntent(context, Alarm.class);
booleanalarmUp= (PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp)
{
// The alarm is already running, do not set it twice
}
else
{
AlarmManageram= (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntentpi= PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000, pi); // 1000 Millisec means it will trigger it every second... and RTC_WAKEUP means that it will wake up your device if needed.
}
}
// later on, use this method if you want to manually cancel the AlarmManager :publicvoidCancelAlarm(Context context)
{
Intentintent=newIntent(context, Alarm.class);
PendingIntentsender= PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManageralarmManager= (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
In your Manifest declare this Alarm BroadcastReceiver
<receiverandroid:name=".utils.Alarm"android:process=":remote" ></receiver>
And from where you want in your Activity call this AlarmManager !
Alarmalarm=newAlarm();
@OverrideprotectedvoidonCreate(Bundle savedInstanceState)
{
alarm.SetAlarm(this);
}
// or if elsewhere you need to stop the Alarm :
alarm.CancelAlarm(this);
This is the main idea. Now you need to deal with screen on or off. For this 2 solutions : you can register for the device screen state intent and manage the AlarmManager on/off... or you can let the AlarmManager always running but checking if the device is on/off before sending data...
Hope this will help !
Solution 2:
You are acquiring the wake lock in your Activity
. The problem here is that when the device is locked, your Activity
gets pushed to the background. After 15 minutes of inactivity, Android is simply killing the process. This releases the wake lock. The device goes to sleep.
Now, the next time your alarm goes off, the device wakes up, your BroadcastReceiver
is triggered, onReceive()
is called, it starts your Service
, but then the device goes back to sleep because there is no wake lock, so the `Service doesn't do anything.
Another approach, if you want to prevent the phone from going to sleep while your app is running, would be to acquire the wake lock in the Service
. In this case, you don't want to call stopSelf()
every time your Runnable
runs. You would want to keep your Service
running until you want to stop it, at which time you would call stopService()
. This way, the Service
would always be active (even though it isn't doing anything) and it would prevent the device from sleeping through the wake lock. This may, however, put an unacceptable drain on the battery (you'll have to test it).
You need to acquire the wake lock in the BroadcastReceiver
and make sure that the Service
gets started and acquires a wake lock before the device goes back to sleep. Have a look at WakefulBroadcastReceiver
, which you can use to implement this behaviour.
Solution 3:
Yes, you can run any service even if the device is locked. Even, you can resume the service after rebooting the device.
You can implement GCM Network Manager.
Sample code required:-
<serviceandroid:name=".MyTaskService"android:exported="true"android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE"><intent-filter><actionandroid:name="com.google.android.gms.gcm.ACTION_TASK_READY" /></intent-filter></service>
Java code :-
mGcmNetworkManager = GcmNetworkManager.getInstance(this);
OneoffTask task = new OneoffTask.Builder()
.setService(MyTaskService.class)
.setTag(TASK_TAG_WIFI)
.setExecutionWindow(0L, 3600L)
.setRequiredNetwork(Task.NETWORK_STATE_UNMETERED)
.build();
mGcmNetworkManager.schedule(task);
Fore more info you can visit https://developers.google.com/cloud-messaging/network-manager#run_tasks and read the docs.
You just have to include the gcm services in you project to use GCM network manager. Support 4.0 +
Please accept this answer if this is the solution you want. This may help other developers also.
Solution 4:
Yes you can implement a background service that it will almost never be killed. But you have to declare it to run in the foreground. you can see what Android Developer site says, by referring to this url(http://developer.android.com/guide/components/services.html) also in this article (http://developer.android.com/guide/components/processes-and-threads.html) they say,
There are five levels in the importance hierarchy and the different types of processes in order of importance (the first process is most important and is killed last):
- Foreground process:
A process that is required for what the user is currently doing. A process is considered to be in the foreground if any of the following conditions are true:
- It hosts an Activity that the user is interacting with (the Activity's onResume() method has been called).
- It hosts a Service that's bound to the activity that the user is interacting with.
- It hosts a Service that's running "in the foreground"—the service has called startForeground().
- It hosts a Service that's executing one of its lifecycle callbacks (onCreate(), onStart(), or onDestroy()).
- It hosts a BroadcastReceiver that's executing its onReceive() method.
Generally, only a few foreground processes exist at any given time. They are killed only as a last resort—if memory is so low that they cannot all continue to run. Generally, at that point, the device has reached a memory paging state, so killing some foreground processes is required to keep the user interface responsive.
So you have to start your service in the foreground. In order to do this you have implement the service as below.
publicclassMyForegroundServiceextendsService {
@OverridepublicvoidonCreate() {
super.onCreate();
//your code goes here
}
@Overridepublic IBinder onBind(Intent intent) {
thrownewUnsupportedOperationException("Not yet implemented");
}
@OverridepublicintonStartCommand(Intent intent, int flags, int startId) {
keepServiceAlive();
//your code goes herereturn(START_NOT_STICKY);
}
privatevoidkeepServiceAlive() {
IntentnotificationIntent=newIntent(this, MainActivity.class);
PendingIntentpendingIntent= PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notificationnotification=newNotificationCompat.Builder(this).setContentTitle(getString(R.string.app_name))
.setContentText("Hello")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build();
startForeground(Notification.FLAG_ONGOING_EVENT, notification);
}
@OverridepublicvoidonDestroy() {
super.onDestroy();
Log.w(getClass().getName(), "Got to stop()!");
stopForeground(true);
}
}
Thanks and gud luck..
Solution 5:
You have to fire the alarm over and over again when the service completes running.
Also you can implement a BroadCastReceiver that starts the service on the device boot.
Check this tutorial: http://ncona.com/2014/04/schedule-your-android-app-to-do-something-periodically/
Post a Comment for "Is It Possible To Run Service In Android Platform Continuously Even After Locking The Device?"