public void startScan(final FileExtensionFilter filter, final String... paths) {
   if (inScan.compareAndSet(false, true)) {
     m_scanTask = new ScanTask(filter);
     m_scanTask.execute(paths);
   } else {
     m_scanTask.addPaths(paths);
   }
 }
 public void startScan(final FileExtensionFilter filter, final Collection<String> paths) {
   final String[] arr = paths.toArray(new String[paths.size()]);
   if (inScan.compareAndSet(false, true)) {
     m_scanTask = new ScanTask(filter);
     m_scanTask.execute(arr);
   } else {
     m_scanTask.addPaths(arr);
   }
 }
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null) {
      if (intent.hasExtra("isInstall") && intent.getStringExtra("isInstall").equals("true")) {
        packageName = intent.getStringExtra("packageName");
        ScanTask task =
            new ScanTask(getApplicationContext()) {
              @Override
              protected void onPreExecute() {}

              @Override
              protected void onPostExecute(ScanResult result) {
                showInstallNotification(result);
              }

              @Override
              protected void onProgressUpdate(String... values) {}
            };
        task.execute(packageName);
      }
      if (intent.hasExtra("isSetTime") && intent.getStringExtra("isSetTime").equals("true")) {
        // scan all activity
        ScanTask task =
            new ScanTask(getApplicationContext()) {
              @Override
              protected void onPreExecute() {}

              @Override
              protected void onPostExecute(ScanResult result) {
                showNotification(result);
              }

              @Override
              protected void onProgressUpdate(String... values) {}
            };
        task.execute();
      }
    }

    return super.onStartCommand(intent, flags, startId);
  }
  // see DirectoryScannerMXBean
  public void scan() {
    final ScanTask task;

    synchronized (this) {
      final LinkedList<File> list;
      switch (state) {
        case RUNNING:
        case SCHEDULED:
          throw new IllegalStateException(state.toString());
        case STOPPED:
        case COMPLETED:
          // only accept to scan if state is STOPPED or COMPLETED.
          list = new LinkedList<File>();
          list.add(rootFile);
          break;
        default:
          throw new IllegalStateException(String.valueOf(state));
      }

      // Create a new ScanTask object for our root directory file.
      //
      currentTask = task = new ScanTask(list, this);

      // transient state... will be switched to RUNNING when
      // task.execute() is called. This code could in fact be modified
      // to use java.util.concurent.Future and, to push the task to
      // an executor. We would then need to wait for the task to
      // complete before returning.  However, this wouldn't buy us
      // anything - since this method should wait for the task to
      // finish anyway: so why would we do it?
      // As it stands, we simply call task.execute() in the current
      // thread - brave and fearless readers may want to attempt the
      // modification ;-)
      //
      setStateAndNotify(SCHEDULED);
    }
    task.execute();
  }