Android Open Source - Android-Universal-Notifier Tasks Queue






From Project

Back to project page Android-Universal-Notifier.

License

The source code is released under:

Apache License

If you think the Android project Android-Universal-Notifier listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.mairos.universalnotifier.model;
/*from w  w  w .  j  a v a  2 s.  com*/
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;

import com.mairos.universalnotifier.network.SMSSender;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.telephony.SmsManager;
import android.util.Log;
import android.webkit.ConsoleMessage;
import android.webkit.WebChromeClient;
import android.webkit.WebView;

// core functions here - Update tasks list, schedule task execution via AlarmSevice and Execute tasks
// calls from GUI and AlarmManagerBroadcastReceiver
// it works in UI thread, because there's no way to run WebView (which
//     is interpreter for Task actions description) in other thread
public class TasksQueue {
  
  private static String m_tasksURL = "http://4lessons.ru/tmp/sample_tasks.xml";
  
  public static String getTasksURL(){
    return m_tasksURL;
  }
  public static void setTasksURL(String f_tasksURL){
    m_tasksURL = f_tasksURL;
  }
  
  private Context m_context = null;
  private ConcurrentHashMap<String, NotificationTask> m_tasks_map = new ConcurrentHashMap<String, NotificationTask>();
  
  private List<Runnable> m_activeTasks = new ArrayList<Runnable>();
  
  public NotificationTask[] getTasksArray() {
    if (m_tasks_map.size() == 0) return null;
    return m_tasks_map.values().toArray(new NotificationTask[m_tasks_map.size()]);
  }
  public ConcurrentHashMap<String, NotificationTask> getTasksMap() {
    return m_tasks_map;
  }

  //  Singleton usage
  private static TasksQueue m_instance;
  
  private TasksQueue(Context f_context){
    m_context = f_context;
    
    // TODO - move registerReceiver away from here
        // ---when the SMS has been sent---
        m_context.registerReceiver(new BroadcastReceiver() {
            public void onReceive(Context arg0, Intent arg1) {
              String sentToPhoneNumber = arg1.getStringExtra("phoneNumber");
                switch (getResultCode()) {
                case Activity.RESULT_OK:
                  Logger.addToLog("SMS sent to " + sentToPhoneNumber, m_context);
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                  Logger.addToLog("Generic failure " + sentToPhoneNumber, m_context);
                  break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                  Logger.addToLog("No service " + sentToPhoneNumber, m_context);
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                  Logger.addToLog("Null PDU " + sentToPhoneNumber, m_context);
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                  Logger.addToLog("Radio off " + sentToPhoneNumber, m_context);
                    break;
                }
            }
        }, new IntentFilter(SMSSender.SMS_SENT));

        // ---when the SMS has been delivered---
        m_context.registerReceiver(new BroadcastReceiver() {
            public void onReceive(Context arg0, Intent arg1) {
              String sentToPhoneNumber = arg1.getStringExtra("phoneNumber");
                switch (getResultCode()) {
                case Activity.RESULT_OK:
                  Logger.addToLog("SMS delivered to " + sentToPhoneNumber, m_context);
                    break;
                case Activity.RESULT_CANCELED:
                  Logger.addToLog("SMS not delivered to " + sentToPhoneNumber, m_context);
                    break;
                }
            }
        }, new IntentFilter(SMSSender.SMS_DELIVERED));
    
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(m_context);
        if (prefs.getBoolean("http_update", false))
          loadAndScheduleCurrentTasks(Const.FROM_WEB);
        else
          loadAndScheduleCurrentTasks(Const.FROM_FOLDER);
  }
  public synchronized static TasksQueue getInstance(Context f_context){
    if (m_instance == null){
      m_instance = new TasksQueue(f_context);
    }
    return m_instance;
  }
  
  public String toString(){
    String res = "";    
    for (NotificationTask entry: m_tasks_map.values())
      res += "################" + "\n" + entry.toString() + "\n";
    return res;
  }
  
