Android work in background - java

I got 3 activities ( A , B ,C ) and a service that I call to check if I got new messages from DB. It's a HTTP request . I need to make the request each 15 sec.
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(15000);
runOnUiThread(new Runnable() {
#Override
public void run() {
// Here i call
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
How to make it work when i am changing activities ?

Option: Consider changing setup to have three fragments as your original activities, and a MainActivity that controls the repeat polling for messages to DB, as well as controlling the fragments.

#SuppressLint("SimpleDateFormat")
public class AlarmService extends Service {
private PendingIntent pendingIntent;
Handler mHandler;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
}
public void f() {
Toast t = Toast.makeText(this, "Service is still running",
Toast.LENGTH_SHORT);
t.show();
};
}
#Override
#Deprecated
public void onStart(Intent intent, int startId) {
Toast t = Toast.makeText(this, "Service started", Toast.LENGTH_SHORT);
t.show();
// TODO Auto-generated method stub
super.onStart(intent, startId);
mHandler = new Handler();
Runnable r = new Runnable() {
#Override
public void run() {
f();
mHandler.postDelayed(this, 20000);
}
};
mHandler.postDelayed(r, 20000);
}
}
and in manifest use this
<service android:name="com.example.yourservice"></service>

Related

Android - Explanation about AsyncTask in Service class

I've a task to running service every 3 second, the service will execute asynctask to checking sqlite and sending data into server
Code of myService.class
/* import foo.foo.foo */
public class myService extends Service {
public Runnable mRunnable = null;
private boolean mRunning = false;
Handler mHandler = new Handler();
IBinder mBinder = new LocalBinder();
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public myService getServerInstance() {
return myService.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Service"," onstart kepanggil ga?");
mRunnable = new Runnable() {
#Override
public void run() {
Log.d("Service","SERVICE RUN");
SharedPreferences pref = getSharedPreferences("wit_player_shared_preferences", MODE_PRIVATE);
String servcheck = pref.getString("serviceChecker", null);
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
int countFlagAuditID = db.getCountFlagAuditID();
int countNeedToSend = db.getCountContact();
if (countNeedToSend > 0){
Log.d("countNeedToSend : ", String.valueOf(countNeedToSend));
sending a = new sending();
try {
if(servcheck.equals("no")){
Log.d("Service","SERVICE TRY CALL SENDING");
a.execute().get();
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
if (countFlagAuditID > 0){
Log.d("countFlagAuditID : ", String.valueOf(countFlagAuditID));
if(servcheck.equals("no")){
Log.d("Service","SERVICE TRY CALL SENDGET");
sendget b = new sendget();
b.execute();
}
}
db.close();
mHandler.postDelayed(mRunnable, 3 * 1000);
}
};
mHandler.postDelayed(mRunnable, 3 * 1000);
return START_STICKY;
}
//async task
private class sending extends AsyncTask<Void, Void, String >
{
#Override
protected void onPreExecute() {
Log.i("SENDING", "start sending");
SharedPreferences pref = getSharedPreferences("wit_player_shared_preferences", MODE_PRIVATE);
pref.edit().putString("serviceChecker", "yes").commit();
if (serv.equals("yes")){
Log.i("stop service", "service di stop");
stopSelf();
}
}
#Override
protected String doInBackground(Void... params) {
//send data to server
}
#Override
protected void onPostExecute(String result) {
SharedPreferences pref = getSharedPreferences("wit_player_shared_preferences", MODE_PRIVATE);
pref.edit().putString("serviceChecker", "no").commit();
}
}
private class sendget extends AsyncTask<Void, Void, String >
{
//execute post to server
}
}
I've a list of question about the code above:
to let my service run every 3sec I need to declare twice of mHandler.postDelayed(mRunnable, 3 * 1000);, if I'm declare the code just one, the service will run once, why it can be like that?
on sending asynctask I've add stopSelf() on onPreExecute() that mean the service will stop, but why doInBackground() task keep run?
Try to use timer instead of handler
private final Timer mTimer = new Timer();
mTimer.scheduleAtFixedRate(new LocationUpdateTask(), 0, 3000);
private class LocationUpdateTask extends TimerTask {
#Override
public void run() {
try {
//Do your stuff
} catch (Exception e) {
// TODO: handle exception
} catch (ExceptionInInitializerError in) {
}
}
}

Passing the string value to background service

Please guide me in this. Appreciate all your help.
My background service is toasting ABC
//-------------------String displayingText = "ABC";-----------------
And I have two strings, ABC and DEF declared in mainactivity.java
How do I pass the value displayingText from main activity to this service.
How do I change the displayingText to DEF after the toast ABC finished.
MyService.Java
public class MyService extends Service {
public static final long INTERVAL=3000;//variable to execute services every 5 second
private Handler mHandler=new Handler(); // run on another Thread to avoid crash
private Timer mTimer=null; // timer handling
//the get intent dont work. where or how should i put it?
Intent myIntent = getIntent();
if (myIntent !=null && myIntent.getExtras()!=null)
String value = myIntent.getExtras().getString(PassToService);
#Nullable
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("unsupported Operation");
}
#Override
public void onCreate() {
// cancel if service is already existed
if(mTimer!=null)
mTimer.cancel();
else
mTimer=new Timer(); // recreate new timer
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(),0,INTERVAL);// schedule task
}
#Override
public void onTaskRemoved(Intent rootIntent) {
stopSelf();///its will stop service
super.onTaskRemoved(rootIntent);
}
#Override
public void onDestroy() {
Toast.makeText(this, "In Destroy", Toast.LENGTH_SHORT).show();//display toast when method called
mTimer.cancel();//cancel the timer
super.onDestroy();
}
//inner class of TimeDisplayTimerTask
private class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast at every 10 second
//String displayingText = "ABC";
String displayingText = myIntent.getStringExtra("PassToService");
final Toast Notify = Toast.makeText(getApplicationContext(), displayingText, Toast.LENGTH_SHORT);
Notify.setGravity(Gravity.CENTER, 0, 0);
Notify.show();
Handler cancelToast = new Handler();
cancelToast.postDelayed(new Runnable() {
#Override
public void run() {
Notify.cancel();
}
}, 1000);
}
});
}
}
}
You can do it by passing value from activity to service-
startService(new Intent(YourActivity.Service.class).putExtra("key","value"));

