In my application am using services move to another activity after ten minutes even the screen in off,screen locked.
my problem Service is run when screen is in ON condition,but in screen OFF or when lock the screen condition means the service is stopped after i unlock the screen means service start from there.i don't know how to do this thing.Can any one know please help me to solve this problem.
My service time coding
public class Time_out_services extends Service {
Handler mHandler;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
mHandler = new Handler();
mHandler.postDelayed(first_Task, 4 * 60 * 1000);
return Service.START_NOT_STICKY;
}
Runnable first_Task = new Runnable() {
public void run() {
mHandler = new Handler();
Intent i = new Intent();
i.setClass(Time_out_services.this, Dialog_actvity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
stopSelf();
}
}
};
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
you have to register a reciever for the screen on off
private static BroadcastReceiver mReceiver = new ScreenReceiver();
make a method "regScreenReciever()" put this code in that
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
appContext.registerReceiver(mReceiver, filter);
then create a broadcast reciever , override its onRecieve method and then put
if(intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_ON)){
Util.disableKeygaurd();
}
Intent linkuryIntent = new Intent(context,UpdateService.class);
context.startService(linkuryIntent);
your code will run fine
Related
I successfully used a service to do a certain task in the foreground. Now, to do it in the background, I'd remove the handler.removeCallbacks method in onDestroy().
But this would also prevents me from stopping the service using stopService(intent).
I saw on the official docs that I should maybe use JobScheduler (as I target API 28).
Here is a more precise indication of my code :
public class MainActivity {
private Intent intent;
onCreate() {
if (intent == null) {
intent = new Intent(this, MyService.class);
}
}
startService(intent);
... // Then is some code to stop the service if needed with stopService(intent)
}
--------------------------------------------------------------
public class myService {
private Handler handler = null;
private static Runnable runnable = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
System.out.println("Running service times " + i);
i++;
handler.postDelayed(runnable, 1000);
}
};
handler.post(runnable);
}
#Override
public void onDestroy() {
handler.removeCallbacks(runnable);
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
I would like it to run in the background (even if the device is locked) but still being able to disable the service (or JobScheduler?).
What are your suggestions?
you can use work manager
or job dispatcher
and there is a lot of options like
SyncAdapter, Bound services, Intent Service
you can use one of these options according to your need
I know that is a well known subject, but I have tried lot of things. I have an simple application, dedicated to a specific user, application has an mainActivity which is displaying some status on screen and it's starting two services, one is making request from a server (at every 5 minutes) and one which is sending sms and replay to server (at every ten minutes).
The application is running on a Samsung pocket 2 with Android 4.4.2, this device is used only for this application. While the device is connected to ADB the services are working just fine, but if I disconnect the phone and let it running normally, the services are killed repeatable and restarted after a while. The messaged are send with very much delay. I would be thankful for any suggestions.
Here is my code:
Main activity:
public class MainActivity extends Activity {
private TextView _internet;
private TextView _signal;
private TextView _server;
private BroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
IntentFilter intentFilter = new IntentFilter(Constants.SS);
receiverWorker();
registerReceiver(receiver, intentFilter);
startService(new Intent(this, RefreshDBService.class));
startService(new Intent(this, SmsService.class));
}
private void receiverWorker() {
receiver = new BroadcastReceiver() {
public void onReceive(Context arg0, Intent arg1) {
checkState();
}};
}
public void refreshButonClicked(View v) {
checkState();
}`
Here is my first service:
public class RefreshDBService extends Service {
private Thread _backgroundWork;
private ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
private DataBaseOperations _dataSource;
#Override
public void onCreate() {
super.onCreate();
_dataSource = new DataBaseOperations(this);
_backgroundWork = new Thread(new Runnable() {
#Override
public void run() {
if(Checks.checkInternetConnection(getApplicationContext())){
if(ServerOperations.isServerAvailable(getApplicationContext())){
String inputData = ServerOperations.makeRequest(Constants.GET_DATA_ROUTE, ServerOperations.getMessagesFromServer(getApplicationContext()));
ArrayList<DataSmsObj> dataFromServer=null;
if(inputData!=null && !inputData.isEmpty()){
dataFromServer = ServerOperations.fromJsonToObjects(inputData);
if(dataFromServer.size()>0){
_dataSource.open();
_dataSource.insertDataFromServer(dataFromServer);
_dataSource.close();
}
}
System.out.println("check server for messages in pending status, received -> "+ dataFromServer.size());
}else{
System.out.println("no server");
sentErrorToUI(Constants.NO_SERVER);
}
}else{
System.out.println("no internet");
sentErrorToUI(Constants.NO_INTERNET);
}
}
});
}
public int onStartCommand(Intent intent, int flags, int startId) {
scheduleTaskExecutor.scheduleWithFixedDelay(_backgroundWork, 0, Constants.NEXT_CYCLE/2, TimeUnit.MINUTES);
return START_REDELIVER_INTENT;
}
#Override
public void onDestroy() {
super.onDestroy();
scheduleTaskExecutor.shutdownNow();
}
public IBinder onBind(Intent intent) {
return null;
}
private void sentErrorToUI(String message){
Intent intent = new Intent(Constants.SS);
intent.putExtra(Constants.SS, message);
System.out.println("trimit" +message);
sendBroadcast(intent);
}
}
And this is the second one:
public class SmsService extends Service {
private Thread _backgroundWork;
private ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
private DataBaseOperations _dataSource;
#Override
public void onCreate() {
super.onCreate();
_dataSource = new DataBaseOperations(this);
_backgroundWork = new Thread(new Runnable() {
#Override
public void run() {
sendFeedbackToServer();
List<DataSmsObj> dataToSent = new ArrayList<DataSmsObj>();
_dataSource.open();
dataToSent = _dataSource.getDataToSent();
_dataSource.close();
System.out.println("messages to sent: "+ dataToSent.size());
for (int i = 0; i < dataToSent.size(); i++) {
//here the messages are send, the code is to long to put it here, but if is need i can do it afterwards
}
}
});
}
public int onStartCommand(Intent intent, int flags, int startId) {
scheduleTaskExecutor.scheduleWithFixedDelay(_backgroundWork, 0, Constants.NEXT_CYCLE, TimeUnit.MINUTES);
return START_REDELIVER_INTENT;
}
#Override
public void onDestroy() {
super.onDestroy();
scheduleTaskExecutor.shutdownNow();
public IBinder onBind(Intent intent) {
return null;
}
If you are using a background Service with a scheduled task, it could be killed by the system. The only way to prevent the killing is a foreground Service. Quoting the documentation:
A foreground service is a service that the user is actively aware of and is not a candidate for the system to kill when low on memory.
You have to call the method startForeground() inside your Service using a Notification to show it. For further information you can check: https://developer.android.com/guide/components/services.html#Foreground
By the way, I recommend you to use the new JobScheduler api above api 21.
https://developer.android.com/reference/android/app/job/JobScheduler.html
Android kills service based on priority stack.
Android: keeping a background service alive (preventing process death)
What is START_STICKY,START_NOT_STICKY and START_REDELIVER_INTENT Service
Above links might help you.
Your devices will sleeps if it is unplugged from computer . So, the solutions :
Use startForeground method to prevent service to be killed and/or use AlarmManager in order to charge event.
It is possible to use start_stiky flag but it just restarts the process if it killed by system.
I'm trying to count time that user is using a phone, so i used receiver
it got registered in MainActivity then i am starting TimeService which is registring receiver too so it can work even if user is in other activity or app.
MainActivity
private void registerScreenReceiver(){
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
TimeService
public class TimeService extends Service {
//
#Override
public void onCreate() {
super.onCreate();
// REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public int onStartCommand(Intent intent, int flags, int start_id) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Log.e("SERVICE","ON");
} else {
Log.e("SERVICE","OFF");
}
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
The problem is that when i'm not using the app it's being closed by itself and receiver is no longer wroking.
You have to return START_STICKY in onStartCommand() to keep Service working.
You can also set your Service as a foreground Service but this require showing notification in the status bar which may not be a bad idea. Here is an example.
Update
It probably would be even better if you register your BroadcastReceiver in AndroidManifest.xml and start Service work from receiver when system wake it up.
please before you don't like my question , please read the details .. what i am trying to do is to use a broadcast receiver when screen-off , so i want my app to start if the screen goes off .. here is my broadcast receiver code :
public class BootReceiver extends BroadcastReceiver {
public boolean screenoff;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenoff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenoff = false;
}
Intent intent1 = new Intent(context, ShakeService.class);
intent1.putExtra("screen_state", screenoff);
context.startService(intent1);
}
and here is the service code :
public class ShakeService extends Service{
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stu
return null;
}
#Override
public void onCreate() {
super.onCreate();
// REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new BootReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try{
Intent intent1 = new Intent(getApplicationContext(), SplashScreen.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return START_STICKY;
}
}
and here is my splash screen activity that i call from the service :
public class SplashScreen extends Activity {
private static int SPLASH_TIME_OUT=3000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Remove title bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_splash_screen);
ImageView imageView = (ImageView) findViewById(R.id.imageView1);
new Handler().postDelayed(new Runnable(){
public void run(){
Intent i =new Intent(SplashScreen.this,HomeScreen.class);
startActivity(i);
finish();
}
},SPLASH_TIME_OUT);
}
#Override
protected void onResume() {
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
BroadcastReceiver mReceiver = new BootReceiver();
registerReceiver(mReceiver, filter);
super.onResume();
}
#Override
protected void onPause() {
// mSensorManager.unregisterListener(mShakeDetector);
BroadcastReceiver mReceiver = new BootReceiver();
unregisterReceiver(mReceiver);
super.onPause();
}
}
and as you can noticed i have unregistered my receiver but still i keep seeing this in the logcat :
leaked Intent Receiver are you missing a call to unregisterReceiver??
I agree with the method of registering the receiver in onResume() and unregistering it in onPause(). This helps when the app goes in and out of scope. I'm somewhat confused on what you're trying to do with your app, but initially I see that you create a new instance of the braodcast receiver in onPause() and unregister that. Try unregistering using the same instance . Also, if you want your service to remain running in the background, you may want to look into implementation of a partial wake lock, that keeps the CPU running for your app while the screen remains off. Could you provide one more details about the purpose of the app?
I'm starting a service from an Activity. The service registers for Battery Changed broadcast Receiver. I receive broadcasts as long as the screen is ON. Once the screen is turned OFF, I stop receiving broadcasts, however, the service doesn't die.
My activity code,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = this.getApplicationContext();
Intent intent = new Intent(this,BatteryStatusService.class);
startService(intent);
}
and my service code,
public class BatteryStatusService extends Service{
private final static String TAG = BatteryStatusService.class.getSimpleName();
private BroadcastReceiver timeTickReceiver;//changeReceiver;
private boolean registered = false;
public class LocalBinder extends Binder {
BatteryStatusService getService() {
return BatteryStatusService.this;
}
}
private final IBinder mBinder = new LocalBinder();
#Override
public void onStart(Intent intent, int startId){
Log.i(TAG,"Starting service");
IntentFilter filter = new IntentFilter();
filter.addAction(Constants.ACTION_BATTERY_CHANGED);
timeTickReceiver = new TimeTickReceiver();
this.getApplicationContext().registerReceiver(timeTickReceiver, filter);
registered = true;
}
#Override
public void onDestroy(){
Log.d(TAG,"Stopping service");
if(registered){
this.getApplicationContext().unregisterReceiver(timeTickReceiver);
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return mBinder;
}
public class TimeTickReceiver extends BroadcastReceiver {
private String action = null;
private final String TAG = TimeTickReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
action = intent.getAction();
if(action.equals(Constants.ACTION_BATTERY_CHANGED)){
Log.d(TAG,"I got action = "+action);
}
}
}
}
}
use AlarmManager and get last broadcasted level with
Intent BATTERYintent=this.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
However there are mobiles where it would work either. I have t-mobile MOVE which will not update battery value/broadcast no matter what in sleep mode... but most mobiles will do it as they should
by the way dont listen to dcanh121 there are cases when u need to get battery level even when phone is in sleepmode.
Once the screen is turned OFF, I stop receiving broadcasts, however, the service doesn't die.
When the screen is turned off, shortly thereafter the device goes into sleep mode. Your code does not execute again until something wakes up the device from sleep mode.
Also:
You do not need to use getApplicationContext() here
You do not need a Binder here, since you are not binding to the service, so just have onBind() return null
You need to have some code somewhere to stop this service, so it does not run forever
why don't you try by using onResume() and onPause()