  public static Date getNearestTime(Date f_from, int f_interval){
    long now = (new Date()).getTime();
    long from = f_from.getTime();
    while(from < now) {
      from += f_interval;
    }
      return new Date(from);
  }
  
  public void loadAndScheduleCurrentTasks(final String f_source){
    new Thread(new Runnable() {
          public void run() {

            ArrayList<NotificationTask> nts = null;
            
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(m_context);
            
            if (f_source.equals(Const.FROM_FOLDER)){
              nts = TasksXMLLoader.loadAndParseFromFolder(prefs.getString("tasks_folder", "default"), m_context);              
            }
            else if (f_source.equals(Const.FROM_WEB)){
              if (prefs.getBoolean("http_update", false))
                nts = TasksXMLLoader.loadAndParseFromWeb(m_tasksURL, m_context);
            }
            
            AlarmManager am = (AlarmManager) m_context.getSystemService(Context.ALARM_SERVICE);
            
            if (nts != null && nts.size() > 0) {
              // clear old tasks
              Collection <NotificationTask> old_nts = m_tasks_map.values();
              for (NotificationTask item : old_nts) {
                if (item.isScheduled()){
                  Intent intentAM = new Intent(m_context, AlarmManagerBroadcastReceiver.class);
                  PendingIntent pi = PendingIntent.getBroadcast(m_context, item.hashCode(), intentAM, 0);
                  am.cancel(pi);
                  item.setSheduled(false);
                }
              }
              m_tasks_map.clear();
              
              NotificationTask tmpNT = null;
              // add new tasks
              for (int i = 0; i < nts.size(); i++) {
                tmpNT = nts.get(i);
                
                  // tasks execution time hasn't passed yet
                if ((!tmpNT.getRepeatable() && tmpNT.getStartTime().getTime() > (new Date()).getTime()) ||
                  (tmpNT.getRepeatable() && tmpNT.getFinishTime().getTime() > (new Date()).getTime())) {
                  
                  if (tmpNT.getRepeatable() && tmpNT.getStartTime().getTime() < (new Date()).getTime())
                    tmpNT.setStartTime(getNearestTime(tmpNT.getStartTime(), tmpNT.getInterval()));                
                  
                  Intent unit_intent = new Intent(m_context, AlarmManagerBroadcastReceiver.class);
                  unit_intent.putExtra(AlarmManagerBroadcastReceiver.ALARM_MODE, AlarmManagerBroadcastReceiver.ALARM_MODE_EXECUTE_TASK);
                  unit_intent.putExtra(NotificationTask.TASK_NAME, tmpNT.getName());
                      PendingIntent pi = PendingIntent.getBroadcast(m_context, tmpNT.hashCode(), unit_intent, 0);
                      
                      if (!tmpNT.getRepeatable())
                        am.set(AlarmManager.RTC_WAKEUP, tmpNT.getStartTime().getTime(), pi);
                      else
                        am.setRepeating(AlarmManager.RTC_WAKEUP, tmpNT.getStartTime().getTime(), tmpNT.getInterval(), pi);
                
                      tmpNT.setSheduled(true);
                }
                
                m_tasks_map.put(tmpNT.getName(), tmpNT);
          }
              
              if (nts.size() > 0) {
                Intent intentCT = new Intent();
            intentCT.setAction(Const.ACTION_SHOW_CURRENT_TASKS);
            StringBuilder msgStr = new StringBuilder();
                Format formatter = new SimpleDateFormat("hh:mm:ss", Locale.US);
                msgStr.append(formatter.format(new Date()));
                String add = "";
                if (f_source.equals(Const.FROM_FOLDER)){
                  add = "Tasks updated from " + prefs.getString("tasks_folder", "default") + " at " + msgStr + ":";
                } else if (f_source.equals(Const.FROM_WEB)){
                  add = "Tasks updated from " + TasksQueue.getTasksURL() + " at " + msgStr + ":";
                }
            
            intentCT.putExtra(Const.TF_MESSAGE, add);
            m_context.sendBroadcast(intentCT);
              }
            }          
          }
    }).start();
  }
    
