I want to know how could I setup my application to update its details via API post every after 15 minutes. Right now, I knos how to use get and use a thread in order to create a loader for it while accessing the API.
Here's how I do it:
private int authenticateLogin()
{
EditText user = ((EditText)findViewById(R.id.username));
EditText pass = ((EditText)findViewById(R.id.password));
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
String username = user.getText().toString(), password = pass.getText().toString();
String URL = "MyUrl";
String authData = "Basic " + Base64.encodeToString((username + ":" + password).getBytes(), Base64.NO_WRAP);
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(URL);
httpget.setHeader("Authorization", authData);
HttpResponse response = null;
try {
response = httpclient.execute(httpget);
StatusLine sl = response.getStatusLine();
int statCode = sl.getStatusCode();
if (statCode == 200) {
String entityStringDrivers = EntityUtils.toString(response.getEntity());
Intent i = new Intent(Login.this,DriverLogin.class);
i.putExtra("stringDrivers", entityStringDrivers);
startActivity(i);
return 100;
}
else
{
user.setText("");
pass.setText("");
Toast.makeText(getBaseContext(), "Unauthorized Login", Toast.LENGTH_SHORT).show();
return 100;
}
} catch (Exception e) {
// Auto-generated catch block
e.printStackTrace();
return 100;
}
finally {
}
}
I want to to know how should I do it when posting and do it in background. I don't know where to start specially with the every 15 minutes POST. Any ideas? Thanks!
You can check this out , and use Intent Services to run in the back ground.
android timer, For intent servicse check it out Intent Services
Use a handler for the timer as follows:
In the snippet call startTimeReqTask() to start your timer.
private Handler m_handler = new Handler();
....
Runnable m_handlerTask = new Runnable() {
#Override
public void run() {
m_handler.postDelayed(m_handlerTask, 900000); // 15 minutes
new authenticateLoginTask().execute(); // POST (your asynctask)
}
};
private void startTimeReqTask() // start timer
{
m_handlerTask.run();
}
private void stopTimeReqTask() // stop time
{
m_handler.removeCallbacks(m_handlerTask);
}
And use AsyncTask authenticateLoginTask for doing it background.
If you want to do this background, create a Service and start it in your main activity's onCreate or some BroadcastReceiver
eg:( You need to add try-catch or other sort of protective code)
public class MyService extends Service {
#Override
public void onStartCommand(Intent intent, int flags, int startId) {
//Use intent to pass your username and password here
//start a PostThread here.
}
private class PostThread extends Thread {
private static final int INTERVAL = 15 * 60 * 1000L;
private boolean canceled = false;
#Override
public void run() {
while (!canceled) {
Post();
Thread.sleep(INTERVAL); // or you can use a Timer to trigger this
}
}
public void interrupt() { canceled = true; super.interrupt();}
}
}
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
// call your api method here
}
});
}
}, 0, /*here define your internal*/);
// when you no longer required this api call just call "cancel" method of timer
Related
I want to load a url in the background after every 30 seconds (as a Service) in my app. I have to load url in my service class, as it has no layout, so webview is not suitable for this. What should I use to load url in background even when the app is closed ?
MyService.java class
public class MyService extends Service {
Activity activity ;
Handler handler = new Handler();
Runnable runnable;
int delay = 7*1000;
public MyService(Activity activity){
this.activity = activity ;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler.postDelayed( runnable = new Runnable() {
public void run() {
loadURL();
handler.postDelayed(runnable, delay);
}
}, delay);
return START_STICKY ;
}
#Override
public void onDestroy() {
}
public void loadURL(){
try{
String id = activity.getIntent().getStringExtra("ID");
URL url = new URL("http://localhost/att.php?id=" + id + "&status=&submit=Insert");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
} catch (Exception e){
Toast.makeText(this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
You can use the new WorkManager.
Basically you create a Worker class that extends from one of these:
Worker
CoroutineWorker
RxWorker
ListenableWorker
Then you declare it like this:
val mWorker = PeriodicWorkRequestBuilder<Worker>(15, TimeUnit.MINUTES)
.addTag(WORK_TAG)
.setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
.build()
And then enqueue unique work so that work manager doesn't start more of the same task:
WorkManager.getInstance(context)
.enqueueUniquePeriodicWork(WORK_TAG, ExistingPeriodicWorkPolicy.KEEP, locationWorker)
Using your code when you extend your Worker class to for example ListenableWorker, you override a startWork() function and in the body run:
handler.postDelayed( runnable = new Runnable() {
public void run() {
loadURL();
handler.postDelayed(runnable, delay);
}
}, delay);
Hi people I am getting problem in getting my latest JSON value after every 10 seconds. I have developed this code and now I am stucked in this. When I run this code it shows the value after second and did not get updated the second time. I have implemented the handler but it is also not working here.
public class MainActivity extends AppCompatActivity {
TextView a,b,c,d,e,f,g,h;
String result = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
a=(TextView) findViewById(R.id.a);
b=(TextView) findViewById(R.id.b);
c=(TextView) findViewById(R.id.c);
DownloadTask task = new DownloadTask();
task.execute("https://api.thingspeak.com/channels/12345/feeds.json?results=1");
}
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(final String result) {
super.onPostExecute(result);
new Handler().postDelayed(new Runnable() {
public void run() {
search(result);
}
}, 10000);
}
public void search(String result){
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray weatherInfo = jsonObject.getJSONArray("feeds");
JSONObject legsobject = weatherInfo.getJSONObject(0);
a.setText(legsobject.getString("field1"));
b.setText(legsobject.getString("field2"));
c.setText(legsobject.getString("field3"));
}catch (JSONException e) {
e.printStackTrace();
}
}
}
}
I want to get my value refreshed after every 10 seconds and it is not doing it.
Can any one guide me that how can I make it possible.
Try this code ..
private final int INTERVAL_MILLI = 60000; // define your time..
Handler mHandler;
#Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(SyncData);
}
Runnable SyncData = new Runnable() {
#Override
public void run() {
// call your code here..
Log.e(TAG, "SyncData1: " + new java.sql.Date(System.currentTimeMillis()).toString());
final String Token = AppSetting.getStringSharedPref(mContext, Constants.USER_KEY_TOKEN, "");
if (!TextUtils.isEmpty(Token) && !CommonUtils.isServiceRunning(mContext)) {
Log.e(TAG, "SyncData2: " + new java.sql.Date(System.currentTimeMillis()).toString());
startService(new Intent(mContext, SyncService.class));
}
callSyncData();
}
};
public void callSyncData()
{
mHandler.postDelayed(SyncData, INTERVAL_MILLI);
}
and callSyncData() method called in activity onCreate method and run method.
To begin with, I don't like the idea of hammering the server with a request every 10s even nothing changes really. If you can move to a solution with notification from the server it will be better.
If you still need to do that you can use three common solutions to fire a repeating task with a period:
1- Use Timer & TimerTask
For this solution you need to declare your timer task to run:
final TimerTask repeatedTask = new TimerTask() {
#Override
public void run() {
//you stuff here
}
};
Then you need to schedule your task using a timer like below:
final Timer timer = new Timer();
timer.scheduleAtFixedRate(repeatedTask,0, 10 * 1000);
==> Don't forget to call timer.cancel(); when your are done (or activity pause, stop, ...)
2- Use ScheduledThreadPoolExecutor
This is basically a replacing for Timer task starting android 5.0. The setup is more easy and straightforward like below:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
//you stuff here
}
}, 0, 10, TimeUnit.SECONDS);
==> don't forget to shutdown your executor when you are done by calling : executor.shutdown();
3- Use Handler
The tip here is to repost the runnable after downloading your json like mentionned in the previous answer.
You can use TimerTask and Timer. If you need to update UI components you should run it on UI thread.
final TimerTask yourRepeatedTask = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
//your code here
}
});
}
};
And the Timer which schedules your task in a given interval. In your case, it is 10s. Make sure to give the interval in milliseconds.
final Timer timer = new Timer();
timer.scheduleAtFixedRate(yourRepeatedTask ,0, 10 * 1000);
At last call timer.cancel() to stop the timer.
#Override
protected void onPause() {
if (timer != null) {
timer.cancel();
}
super.onPause();
}
Every time I`m trying to finish an activity inside of a timer method, the activity comes back alive over and over again.
I running this activity:
public class PlayerNoAdmin extends ActionBarActivity {
Timer myTimer; boolean isAdmin;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player_no_admin);
Intent oldIntent = getIntent();
if (oldIntent != null && oldIntent.hasExtra("THE_LIST")){
songs = oldIntent.getParcelableArrayListExtra("THE_LIST");
id = oldIntent.getIntExtra("ID",0);
listId = oldIntent.getIntExtra("LIST_ID",0);
isAdmin = oldIntent.getBooleanExtra("IS_ADMIN",false);
}
//update the list every k seconds
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
TimerMethod();
}
}, 0, k_time2Update);
}
private void TimerMethod() {
//This method is called directly by the timer
//and runs in the same thread as the timer.
//We call the method that will work with the UI
//through the runOnUiThread method.
this.runOnUiThread(Timer_Tick);
}
private Runnable Timer_Tick = new Runnable() {
public void run() {
//Here check for update in the list every 30 seconds and send the new location
String url = getRunUrl();
new TaskMusicPlay().execute(url);
}
};
private class TaskMusicPlay extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
String jsonResult = null;
try {
String url = params[0];
TestMain client = new TestMain();
jsonResult = client.doGetRequest(url);
} catch (IOException e) {
e.printStackTrace();
}
return jsonResult;
}
#Override
protected void onPostExecute(String aVoid) {
super.onPostExecute(aVoid);
checkIfNew(aVoid);
}
private void checkIfNew(String result) {
try {
JSONObject object = new JSONObject(result);
String temp = object.getJSONObject("info").getString("isAdmin");
isAdmin = (temp.equals("true"));
if (isAdmin) {
Intent intent = new Intent(getApplication(),YouTubePlayer.class);
intent.putExtra("THE_LIST", songs);
intent.putExtra("ID", id);
intent.putExtra("LIST_ID",listId);
intent.putExtra("IS_ADMIN",isAdmin);
startActivity(intent);
finish();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
At the end, I succeeded to move to the YouTubePlayer activity, but every few seconds the app returns to the code of this activity (and then executes again the startActivity call and goes back to YouTubePlayer) and that's going on and on.
Your Timer is periodically calling the player to start over and over again.
You must make a cancel() call to the Timer if it is no longer needed so you prevent it from holding a reference for your activity and thus preventing from being removed from the backstack and GC.
http://developer.android.com/reference/java/util/Timer.html
And your Timer is not running on the same thread as it's code because the timer thread iis another Thread and the Code in the Timer is running on UI. You can check it out by adding some logs in the Timer's run method outside of the runOnUIThread() and inside of it.
Hi currently i have the following code which utilizes Asycn Task and Timer.
My async task is basically trying to send a HTTP GET method from a URL where the response from the server could varies depending on connection and load.
What i would like to do is to have a timed async task. Where, it will schedule an AsyncTask every X second BUT if there is currently an Async Task in progress i would have to kill it first. Then start a new one.
Here is the code that i have at the moment:
private static boolean running = false;
Timer myTimer;
protected void onCreate(Bundle savedInstanceState) {
/* REST OF CODE OMITTED */
MyTimerTask myTask = new MyTimerTask();
myTimer = new Timer();
myTimer.schedule(myTask, 0, 10000);
}
/* REST OF CODE OMITTED */
private class MyTimerTask extends TimerTask {
public void run() {
if(!running){
Log.i("TAG", "NEW TIMER STARTED.");
RetrieveChatMessage task = new RetrieveChatMessage();
task.execute();
running = true;
}else{
running = false;
}
}
}
private class RetrieveChatMessage extends AsyncTask<String, Void, ArrayList<Chat>> {
#Override
protected ArrayList<Chat> doInBackground(String... params) {
// TODO Auto-generated method stub
ArrayList<Chat> cList = null;
String jResult = null;
Log.i("TAG", "RETRIEVING CHAT MESSAGE");
try {
jResult = ((new HttpRetriever())).getChatList(mAccount.email, mAccount.passwd);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(jResult != null){
Log.i("TAG", "JSON DATA: " + jResult);
cList = (new ChatHandlers()).getChatList(jResult);
}else{
cList = null;
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("TAG", "JSON Exception " + e.toString());
}
return cList;
}
#Override
protected void onPostExecute(final ArrayList<Chat> result) {
Log.i("TAG", "ON POST EXECUTE");
if(result != null){
// Do something here
}
}
}
To be honest the code above works with slight issues:
1. It seems to execute the Async randomly, instead of every 10 seconds.
2. When i go to another activity, somewhat it prevents other Async task from doing its job (Which is also trying to retrieve JSON response from server).
I am not too worried about the later problem (and that is not the question i am asking). I just would like to know how to have a proper timed Async Task. Can anyone point me to a direction.
Thank you.
EDIT #1:
after reading #thepoosh comment's i tried the following (i put it in onCreate):
scheduleTaskExecutor= Executors.newScheduledThreadPool(5);
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
// Parsing RSS feed:
// myFeedParser.doSomething();
Log.w("THUMBQOO", "NEW TASK STARTED");
retrieveChat();
}
}, 0, 15, TimeUnit.SECONDS);
Result: i have a consistent execution of Task. However, it seems that retrieveChat(); is never be called after the first execution.
Actually AsyncTask is not used for long operations .Check Here
You should use a Thread that uses a interface to notify UI or you can simply use a Handler which is the most Preffered way in android. Simply you can do a task repeatedly for every 10 seconds by
handler.postDelayed(new Runnable() {
#Override
public void run() {
// do work
handler.postDelayed(10000);
}
}, 10000);
Declare a Handler object to maintain future task executor...
private Handler mTimerHandler = new Handler();
Write a thread which will execute your future task...
private Runnable mTimerExecutor = new Runnable() {
#Override
public void run() {
//write your code what you want to do after the specified time elapsed
if(!running){
RetrieveChatMessage task = new RetrieveChatMessage();
task.execute();
running = true;
}else{
running = false;
}
}
};
Call your future tast executor with time using hanlder...
mTimerHandler.postDelayed(mTimerExecutor, 10000);
You can cancle your future task executor any time by this...
mTimerHandler.removeCallbacks(mTimerExecutor);
I am not sure if this is a very good way of accomplishing this (my answer here below) :
Use a Handler, create a HandlerThread and keep posting messages to this handler.
For the handlers "handleMessage" method, you can do your task and again send a message back to the MessageQueue.
HandlerThread thread = new HandlerThread(<name>);
thread.start();
Looper looper = thread.getLooper();
CustomHandler handler = new CustomHandler(looper);
// The CustomHandler class
class CustomHandler extends Handler {
public CustomHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
//Do your operation here
handler.sendEmptyMessageDelayed(msg, <delayTime>);
}
}
This question already has answers here:
Accessing UI thread handler from a service
(7 answers)
Closed 9 years ago.
I wanted to make a service which will check my SMS in every 20 sec if there are any unread SMS then send it to my website then mark as read for posting data to website I used asynctask and it worked fine when I tried manually (by making button click type app)
but in side service I cant define
runOnUiThread(new Runnable() {
#Override
public void run() { new MyAsyncTask().execute(sender,time,message);}
});
it is unable to identify and asks me to define runOnUiThread
Is there any way to call my asynctask from the place where I am calling in below code
public class TestService extends Service {
String sender = null;
String time = null;
String message = null;
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
Toast.makeText(getApplicationContext(), "Service Created", 1).show();
super.onCreate();
}
#Override
public void onDestroy() {
Toast.makeText(getApplicationContext(), "Service Destroy", 1).show();
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(), "Service Running ", 1).show();
new Thread(new Runnable() {
public void run() {
ContentValues values = new ContentValues();
Uri mSmsinboxQueryUri = Uri.parse("content://sms/inbox");
String[] columns = new String[] { "_id", "thread_id",
"address", "person", "date", "body", "type" };
Cursor cursor1 = getContentResolver().query(mSmsinboxQueryUri,
null, "read=0", null, null);
DateFormat formatter = new SimpleDateFormat(
"dd/MM/yyyy hh:mm:ss.SSS");
Calendar calendar = Calendar.getInstance();
if (cursor1.getCount() > 0) {
cursor1.moveToFirst();
do {
// Retrieving sender number
sender = (cursor1.getString(cursor1
.getColumnIndex(columns[2])).toString());
// Retriving time of reception
long ms = cursor1.getLong(cursor1
.getColumnIndex(columns[4]));
calendar.setTimeInMillis(ms);
time = formatter.format(calendar.getTime()).toString();
// Retriving the message body
message = (cursor1.getString(cursor1
.getColumnIndex(columns[5])).toString());
runOnUiThread(new Runnable() {
#Override
public void run() {
new MyAsyncTask()
.execute(sender, time, message);
}
});
} while (cursor1.moveToNext());// end of while
}// end of if
// set as read
values.put("read", true);
getContentResolver().update(Uri.parse("content://sms/inbox"),
values, null, null);
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
private class MyAsyncTask extends AsyncTask<String, Integer, Double> {
#Override
protected Double doInBackground(String... params) {
postData(params[0], params[1], params[2]);
return null;
}
protected void onPostExecute(Double result) {
// pb.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(), "command sent",
Toast.LENGTH_LONG).show();
}
protected void onProgressUpdate(Integer... progress) {
// pb.setProgress(progress[0]);
}
public void postData(String sender, String time, String message) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(
"http://www.mysite.co.nf/reciever.php");
try {
// Add your data
List<NameValuePair> nameValuePairs =
new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("sender", sender));
nameValuePairs.add(new BasicNameValuePair("time", time));
nameValuePairs.add(new BasicNameValuePair("message", message));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {} catch (IOException e) {}
}
}
}
Service does not have a method called runOnUiThread(). You're assuming that the method from Activity is also defined for a Service, but it's not.
Solution, just define a method that does exactly that. Here's a simplified example, the rest of your code would remain unchanged.
import android.os.Handler;
public class TestService extends Service {
Handler handler;
#Override
public void onCreate() {
// Handler will get associated with the current thread,
// which is the main thread.
handler = new Handler();
super.onCreate();
}
private void runOnUiThread(Runnable runnable) {
handler.post(runnable);
}
}
For more info, see the docs for Handler. It's used to dump some work onto a specific thread. In this case, the Handler gets associated with the UI thread, since the UI thread always calls Service.onCreate().