Running toast in at certain interval in a service

I am trying to show a toast at 2 seconds interval from a service.
This normal code works fine. This one is just a test to show toast.
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
new Thread(new ToastRunner(this)).start();
return START_STICKY;
}
But the below code crashes...
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
new Thread(new ToastRunner(this)).start();
return START_STICKY;
}
class ToastRunner implements Runnable{
Context context;
public ToastRunner(Context context){
this.context = context;
}
#Override
public void run() {
try {
while (true) {
Toast.makeText(context, "Service Started", Toast.LENGTH_SHORT).show();
Thread.sleep(2000);
}
}catch (Exception e){
Log.d("tag", e.toString() );
}
}
}
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Try this code,
while (true) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(context, "Service Started", Toast.LENGTH_SHORT).show();
}
});
Thread.sleep(2000);
}
That mean you cannot access ui element from one another thread. You must use uiThred. Try this code,
while (true) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context, "Service Started", Toast.LENGTH_SHORT).show();
Thread.sleep(2000);
}
}
}
try like this...
#Override
public void run() {
try {
// preparing a looper on current thread
// the current thread is being detected implicitly
Looper.prepare();
// now, the handler will automatically bind to the
// Looper that is attached to the current thread
// You don't need to specify the Looper explicitly
handler = new Handler();
// After the following line the thread will start
// running the message loop and will not normally
// exit the loop unless a problem happens or you
// quit() the looper (see below)
Looper.loop();
}
catch (Throwable t) {
Log.e(TAG, "halted due to an error", t);
}
}

Stop threads created by Android Service