  public void executeTask(String f_task_name) {
    Logger.addToLog("========>>>>>>>>>>\n" +
                "Task '" + f_task_name + "' execution started!", m_context);
    
    final String task_name = f_task_name;
        
        Handler handler = new Handler();
        
        final Runnable newTaskCode = new Runnable() {
          private NotificationTask nt = null;
          private WebView executor = null;
          
          @Override
      protected void finalize() throws Throwable {
            Log.d(Const.LOG_TAG, task_name + " Runnable from TasksQueue.executeTask() finalized");
        super.finalize();
      }
      
          @SuppressLint({ "SetJavaScriptEnabled", "JavascriptInterface" })
      public void run() {
            if (m_tasks_map.containsKey(task_name)) {
            nt = m_tasks_map.get(task_name);
            executor = new WebView(m_context);
            Log.d(Const.LOG_TAG, task_name + " WebView 'executor' created");
            executor.setWebChromeClient(new WebChromeClient() {            
            @SuppressWarnings("deprecation")
            @Override
            public boolean onJsTimeout() {
              Logger.addToLog("'" + task_name + "' - JsTimeout", m_context);
              return super.onJsTimeout();
            }
            @Override
            public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
              Logger.addToLog("JSMessage: at line " + consoleMessage.lineNumber() + ", " +  
                        consoleMessage.message() /*+ ", sourceId = " + consoleMessage.sourceId()*/, m_context);
              return super.onConsoleMessage(consoleMessage);
            }
            });
            executor.getSettings().setJavaScriptEnabled(true);
            executor.addJavascriptInterface(new JSInterpreter(m_context, nt, task_name), "Java");
            executor.loadData("<script type=\"text/javascript\">" + nt.getJS_script() + "</script>", "text/html", "en_US");
            }
          }
        };
        // in order GC not to finalize this task code
        m_activeTasks.add(newTaskCode);
        handler.post(newTaskCode);
        handler.postDelayed(new Runnable() {
      @Override
      public void run() {
        Log.d(Const.LOG_TAG, "'" + task_name + "' task runnable reference removed");
        // TODO the way to stop WebViewCoreThread - not needed any more
        //Class.forName("android.webkit.WebView").getMethod("onPause", (Class[]) null).invoke(newTaskCode.executor, (Object[]) null);
        // allow GC to remove this task
        m_activeTasks.remove(newTaskCode);
      }
    }, m_tasks_map.get(task_name).getLifetime());
  }
}




Java Source Code List

com.mairos.universalnotifier.UI.LogFragmentTab.java
com.mairos.universalnotifier.UI.MainActivity.java
com.mairos.universalnotifier.UI.SettingsActivity.java
com.mairos.universalnotifier.UI.TabListener.java
com.mairos.universalnotifier.UI.TaskInfoActivity.java
com.mairos.universalnotifier.UI.TasksFragmentTab.java
com.mairos.universalnotifier.model.AlarmManagerBroadcastReceiver.java
com.mairos.universalnotifier.model.AttachmentData.java
com.mairos.universalnotifier.model.Const.java
com.mairos.universalnotifier.model.JSInterpreter.java
com.mairos.universalnotifier.model.LauncherBroadcastReceiver.java
com.mairos.universalnotifier.model.Logger.java
com.mairos.universalnotifier.model.NotificationService.java
com.mairos.universalnotifier.model.NotificationTask.java
com.mairos.universalnotifier.model.TasksQueue.java
com.mairos.universalnotifier.model.TasksXMLLoader.java
com.mairos.universalnotifier.network.GMailSender.java
com.mairos.universalnotifier.network.JSSEProvider.java
com.mairos.universalnotifier.network.NetworkOperations.java
com.mairos.universalnotifier.network.SMSSender.java