I use Volley library to connect with server in my app. Now, I have to send request in background every 5 minutes also when app is not running (killed by user). How should I do it? With background services, AlarmManager (Google says that it isn't good choice for network operations) or something else?
Or maybe SyncAdapter will be good for it?
You can use a TimerTask with scheduleAtFixedRate in a service class to achieve this, here is an example of Service class, you can use it
public class ScheduledService extends Service
{
private Timer timer = new Timer();
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onCreate()
{
super.onCreate();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
sendRequestToServer(); //Your code here
}
}, 0, 5*60*1000);//5 Minutes
}
#Override
public void onDestroy()
{
super.onDestroy();
}
}
You can use sendRequestToServer method to connect with the server.
Here is the manifest declaration of the Service.
<service android:name=".ScheduledService" android:icon="#drawable/icon" android:label="#string/app_name" android:enabled="true"/>
To start the service from MainActivity,
// use this to start and trigger a service
Intent i= new Intent(context, ScheduledService.class);
context.startService(i);
I prefer to use Android Handler because it is executes in UI Thread by default.
import android.os.Handler;
// Create the Handler object (on the main thread by default)
Handler handler = new Handler();
// Define the code block to be executed
private Runnable runnableCode = new Runnable() {
#Override
public void run() {
sendVolleyRequestToServer(); // Volley Request
// Repeat this the same runnable code block again another 2 seconds
handler.postDelayed(runnableCode, 2000);
}
};
// Start the initial runnable task by posting through the handler
handler.post(runnableCode);
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.
In my android app i have one service which calls some webservices after a fix interval.
App is running perfectly in foreground and refresh data,but when user exit from app and use some other app then my app force close after many times.
Why this app force close while running in background.
Code that i was using for start service -
msgIntent = new Intent(mContext, MyBackgroundService.class);
startService(msgIntent);
and inside onDestroy() of my main activity i have following code to stop service-
if(msgIntent!=null){
stopService(msgIntent);
}
background service call some async task and each aync task onPostExecute() method execute some insert statement in database.
i am not geting why this force close occure.
Please give your comments.
Thanks in advance.
My Service Code
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
callAsynchronousTask();
return Service.START_NOT_STICKY;
}
#Override
public void onCreate() {
mContext = this;
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void callAsynchronousTask() {
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
callWebservice();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
timer.schedule(doAsynchronousTask, START_DELAY, DELAY);
}
Actually the problem is here
if(msgIntent!=null){
stopService(msgIntent);
}
in your onDestroy(). Because when you close your application so this above code gets called which is closing your service.
And after closing service again you are trying to insert data by calling service + web service. Hence, there is no service object thats why it gets crashed.
To handle this scenario, you need to comment above code which is in onDestroy() & then check/run it, will solve your problem. & there you need to stop your service by other ways. Go step by step.
you stop the service at onDestroy() method. but services are not depend the activity. So try to neglect the stop service.
(or)
try
{
//stop service code
}
catch(Exception e)
{
}
try this.
I'm designing my first Android app.
This app consist in several Runnable that do some stuff. Initially I made this Runnable to be execute by a Thread (a Thread for each Runnable). Each Runnable is also Observable, so it can notify changes to Activity. User click on a start button, one or more Runnable starts, them do their job notifying gui during execution and then stops. All works fine.
First question: Is that approach the right one? In order to answer this question please keep reading.
I need two other things in my app:
to be sure that execution of my jobs doesn't stops, even if user goes away from my app to do something else;
to plan the execution of my Runnable that has to start and execute in background. Example: user decides that wants a "job" to be execute everyday at 16:00.
I've seen that I can do that with an AlarmManager and Service.
Second question: I need a Service that can manage several Runnable asynchronously, so when AlarmManager starts I ask this Service to do the requested job; I'll also modify the first part of application: instead of Thread I'll use this Service, so I can be sure that execution doesn't stop.
What kind of Service I need? IntentService can do this job?
It's right to proceed in this way? There is a better solution?
Can you give me some example of how I can implement all that?
I hope that I explained clearly my situation, otherwise I'll try to do it better.
Regards
First question: Is that approach the right one?
No, you should implement and run your Runnables in Threads in a Service.
An IntentService would be your best option if you don't require your Service to handle multiple requests simultaneously. If you start a Service it will keep running in the background even if the Activity that started it goes to the background or stops.
A Runnables can send a broadcast indicating a UI update is needed. The Activity should register a BroadcastReceiver to listen to the broadcast message and update the UI accordingly.
You can use an AlarmManager to schedule the execution of your jobs as you indicated. One way to do it is to schedule the AlarmManager to send a broadcast to be received by your IntentService which acts upon it by running the appropriate job.
Here is an example that combines all that:
Here is the IntentService
public class MyIntentService extends IntentService {
public static final String ACTION_START_JOB = "com.mycompany.myapplication.START_JOB";
public static final String ACTION_UPDATE_UI = "com.mycompany.myapplication.UPDATE_UI";
private final IBinder mBinder = new MyBinder();
// You can have as many Runnables as you want.
Runnable run = new Runnable() {
#Override
public void run() {
// Code to run in this Runnable.
// If the code needs to notify an Activity
// for a UI update, it will send a broadcast.
Intent intent = new Intent(ACTION_UPDATE_UI);
sendBroadcast(intent);
}
};
public MyIntentService() {
super("MyIntentService");
}
#Override
public void onCreate() {
// You need to register your BroadcastReceiver to listen
// to broadcasts made by the AlarmManager.
// The BroadcastReceiver will fire up your jobs when these
// broadcasts are received.
IntentFilter filter = new IntentFilter(ACTION_START_JOB);
registerReceiver(jobBroadcastReceiver, filter);
}
#Override
public void onDestroy() {
// You should unregister the BroadcastReceiver when
// the Service is destroyed because it's not needed
// any more.
unregisterReceiver(jobBroadcastReceiver);
}
/**
* This method is called every time you start this service from your
* Activity. You can Spawn as many threads with Runnables as you want here.
* Keep in mind that your system have limited resources though.
*/
#Override
protected void onHandleIntent(Intent intent) {
Intent intentFireUp = new Intent();
intentFireUp.setAction(ACTION_START_JOB);
PendingIntent pendingIntentFireUpRecording = PendingIntent
.getBroadcast(MyIntentService.this, 0, intentFireUp, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
int year = 2013, month = 5, day = 10, hourOfDay = 7, minute = 13, second = 0;
cal.set(year, month, day, hourOfDay, minute, second);
long startTime = cal.getTimeInMillis() + 5 * 60 * 1000; // starts 5
// minutes from
// now
long intervalMillis = 24 * 60 * 60 * 1000; // Repeat interval is 24
// hours (in milliseconds)
// This alarm will send a broadcast with the ACTION_START_JOB action
// daily
// starting at the given date above.
alarm.setRepeating(AlarmManager.RTC_WAKEUP, startTime, intervalMillis,
pendingIntentFireUpRecording);
// Here we spawn one Thread with a Runnable.
// You can spawn as many threads as you want.
// Don't overload your system though.
new Thread(run).run();
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// Depending on your implementation, you may need to bind
// to this Service to run one of its methods or access
// some of its fields. In that case, you will need a Binder
// like this one.
public class MyBinder extends Binder {
MyIntentService getService() {
return MyIntentService.this;
}
}
// Spawns a Thread with Runnable run when a broadcast message is received.
// You may need different BroadcastReceivers that fire up different jobs.
BroadcastReceiver jobBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
new Thread(run).run();
}
};
}
And here is the Activity
public class MyActivity extends Activity {
Service mService;
boolean mBound = false;
ToggleButton mButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (ToggleButton) findViewById(R.id.recordStartStop);
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (mButton.isChecked()) {
Intent intent = new Intent(MyActivity.this,
MyIntentService.class);
startService(intent);
}
}
});
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(MyIntentService.ACTION_UPDATE_UI);
registerReceiver(uiUpdateBroadcastReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(uiUpdateBroadcastReceiver);
}
BroadcastReceiver uiUpdateBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Here goes the code to update your User Interface
}
};
ServiceConnection myServiceConnection = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
mBound = false;
}
// If you need
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyIntentService mService = ((MyBinder) service).getService();
mBound = true;
}
};
}
And don't forget to add the Service definition in your AndroidManifest.xml file:
<manifest ... >
...
<application ... >
<service android:name=".MyIntentService" />
...
</application>
</manifest>
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.
I am using intent service to periodically send queries to my server to check if there are any updates. In the intent service there is a timer task, which queries the server every 3 seconds, This starts running when the application is closed.
Now when the user again comes back in to the application I want to stop the service.
How should I do this? how can an intent service which is doing timertask be stopped form another activity?
Please give suggestions for Intent Service because that is what I am using.
Maybe it will be better to use just service instead of IntentService.
public class UpdateService extends Service {
public class LocalBinder extends Binder {
public void startUpdates() {
// start updateThread if it not started, or
// notify about resuming probes
}
public void stopUpdates() {
// make updateThread to wait, until startUpdates
// called again.
//
// REMEMBER this method can be called when startUpdates didnt called.
}
}
// For simplicity we will use local binder.
private final IBinder binder = new LocalBinder();
#Override
public IBinder onBind(Intent intent) {
return binder;
}
private Thread updateThread = new Thread() {
#Override
public void run() {
while (true) {
// Do updates. Sleep/awake managment.
}
}
};
}
Just bind to service (with AUTO_CREATE_FLAG) and start updates when you are need.
When your activity shows just bind again to service and make it stop updates.
First of all,IntentService cannot be stopped.It will stop itself only after it has completed all the tasks present in its queue.Hence,IntentService should not be used here.