I currently have an app which when a button is pressed starts a service and within the service a thread is created.
I then have a second button (which appears once the first it pressed) that should shut down the service and in turn kill the thread, below is my current code however the service seems to stop but the thread keeps going.
public class MainActivity extends Activity {
private static Button lock = null;
private static Button unlock = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lock = (Button) this.findViewById(R.id.lock);
unlock = (Button) this.findViewById(R.id.unlock);
lock.setOnClickListener(btn_lock);
unlock.setOnClickListener(btn_unlock);
unlock.setVisibility(View.VISIBLE);
lock.setVisibility(View.GONE);
text.setVisibility(View.GONE);
startService(new Intent(this, MainService.class));
}
private OnClickListener btn_lock = new OnClickListener() {
public void onClick(View v) {
unlock.setVisibility(View.VISIBLE);
lock.setVisibility(View.GONE);
startService(new Intent(MainActivity.this, MainService.class));
}
};
private OnClickListener btn_unlock = new OnClickListener() {
public void onClick(View v) {
unlock.setVisibility(View.GONE);
lock.setVisibility(View.VISIBLE);
stopService(new Intent(MainActivity.this, MainService.class));
}
};
}
And then my service class looks like:
public class MainService extends Service {
Thread 1Thread;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
1Thread = new Thread() {
public void run() {
while(true){
try {
Thread.sleep(180000); // 3 minutes
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("TEST", "Thread is still here!");
}
}
};
}
#Override
public void onDestroy() {
1Thread.interrupt();
}
#Override
public void onStart(Intent intent, int startId) {
1Thread.start();
}
}
Hope someone can help and if you need any more info let me know!
boolean mStatus = true;
#Override
public void onCreate() {
1Thread = new Thread() {
public void run() {
while (mStatus) {
try {
Thread.sleep(180000); // 3 minutes
} catch (InterruptedException e) {
e.printStackTrace();
continue;
}
Log.i("TEST", "Thread is still here!");
}
};
}
#Override
public void onDestroy() {
mStatus = false;
1Thread.interrupt();
}
Your thread is not handling interrupt, in while loop in each iteration check if thread is interrupted, if so then do not continue the loop:
while(!Thread.currentThread().isInterrupted()){
try {
Thread.sleep(180000); // 3 minutes
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
break; //BREAK here, as thread was interrupted
}
Log.i("TEST", "Thread is still here!");
}
Also on click of second button, you should interrupt this thread:
1Thread.interrupt();

Setting up a background process with Threading to handle work in Android

Hello I am trying to create a sample app when executed, will bring you back to the home screen , run a back ground process, and display toast points.
I figure that I will need a separate thread in the background process to do whatever work I need. Here is the Code of my Main Activity(BackGroundPrcessingExampleActivity):
enter code here
public class BackGroundProcessExampleActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
Intent myIntent = new Intent(this, MyService.class);
startService(myIntent);
moveTaskToBack(false);
} catch (Exception e) {
e.printStackTrace();
}
}
Here is the Code from "MyService.java":
enter code here
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getBaseContext(), "Service is started!", 1).show();
myHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Toast.makeText(getBaseContext(), "Hello!",
Toast.LENGTH_SHORT).show();
}
};
Runnable runnable = new Runnable() {
#Override
public void run() {
while (true) {
try {
Thread.sleep(2);
myHandler.sendEmptyMessage(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
new Thread(runnable).start();
return super.onStartCommand(intent, flags, startId);
}
The problem I am having is that the Toast message is not appearing. I can put breakpoints and see that it is stepping through the code but no message appears. I think it might be that the context is not correct? Do I need the UI's Context(BackGroundPRcessExampleActivity)? Any help is appreciated, thanks in advance.
D
Try it -
public int onStartCommand(Intent intent, int flags, int startId) {
Handler mHandler = new Handler();
Toast.makeText(getApplicationContext(), "Service is started!", 1).show();
Runnable runnable = new Runnable() {
#Override
public void run() {
while (true) {
try {
Thread.sleep(5000);
mHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Hello!", Toast.LENGTH_LONG).show();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
new Thread(runnable).start();
return super.onStartCommand(intent, flags, startId);
}
With the help of the replies, this is what eventually worked for me. There is notification code added.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
// Create Notifcation
final Notification notification = new Notification(R.drawable.ic_launcher,
"A new notification", System.currentTimeMillis());
// Cancel the notification after its selected
notification.flags |= Notification.FLAG_AUTO_CANCEL;
//
notification.number += 1;
// Specify the called Activity
Intent intent2 = new Intent(this, NotificationReceiver.class);
Toast.makeText(getApplicationContext(), "Service is started!", 1)
.show();
PendingIntent activity = PendingIntent.getActivity(this, 0, intent2, 0);
notification.setLatestEventInfo(this, "This is the title",
"This is the text", activity);
myHandler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
int i = 0;
while (true) {
final int x = i++;
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
myHandler.post(new Runnable() {
#Override
public void run() {
try {
Toast.makeText(getApplicationContext(),
"Hello!" + String.valueOf(x),
3).show();
if(x == 100)
notificationManager.notify(0, notification);
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
};
new Thread(runnable).start();
Thank you everyone for their help.
D

Categories