I've just made a service to set something, Added a log and a timer, the timer delay is taken form sharedpreferences value, the value is returning 5 minutes, the problem that the Service is looping in a crazy way, it's not a 1 sec delay, nope .. it's less than a second delay and it's outputting the log message .
And to mention, I'm using the same code with another service, I have this problem only in this service, Codes :
Manifest :
<service
android:name=".services.ServiceTest"
android:enabled="true"
android:exported="false" >
</service>
Switch that starts the service :
Intent BroadcastIntent = new Intent(getActivity(),ReceiverTest.class);
BroadcastIntent.setAction(packagetest+"startservice");
getActivity().sendBroadcast(BroadcastIntent);
Receiver takes the action, in a if statement and runs the service via intent in the following way :
Intent ServiceTestIntent = new Intent(context, ServiceTest.class);
context.startService(ServiceTestIntent);
The Service :
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SharedPreferences Preference = PreferenceManager.getDefaultSharedPreferences(this);
int Delay= Preference.getInt("Value", 2 * 60 * 1000);
MyTimer = new Timer();
new Thread()
{
public void run() {
MyTimer.schedule(new TimerTask() {
#Override
public void run() {
Log.i(Fragment.TAG,"Message Test");
}
}, Delay, Delay);
}
}.start();
return START_NOT_STICKY;
}
The delay returns 5 minutes (5*60*1000) and then i store it in the sharedpreferences, When i log the value it says 5 minutes, so it's a correct time, even though the default is 2 minutes, the service loops directly and output the message .
Receiver :
if(intent.getAction().equals(mainactivity.package+"startservice"))
{
context.startService(ServiceIntent);
}
UPDATE :
Another thing is, I got 3 other services with different receivers, When i switch any of them, the Test service will be launched, even though i didn't start it or reference it, or anything related to it in the other switches .
I've tried rebooting/App full deletion using Root App remover .
Add a log statement to show the delay. Either the delay value is wrong or the service is being started multiple times:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SharedPreferences Preference = PreferenceManager.getDefaultSharedPreferences(this);
final int Delay= Preference.getInt("Value", 2 * 60 * 1000);
Log.i(Fragment.TAG, String.format("onStartCommand(): delay=%d", Delay));
final Timer MyTimer = new Timer();
new Thread()
{
public void run() {
MyTimer.schedule(new TimerTask() {
#Override
public void run() {
Log.i(Fragment.TAG, "Message Test");
}
}, Delay, Delay);
}
}.start();
return START_NOT_STICKY;
}
Related
I want a best consistent solution to call an api to update current location in every 2 minutes on Nougat and higher version. The process should not be terminated even when the app is killed or closed.
Thanks in advance
Create a services:
public class MyServices extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
startService(new Intent(this,MyServices.class));
Timer t = new Timer();
final Handler handler = new Handler();
// Timer task makes your service will repeat after every 20 Sec.
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
//Do network call here
}
});
}
};
//Starts after 20 sec and will repeat on every 20 sec of time interval.
t.schedule(doAsynchronousTask, 3000,3000); // 20 sec timer
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
}
Register the service in menifest
<service android:name=".MyServices" />
Start the service in your activity
Intent intent = new Intent(this, MyServices.class);
startService(intent);
if version > N use this
startForegroundService(intent);
Create a service and update from there.
Service will not stop after closing the application but it will get stopped if the application is force stopped.
And also if your app goes to doze mode your app cannot use Internet or GPS service from the background.
You should check out WorkManager to schedule any kind of work you want your app to do.
I'm trying to learn Android Service, I'm very noob. I'm creating a service which will run even after the app is destroyed but when I terminate the App, the Service gets terminated too. I'm trying to make a NotificationService, below is my code that I just tried working with Service.
Manifest:
<service
android:name="com.test.testworks.MyService"
/>
Starting Service via Button Click:
startService(new Intent(this, MyService.class));
Service class MyService.class:
public class MyService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
/* 1. *//*ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
// This schedule a runnable task every 2 minutes
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
}
}, 0, 10000, TimeUnit.SECONDS);*/
/* 2. *//*final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Toast.makeText(MyService.this, "suiubsibddubsuidv", Toast.LENGTH_LONG).show();
handler.postDelayed(this, 10000); //now is every 2 minutes
}
}, 10000);*/
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
I'm checking on my phone where the other Services are running and when I terminate the App, the Service terminates also.
On some phones, you need to add your app explicitly to the list of apps that are allowed to run in the background. Otherwise, Android will not restart your app if it is killed for whatever reason. There should be a settings page which lists installed apps and allows you to add them to this list. It is called "protected apps" on some devices. Especially devices from Xiaomi, LG, Huawei have this feature, but also other phones.
I'm making a simple alarm clock app and now I'm having problem with the service which checks if the current time matches the set time and starts another activity. Here's the code:
#Override
public int onStartCommand(Intent intent, int flags, int startID){
hourSet = intent.getIntExtra("hourSet", 0);
minuteSet = intent.getIntExtra("minuteSet", 0);
checkTime();
return START_STICKY;
}
private void checkTime(){
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
time.setToNow();
currentHour = time.hour;
currentMinute = time.minute;
if(currentHour == hourSet && currentMinute == minuteSet){
Intent i = new Intent(AlarmService.this, AlarmTime.class);
startActivity(i);
cancel();
}
}
}, 0, UPDATE_INTERVAL );
}
I have debugged the service, everything is fine until the if statement. When the current time matches the set time, the app crashes.
So how to fix this ?
Why people dont include catLog?
Problem is you are trying to start activity on service task, which is not possible, but if you add magic code like
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
before startActivity call, it starts on the new task and everything should work just fine :)
In my activity I have a private BroadcastReceiver, when triggered, should update the UI after some ms. In my Activity I have:
private BroadcastReceiver broadCastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("BroadCastReciever: ", "UpdateCaseList");
update.RefreshCaseList();
}
};
This BroadcastReceiver is beeing triggered from a Service:
#Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
#Override
public void onStart(Intent intent, int startId) {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 0);
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
handler.postDelayed(this, 10000); // 10 seconds
sendUpdateToUiThread();
}
};
private void sendUpdateToUiThread() {
sendBroadcast(intent);
}
I guess that the onStart method is being called when I Register BroadcastReceiver in my OnResume() method. I also unregister the BroadcastReceiver in onPause.
My intention is that this should sent a notification to the Activity, every 10 seconds. Once I start the application, my service will notify the Activity every 10 seconds, as planned. The problem is when I leave the Activity and return back, it doesn't post a notification to the activity every 10 seconds, but just at a random time. I can see in LogCat that this randomness spamming occurs every 4, 6, 3, 8, 6 seconds and so on. Why on earth this behaviour?
According to postDelayed documentation
the Runnable is called after millisecods elapsed and
Time spent in deep sleep will add an additional delay to execution.
So some randomness is by design. So I would expect the Runnable called after more than 10000 ms in your case.
I was searching over the internet for last 2 days but I couldn't find any tutorial helpful. I have created a service and I am sending a notification in status bar when the service starts. I want that service to stop after showing the notification and start it again after 5 minutes. Please let me know if it is possible and provide me some helpful tutorials if you have any. I heard of TimerTask and AlarmManager and I tried to use them as well but I wasn't able to get the desired result.
EDIT: I need the service to be started every 5 minutes even if my application is not running.
You do not want to use a TimerTask since this depends on your application running continuously. An AlarmManager implementation makes it safe for your application to be killed between executions.
Stating that you tried to use AlarmManager but did not get the desired result is not a helpful statement, in that it tells no one how to help you to get it right. It would be much more useful to express what happened.
http://web.archive.org/web/20170713001201/http://code4reference.com/2012/07/tutorial-on-android-alarmmanager/ contains what appears to be a useful tutorial on AlarmManager. Here are the salient points:
1) Your alarm will cause an Intent to fire when it expires. It's up to you to decide what kind of Intent and how it should be implemented. The link I provided has a complete example based on a BroadcastReceiver.
2) You can install your alarm with an example such as:
public void setOnetimeTimer(Context context) {
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(ONE_TIME, Boolean.TRUE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
}
Below I have provided three files, MainActivity.java for start service, Second file MyService.java providing service for 5 Minute and Third is manifest file.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, MyService.class)); //start service which is MyService.java
}
}
MyService.java
public class MyService extends Service {
public static final int notify = 300000; //interval between two services(Here Service run every 5 Minute)
private Handler mHandler = new Handler(); //run on another Thread to avoid crash
private Timer mTimer = null; //timer handling
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
if (mTimer != null) // Cancel if already existed
mTimer.cancel();
else
mTimer = new Timer(); //recreate new
mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify); //Schedule task
}
#Override
public void onDestroy() {
super.onDestroy();
mTimer.cancel(); //For Cancel Timer
Toast.makeText(this, "Service is Destroyed", Toast.LENGTH_SHORT).show();
}
//class TimeDisplay for handling task
class TimeDisplay extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast
Toast.makeText(MyService.this, "Service is running", Toast.LENGTH_SHORT).show();
}
});
}
}
}
AndroidManifest.xml
<service android:name=".MyService" android:enabled="true" android:exported="true"></service>
Create a Timer object and give it a TimerTask that performs the code you'd like to perform.
Timer timer = new Timer ();
TimerTask hourlyTask = new TimerTask () {
#Override
public void run () {
// your code here...
}
};
// schedule the task to run starting now and then every hour...
timer.schedule (hourlyTask, 0l, 1000*60*60); // 1000*10*60 every 10 minut
The advantage of using a Timer object is that it can handle multiple TimerTask objects, each with their own timing, delay, etc. You can also start and stop the timers as long as you hold on to the Timer object by declaring it as a class variable or something.