Background services

Put your problem here if it does not fit any of the other categories.

Background services

Postby Steph » Sat Sep 01, 2012 8:23 am

Hi,

I'm working on a twitter like.
I'd like to load my tweet in a background service but each time I close my activity, the onDestroy of my service is called.
How can i make my service running in background without my activity?

Best regards,
Thanks

Service code
Code: Select all
public class TwoiceTimelineService extends TwoiceService {

   /*
    * using to keep service alive even if screen off
    */
   private static final Class<?>[] mStartForegroundSignature = new Class[] {
      int.class, Notification.class};
   private static final Class<?>[] mStopForegroundSignature = new Class[] {
      boolean.class};

   private Method mStartForeground;
   private Method mStopForeground;

   private Object[] mStartForegroundArgs = new Object[2];
   private Object[] mStopForegroundArgs = new Object[1];

   /**
    * TWEETS_UPDATE : Communication with activity
    */
   static public String TWEETS_UPDATE = "stephane.castrec.twoice.UPDATE_TWEETS";

   /**
    * OPTION_TIME_TO_UPDATE : What receive if update time in second receive from parameters
    */
   static public final int OPTION_TIME_TO_UPDATE = 100;
   /**
    * OPTION_TIME_TO_UPDATE : What receive if update time in second receive from parameters
    */
   static public final int OPTION_ENABLE_SOUND = 110;
   /**
    * NB_TWEETS_TO_SAVE
    */
   static private final int NB_TWEETS_TO_SAVE = 10;

   private static final int TWOICE = 1;
   private static int REFRESH_TIME = 10000;

   //timer to update regurlay statuses
   private Timer timer = null;
   //TimerTask for scanning
   private TimerTask timerTask;

   /**
    * Handler to update options
    */
   public static final Handler serviceTimelineHandler = new Handler(){
      public void handleMessage(Message msg) {
         switch (msg.what) {
         case OPTION_ENABLE_SOUND:
            Log.d("twoice","TwoiceTimelineService isSpeak="+isSpeak);
            isSpeak = !isSpeak;
            //stop speaking
            mTts.stop();
            break;
         case OPTION_TIME_TO_UPDATE:
            Log.d("twoice","TwoiceTimelineService refresh time="+msg.arg1);
            REFRESH_TIME = msg.arg1;
            break;
         default:
            break;
         }
      }
   };


   /**
    * send update event to activity
    *       each time new tweets coming, send event
    */
   private void sendDataToActivity(){
      Log.d("twoice", "Service sendDataToActivity TWEETS_Update");
      Intent intent = new Intent(TWEETS_UPDATE);
      sendBroadcast(intent);
   }

   // This is the object that receives interactions from clients.  See
   // RemoteService for a more complete example.
   private final IBinder mBinder = new LocalBinder();

   /**
    * Class for clients to access.  Because we know this service always
    * runs in the same process as its clients, we don't need to deal with
    * IPC.
    */
   public class LocalBinder extends Binder {
      TwoiceTimelineService getService() {
         return TwoiceTimelineService.this;
      }
   }

   /**
    * Configure and display notification icon
    */
   @SuppressWarnings("static-access")
   protected Notification getNotification(){
      //NotificationManager mNotificationManager = (NotificationManager) getSystemService(this.NOTIFICATION_SERVICE);
      //instanciate notif
      int icon = R.drawable.icon;
      CharSequence tickerText = this.getString(R.string.app_name);
      long when = System.currentTimeMillis();

      Notification notification = new Notification(icon, tickerText, when);

      //define message and Intent
      CharSequence contentTitle = this.getString(R.string.app_name);
      CharSequence contentText = this.getString(R.string.message_notification);
      Intent notificationIntent = new Intent(this, TwoiceActivity.class);
      PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

      notification.setLatestEventInfo(this, contentTitle, contentText, contentIntent);
      notification.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR | Notification.FLAG_FOREGROUND_SERVICE;
      return notification;
   }

