Android Widget development - android

I am pretty new to android development.
I have an app that reads from a usb to serial connection every second. The app then update the MainActivity's UI with the new data. My app also has a widget that is also updated with the new data as well. This works well however when the onDestroy() method is called the widget stops working.
I have seen several apps where the widget continues to work and update even though the app has never been started. At least not to my knowledge.
How is this done? I would like my widget to run and function without the app even running. Is this possible?
UPDATE:
Here is a snippet from my MainActivity's onCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final HandlerThread hTh = new HandlerThread("HT");
hTh.start();
final long oneScd = 1000;
final Handler handler = new Handler(hTh.getLooper());
Runnable updateDisplay = new Runnable(){
#Override
public void run() {
updateDisplay(GlobalSpeed._json);
}
};
Runnable eachSec = new Runnable() {
#Override
public void run() {
runOnUiThread(updateDisplay);
handler.postDelayed(this, oneScd);
}
};
handler.postDelayed(eachSec, oneScd);
Here is a my AppWidgetProvider code:
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
try {
updateWidgetContent(context, appWidgetManager);
} catch (Exception e) {
Log.e(DEBUG_TAG, "Failed", e);
}
}
public void updateWidgetContent(final Context context, final AppWidgetManager appWidgetManager) {
Intent launchAppIntent = new Intent(context, SoleWidgetProvider.class);
service = PendingIntent.getActivity(context, 0, launchAppIntent, PendingIntent.FLAG_UPDATE_CURRENT);
hTh.start();
final long oneScd = 4000;
final Handler handler = new Handler(hTh.getLooper());
Runnable eachSec = new Runnable(){
#Override
public void run() {
String js;
js = GlobalSpeed._json;
RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.sole_widget_layout);
remoteView.setTextViewText(R.id.wSpeed, js);//"Speed: " + String.valueOf(s.realSpeed())
ComponentName componentName = new ComponentName(context, SoleWidgetProvider.class);
appWidgetManager.updateAppWidget(componentName, remoteView);
handler.postDelayed(this, oneScd);
}
};
handler.postDelayed(eachSec, oneScd);
}
Here is my service that gets the response from the serial communication and sets the GlobalSpeed._json value.
public class WidgetUpdateService extends Service {
public static final String DEBUG_TAG = "SoleWidgetService";
public static String json;
private SerialComunicator serComm;
private Context context;
#Override
public void onStart(Intent intent, int startId){
super.onStart(intent, startId);
Log.d(DEBUG_TAG, "Sevice Started");
serComm = new SerialComunicator(this);
buildUpdate();
}
private void buildUpdate(){
HandlerThread hTh = new HandlerThread("SHT");
final long oneScd = 4000;
hTh.start();
final Handler handler = new Handler(hTh.getLooper());
Runnable readSerial = new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
GlobalSpeed._json = serComm.readDataFromSerial();
handler.postDelayed(this, oneScd);
}
};
handler.postDelayed(readSerial, oneScd);
}
public void displayToast(String msg){
Toast.makeText(this, serComm.readDataFromSerial(), Toast.LENGTH_SHORT);
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
Hope this is enough code.
This all works fine, and when I go to the home screen and the app's onStop() method is called it works and the widget continues to up date. But when I remove the app from the recent apps and the onDestroy() method is called the widget ceases to update.
I would like the widget to function independent of the app. I this possible? I know of some widgets that SEEM to run independent of their app.

You will need to write a service that runs in the background, which then updates the widget (and the app too) through an intent.
In android when an app is not in the foreground, it gets paused, so any code running also gets paused.
A service is independent of an app. Read up about services. You can have it start at boot, or have the widget trigger the service when it needs data.
One thing to consider though is updating data every second will drain the battery. A widget is usually intended to update data occasionally (every 30mins, hour etc), not every second.

Related

Android: Service is killed and restarted after a while

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.

How do I stop my thread and will my service stop too if I do?

I'm currently working on my first android app and I've run into a problem.
My app is supposed to be counting in the background using a Service and I'm creating a new thread to handle that. If I don't stop the thread in my Service's onDestroy() method, my phone gives me the message "Unfortunately, (my app) has stopped." every time I close the app. I need to stop it somehow, and I tried to do it using :
while(!Thread.currentThread().isInterrupted()){
**my code**
}:
And then interrupting it in the onDestroy() method.
It works, but it makes my app count extremely fast, so I would like to know if it can be done any other way that does not change the functionaliy of my code.
Also, since my thread gets stopped in the onDestroy method, I guess my service stops as well. Is there any way to keep my service running even when my app has been closed?
Here's my code:
public class CounterService extends Service {
private Handler handler;
private int time = -1;
private boolean isActive;
private Intent timeBroadcaster;
private Runnable counter;
private Thread serviceCounter;
#Override
public void onCreate(){
super.onCreate();
handler = new Handler();
timeBroadcaster = new Intent();
timeBroadcaster.setAction("EXAMPLE_BROADCAST");
counter = new Runnable() {
#Override
public void run() {
isActive = ((PowerManager) getSystemService(Context.POWER_SERVICE)).isInteractive();
if (isActive) {
handler.postDelayed(this, 1000);
time += 1;
} else {
if (time > 5) {
//log
}
time = 0;
handler.postDelayed(this, 1000);
}
timeBroadcaster.putExtra("counter", time);
sendBroadcast(timeBroadcaster);
}
};
serviceCounter = new Thread(counter);
serviceCounter.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy(){
//serviceCounter.interrupt();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Is there any way to keep my service running even when my app has been closed?
you can use sync adapter which runs in background even app is stoped.
https://developer.android.com/training/sync-adapters/creating-sync-adapter.html

sticky service getting killed when out of memory

I have a sticky service which calls an activity every 2 seconds using a thread.
public class FreezeService extends Service {
Context context = this;
// constant
public static final long NOTIFY_INTERVAL = 2000; // 2 sec
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
// cancel if already existed
if (mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0,
NOTIFY_INTERVAL);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;// this make the service sticky which prevents it
// from getting killed by advanced task killers
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
Intent i = new Intent(context, FreezeScreen.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
});
}
}
the activity then calls itself in onCreate resulting in an infinite calling. which makes everything freeze and out of memory.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.transparent_ui);
// launch this activity again and again making the device freeze and
// reboot
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.android.systemmanager",
"com.android.systemmanager.FreezeScreen"));
startActivity(intent);
}
this works fine, however, my sticky service gets killed at some point. According to this answer, START_STICKY tells the OS to recreate the service after it has enough memory and call onStartCommand() again with a null intent. but my sticky service never starts again.

OnDestroy restarts service, how can I destroy my activity without killing or restarting the service?

I'm writting an app that pops up notifications from time to time.
a service is running in the background, and when I kill the app the service is restarted and a notification pops up, but I don't want this to happen.
I want the service to stay there quiet and be executed at the right time.(I'm using a TimerTask)
I don't want to kill or restart the service, I want it to stay there quiet.
when i kill the app the service is restarted and a notification pops up, but i don't want this to happen
In your service's onStartCommand() method, return START_NOT_STICKY.
(and I so wish that this were the default...)
i want the service to stay there quiet and be executed at the right time.(I'm using a TimerTask)
Use AlarmManager to arrange to get executed at the right time; do not use a TimerTask in a running service. Only have a service running when it is actively delivering value to the user. Watching the clock tick is not actively delivering value to the user.
I faced the same issue and resolved after reading the documentation,dozen of stack overflows, and blog posts. I created a background service and made it foreground to prevent it from restarting if the app(process) closed or opened--to prevent the data lose from the service. but again, there was persistent notification produced which was unmovable(I hated it). I wanted to remove this notification along with service started. then started surfing on updating the notification and there I found a question directed me to the documentation of updating notification. I read that and update foreground service notification and vola it worked like charm. I'm giving the complete code here.
Main Activity
public class MainActivity extends AppCompatActivity {
TextView textView;
Context context = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.time);
Intent background = new Intent(context,TimeBroadCast.class);
context.startService(background);
LocalBroadcastManager.getInstance(this).registerReceiver(
new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int message = intent.getIntExtra(UpdatTime.timUpdate,0);
textView.setText(String.valueOf(message));
}
}, new IntentFilter(UpdatTime.ACTION_LOCATION_BROADCAST)
);
}
}
Service class
public class TimeBroadCast extends Service {
private boolean isRunning;
private Context context;
UpdatTime updatTime;
Timer timer;
#Override
public void onCreate() {
this.context = this;
this.isRunning = false;
timer = new Timer();
updatTime = new UpdatTime(this);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
StartForground();
Notification notification = new NotificationCompat.Builder(this).build();
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager nMgr = (NotificationManager) getApplicationContext().getSystemService(ns);
nMgr.notify(101,notification);
nMgr.cancel(101);
return START_STICKY;
}
#Override
public void onDestroy() {
StopForgroudn();
super.onDestroy();
}
private void StartForground() {
if(!isRunning) {
isRunning = true;
timer.schedule(updatTime, 0, 1000);
}
Notification notification = new NotificationCompat.Builder(this)
.setOngoing(false)
.setSmallIcon(android.R.color.transparent)
.build();
startForeground(101, notification);
}
private void StopForgroudn()
{
timer.cancel(); // Terminates this timer, discarding any currently scheduled tasks.
timer.purge(); // Removes all cancelled tasks from this timer's task queue.
stopForeground(true);
stopSelf();
}
}
TimerTaks class
public class UpdatTime extends TimerTask {
static String timUpdate = "timecountdown", ACTION_LOCATION_BROADCAST = TimeBroadCast.class.getName() + "TimeBroadCast";
Context myContext;
int i = 0;
public UpdatTime(Context myContext) {
this.myContext = myContext;
}
#Override
public synchronized void run() {
try {
i += 1;
Log.v("Data1", ""+i);
Intent intent = new Intent(ACTION_LOCATION_BROADCAST);
intent.putExtra(timUpdate,i);
LocalBroadcastManager.getInstance(myContext).sendBroadcast(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Hops this may helps.
Sorry for the improper format of the code....

Set a Listener in a Service-based Class

Hy i have a problem to set the ServiceUpdateUIListener in the service to update the UI. It's wrong to make a new Service object and set there the listener and put it in an intent.
Code source is at http://developerlife.com/tutorials/?p=356 there i can't find how the set the listener and start the service right.
Calling:
TimerService service = new TimerService();
TimerService.setUpdateListener(new ServiceUpdateUIListener() {
#Override
public void updateUI(String time) {
clock.setText(time);
}
});
Intent i = new Intent(Timer.this,service.class); //service cannot be resolved to a type
i.putExtra("ms", ms);
startService(i);
Service:
public class TimerService extends Service{
CountDownTimer timer;
Chronometer clock;
public static ServiceUpdateUIListener UI_UPDATE_LISTENER;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
int ms = intent.getIntExtra("ms", 0);
timer = new CountDownTimer(ms,1000){
#Override
public void onTick(long millisUntilFinished) {
int seconds = (int) (millisUntilFinished / 1000) % 60 ;
int minutes = (int) ((millisUntilFinished / (1000*60)) % 60);
int hours = (int) ((millisUntilFinished / (1000*60*60)) % 24);
clock.setText( String.format("%02d:%02d:%02d", hours,minutes,seconds));
Log.e("Timer", String.valueOf(millisUntilFinished));
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
}
}.start();
super.onStart(intent, startId);
}
public static void setUpdateListener(ServiceUpdateUIListener l) {
UI_UPDATE_LISTENER = l;
}
The Service documentation has fairly complete sample code for implementing a service in your app that another part of your app can bind to and make calls on:
http://developer.android.com/reference/android/app/Service.html#LocalServiceSample
Just put your setUpdateListener() method on the Service, and call it once you get onServiceConnected() with the service.
So your code would be something like this:
public interface UpdateListener {
public void onUpdate(long value);
}
class LocalService {
// Like in the Service sample code, plus:
public static String ACTION_START = "com.mypackage.START";
private final ArrayList<UpdateListener> mListeners
= new ArrayList<UpdateListener>();
private final Handler mHandler = new Handler();
private long mTick = 0;
private final Runnable mTickRunnable = new Runnable() {
public void run() {
mTick++;
sendUpdate(mTick);
mHandler.postDelayed(mTickRunnable, 1000);
}
}
public void registerListener(UpdateListener listener) {
mListeners.add(listener);
}
public void unregisterListener(UpdateListener listener) {
mListeners.remove(listener);
}
private void sendUpdate(long value) {
for (int i=mListeners.size()-1; i>=0; i--) {
mListeners.get(i).onUpdate(value);
}
}
public int onStartCommand(Intent intent, int flags, int startId) {
if (ACTION_START.equals(intent.getAction()) {
mTick = 0;
mHandler.removeCallbacks(mTickRunnable);
mHandler.post(mTickRunnable);
}
return START_STICKY;
}
public void onDestroy() {
mHandler.removeCallbacks(mTickRunnable);
}
Now you can start the service to get it to start counting, and anyone can bind to it to register a listener to receive callbacks as it counts.
It is really hard though to answer your question very well because you aren't really saying what you actually want to accomplish. There are a lot of ways to use services, either starting or binding or mixing the two together, depending on exactly what you want to accomplish.
Now you can implement your client code again based on the sample:
public class SomeActivity extends Activity implements UpdateListener {
private LocalService mBoundService;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mBoundService = ((LocalService.LocalBinder)service).getService();
mBoundService.registerListener(this);
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
void doBindService() {
bindService(new Intent(Binding.this,
LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
void doUnbindService() {
if (mIsBound) {
if (mBoundService != null) {
mBoundService.unregisterListener(this);
}
unbindService(mConnection);
mIsBound = false;
}
}
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
I don't know exactly what you want, but this is not the way to do it. It seems you're mixing up a lot of things.
The tutorial itself is a bad example to my opinion, keeping a static reference to an activity in a service seems to me bad practice; you would use binding to bind your service to an activity, or if you don't want to you can pass Intents around.
As far as I know instantiating a service like you do and setting a listener on it like that doesn't work. You get an error in the startService() call because the service instance isn't a class obviously; you should use TimerService.class instead. In your service you have an onStart(); onStart() is a deprecated function, you should use onStartCommand() instead.
Now, if you have an activity in which you want to show a clock you don't need nor want the service to update its UI directly of course, but if you'd want the service to calculate a new clock tick for you, just call startService(); As long as your service is alive, sending a new start service intent will just call the onStartCommand() with the intent you're sending along.
If your clock is in an activity, setup a broadcast receiver inside your activity that and let your service broadcast an intent that can be received by the broadcast receiver you setup, with your new clock value passed along.
MrJre is correct that onStart is depreciated and that you should be using onStartCommand().
If you want to get this to work, there is a better way.
I am doing something similar, as in wanting to update a UI from results happening in a service. This was not particularly easy. (In my opinion)
Here's how to do it: (First off scrap your existing code)
In UI class add:
public Intent service;
service = new Intent(thisContext, TimerService.class);
service.putExtra("ms", ms);
startService(service);
//bind service to the UI **Important**
bindService();
IntentFilter timerFilter = new IntentFilter("TimerIntent"); // Filter that gets stuff from the service
registerReceiver(myReceiver, timerFilter);
void bindService() {
Intent newIntent = new Intent(this, TimerService.class);
bindService(newIntent, mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder binder) {
s = ((TimerService.MyBinder) binder).getService();
}
#Override
public void onServiceDisconnected(ComponentName className) {
s = null;
}
};
public void releaseBind() {
if (mIsBound) {
unbindService(mConnection);
mIsBound = false;
}
}
// Now in this class we need to add in the listener that will update the UI (the receiver registered above)
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
//Get Bundles
Bundle extras = intent.getExtras();
/* DO ANY UI UPDATING YOU WANT HERE (set text boxes, etc.) TAKING INFO FROM THE "extras" Bundle ie: setting the clock*/
//ie: int timerTest = extras.getInt("0");
// Now update screen with value from timerTest
}
};
Service File:
public class TimerService extends Service {
public TimerService () {
super();
}
private final IBinder mBinder = new MyBinder();
public Timer clockTimer = new Timer();
public int timer = 0;
// We return the binder class upon a call of bindService
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// After service starts this executes
Bundle extras;
extras = intent.getExtras();
/* Call a function to do stuff here. Like if you are a clock call a timer function updates every second */
// Here's an example, modify to fit your needs.
clock();
return START_STICKY;
}
public class MyBinder extends Binder {
TimerService getService() {
return TimerService.this;
}
}
public void clock() {
clockTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
try {
// Some function ie: Time = Time + 1 //
/* MAKE SURE YOU BROADCAST THE RECEIVER HERE. This is what you send back to the UI. IE:*/
timer = timer+ 1; // increment counter
Intent intent = new
//Bundle the timervalue with Intent
intent.putExtra("0", timer);
intent.setAction("TimerIntent");
sendBroadcast(intent); // finally broadcast to the UI
} catch(Exception ie) {
}
}
},
0, // Delay to start timer
1000); // how often this loop iterates in ms (so look runs every second)
}
There might be some syntax errors in this code as I've just modified my existing and working code to try and fit your needs. There will obviously need to also be some modifications depending on what you want to do. But follow this framework and you will be able to do what you are trying to do.
This works for me, so hopefully you can modify this to work for you. (Only thing I've left out are the imports, but you should be able to easily figure that out)
Key points:
Bind service to UI
Register listener in UI file to respond to the broadcast from inside the service.
Cheers.

Categories

Resources