   /**
    * startScan: scanning for new tweets
    */
   private void execute() {
      //setNotification();

      textCategorizer = new TextCategorizer();
      timer = new Timer();
      timerTask = new TimerTask() {
         public void run() {
            int nbNewTweets = retrieveStatusFromTwitter();

            //send flag to activity
            //check if tts enable and tweets to say
            if(SessionObject.getStatuses() != null){
               sendDataToActivity();
            }

            speak(nbNewTweets);

         }};
         //start timerTask in 100 ms
         timer.schedule(timerTask, 100, REFRESH_TIME);
   }

   /**
    * stopScan: cancel timer
    */
   public void stopScan(){
      if(timerTask!=null){
         timerTask.cancel();
      }
   }

   @Override
   public void onDestroy() {
      //stop timer
      if(timer != null){
         stopScan();
         timer.cancel();         
      }
      //rm notification
      NotificationManager mNotificationManager = (NotificationManager) getSystemService(this.NOTIFICATION_SERVICE);
      mNotificationManager.cancel(TWOICE);

      super.onDestroy();
   }

   /**
    * retrieveStatusFromTwitter
    * @return nb tweet retrieve
    */
   private int retrieveStatusFromTwitter(){
      try {
         ResponseList<Status> status = null;
         //check if first tweet
         if(null == SessionObject.getStatuses() || !SessionObject.getStatuses().isEmpty()){
            status = twitter.getHomeTimeline();
            SessionObject.setStatuses(status);
         } else {
            //check for updates
            status = twitter.getHomeTimeline(new Paging(0, SessionObject.getStatuses().get(0).getId()));
            SessionObject.addStatuses(status);
         }
         if(status != null)
            return status.size();
      } catch (Exception e) {
         Log.e("twoice", "TwoiceTimelineService error on access Twitter");
      }
      return 0;
   }

   /*
    * @see android.app.Service#onBind(android.content.Intent)
    */
   @Override
   public IBinder onBind(Intent arg0) {
      return mBinder;
   }
   
    @Override
    public void onCreate() {
        try {
            mStartForeground = getClass().getMethod("startForeground",
                    mStartForegroundSignature);
            mStopForeground = getClass().getMethod("stopForeground",
                    mStopForegroundSignature);
            return;
        } catch (NoSuchMethodException e) {
            // Running on an older platform.
            mStartForeground = mStopForeground = null;
        }
    }

   @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
      //init service as foreground          
      this.startForegroundService(88888, getNotification());
      // We want this service to continue running until it is explicitly
      // stopped, so return sticky.
      return START_STICKY;
   }
   
   @Override
   public void onLowMemory() {
      System.out.println("I am on low memory :(");
   }

   void invokeMethod(Method method, Object[] args) {
      try {
         method.invoke(this, args);
      } catch (InvocationTargetException e) {
         // Should not happen.
         Log.w("ApiDemos", "Unable to invoke method", e);
      } catch (IllegalAccessException e) {
         // Should not happen.
         Log.w("ApiDemos", "Unable to invoke method", e);
      }
   }

   /**
    * This is a wrapper around the new startForeground method
    */
   private void startForegroundService(int id, Notification notification) {
      // If we have the new startForeground API, then use it.
      if (mStartForeground != null) {
         mStartForegroundArgs[0] = Integer.valueOf(id);
         mStartForegroundArgs[1] = notification;
         invokeMethod(mStartForeground, mStartForegroundArgs);
         return;
      }
   }

   /**
    * This is a wrapper around the new stopForeground method
    */
   private void stopForegroundService(int id) {
      // If we have the new stopForeground API, then use it.
      if (mStopForeground != null) {
         mStopForegroundArgs[0] = Boolean.TRUE;
         invokeMethod(mStopForeground, mStopForegroundArgs);
         return;
      }
   }
}


My activity
Code: Select all
   @Override
   public void onStart(){
      //Start service
      startTimelineService();
      super.onStart();
   }
   private void startTimelineService(){
      if(!isTimelineServiceStarted){
         Intent intent = new Intent(this,TwoiceTimelineService.class);
         startService(intent);
         isTimelineServiceStarted = true;
      }
   }
Steph
Experienced Developer
Experienced Developer
 
Posts: 90
Joined: Mon Oct 20, 2008 1:48 pm
Location: France

Top

Return to Other Coding-Problems

Who is online

Users browsing this forum: No registered users and 24 guests