Android Open Source - AndroidCloud Observer Service






From Project

Back to project page AndroidCloud.

License

The source code is released under:

GNU General Public License

If you think the Android project AndroidCloud 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.twlkyao.androidcloud;
/*from  w  w w.j av  a2s .  co m*/
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Stack;

import com.twlkyao.utils.LogUtils;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileObserver;
import android.os.IBinder;

public class ObserverService extends Service {
  private FileObserver mFileObserver;
  private ServiceBinder serviceBinder;
  
  private boolean debug = false; // Indicate whether is debug.
  private String tag = "ObserverService";
  private LogUtils logUtils = new LogUtils(debug, tag);
  private NotificationManager notificationManager; // NotificationManager.
  private int notification_number = 0; // The number of notifications.
  
  /** Called when the activity is first created. */
  @Override
  public void onCreate() {
    super.onCreate();
    
    if(null == mFileObserver) {
      String filePath = Environment.getExternalStorageDirectory().getPath();
      
      mFileObserver = new RecursiveFileObserver(filePath); // mine
      mFileObserver.startWatching(); // Start watching.
    }
    
    notificationManager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE);
  }
  
  @Override
  public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
//    return serviceBinder;
    return null; // Service not being allowed to bind.
  }
  
  @Override
  public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    if(null != mFileObserver) mFileObserver.stopWatching(); //Stop watching.
  }

  class ServiceBinder extends Binder {
    public ObserverService getService() {
      return ObserverService.this;
    }
  }


  /**
   * Monitor all events under certain directory recursively, can't monitor the hiden directory such as ".a".
   * @author NetWork 
   * @editor Shiyao Qi
   * @date 2014.1.10
   * @email qishiyao2008@126.com
   * @attention
   *       You should protect the FileObserver not to be garbage collected,
   *       or it will not be able to detect the file or directory changes.
   */
  class RecursiveFileObserver extends FileObserver {
    
    ArrayList<SingleFileObserver> mObservers; // An ArrayList of SingleFileObservers to observer files. 
    String mPath; // The file path to be observed.
    int mMask; // Observation mask, specify the file operation that we want to monitor.
    
    /**
     * Constructor, that monitor all the events.
     * @param path The file path to monitor.
     */
    public RecursiveFileObserver(String path) {
      this(path, ALL_EVENTS); // Call the RecursiveFileObserver(String path, int mask) constructor.
    }
    
    /**
     * Constructor, that monitor the specified events that specified by mask.
     * @param path The file or directory to monitor.
     * @param mask The event or events (added together) to monitor.
     */
    public RecursiveFileObserver(String path, int mask) {
      super(path, mask); // Call super().
      mPath = path; // Initial mPath.
      mMask = mask; // Initial mMask.
    }
    
    @Override
    public void startWatching() {
      if (mObservers != null) // There are FileObservers working.
        return;
      
      // Instance a ArrayList<SingleFileObersver> if the mObservers is null.
      mObservers = new ArrayList<SingleFileObserver>();
      Stack<String> stack = new Stack<String>(); // Used to construct and store the full file path.
      stack.push(mPath);
      
      // Add all the files under mPath directory to FileObserver.
      while (!stack.isEmpty()) { // There are still file path in the stack.
        String parent = (String)stack.pop(); // Pop the top element as a file path.
        mObservers.add(new SingleFileObserver(parent, mMask)); // Add the file path to file observer.
        File path = new File(parent); // Construct a file according to the file path.
        File[] files = path.listFiles(); // Get all the files under the file path.
        
        /**
         * (1)the file is not a directory
         * (2)the file does not exist
         * (3)the directory is read-protected
         * (4)there is a IO error.
         * if the directory is empty the result will be zero.
         */
        if (null == files)
          continue;
        // Recursively look through the directory.
        for (File f : files) {
          // Push the subdirectories' path under the file path to stack for future use.
          if (f.isDirectory() && !f.getName().equals(".") // The directory is neither the current directory nor the parent directory.
              && !f.getName().equals("..")) {
            stack.push(f.getPath());
          }
        }
      }
      
      // All the files under specified directory startWathching().
      for (int i = 0; i < mObservers.size(); i++) {
        SingleFileObserver sfo = (SingleFileObserver) mObservers.get(i);
        sfo.startWatching();
      }
    };
    
    @Override
    public void stopWatching() {
      if (mObservers == null) // All FileObservers are stopped.
        return;
      
      // Stop all FileObservers's watching.
      for (int i = 0; i < mObservers.size(); i++) {
        SingleFileObserver sfo = (SingleFileObserver) mObservers.get(i);
        sfo.stopWatching();
      }
      
      mObservers.clear(); // Remove all the FileObservers.
      mObservers = null; // Set the ArrayList to null.
    };
    
    /**
     * Monitor the event of file under specified file path specified by path pararm.
     * @param event The type of event which happened
     * @param path The path, relative to the main monitored file or directory, of the file or directory which triggered the event
     */
    /**
     * ACCESS ????????
     * MODIFY ?????
     * ATTRIB ????????? chmod??chown??touch ?
     * CLOSE_WRITE ??????????
     * CLOSE_NOWRITE ????????????
     * OPEN ?????
     * MOVED_FROM ???????????????? mv
     * MOVED_TO ??????????????? mv??cp
     * CREATE ?????????
     * DELETE ????????????????? rm
     * DELETE_SELF ??????????????????????????????????????????
     * MOVE_SELF ????????????????????????????????????????
     * CLOSE ???????????????????(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
     * ALL_EVENTS ? ???????????
     */
    /**
     * ACCESS  Event typic_notification_clear_alle: Data was read from a file, constant value 1.
     * MODIFY  Event type: Data was written to a file, constant value 2.
     * ATTRIB  Event type: Metadata (permissions, owner, timestamp) was changed explicitly, constant value 4
     * CLOSE_NOWRITE  Event type: Someone had a file or directory open read-only, and closed it, Constant value 8
     * CLOSE_WRITE  Event type: Someone had a file or directory open for writing, and closed it, constant value 16
     * OPEN  Event type: A file or directory was opened, Constant value 32
     * MOVED_FROM  Event type: A file or subdirectory was moved from the monitored directory, constant value 64
     * MOVED_TO  Event type: A file or subdirectory was moved to the monitored directory, constant value 128
     * CREATE  Event type: A new file or subdirectory was created under the monitored directory, constant value 256
     * DELETE  Event type: A file was deleted from the monitored directory, Constant value 512
     * DELETE_SELF  Event type: The monitored file or directory was deleted; monitoring effectively stops, constant value 1024
     * MOVE_SELF  Event type: The monitored file or directory was moved; monitoring continues, constant value 2048
     * ALL_EVENTS  Event mask: All valid event types, combined, Constant value 4095
     */
    /**
     * This method is invoked on a special FileObserver thread.
     * It runs independently of any threads,
     * so take care to use appropriate synchronization!
     * Consider using post(Runnable) to shift event
     * handling work to the main thread to avoid concurrency problems.
     */
    @Override
    public void onEvent(int event, String path) { // The path here is a full path.
      
      // The param is the value | 0x40000000, before operate, first & FileObserver.ALL_EVENTS
      switch (event & FileObserver.ALL_EVENTS) {
      
      // If you want to do some time-costing work under onEvent, you'd better use a thread,
      // in case for that you will not receive the following event.
        case FileObserver.ACCESS: // 1
          logUtils.d(tag, "ACCESS: " + path);
          break;
        case FileObserver.MODIFY: // 2
          logUtils.d(tag, "MODIFY: " + path);
          break;
        case FileObserver.ATTRIB: // 4
          logUtils.d(tag, "ATTRIB: " + path);
          break;
        case FileObserver.CLOSE_NOWRITE: // 8
          logUtils.d(tag, "CLOSE_NOWRITE: " + path);
          break;
        case FileObserver.CLOSE_WRITE: // 16
          logUtils.d(tag, "CLOSE_WRITE: " + path);
          if(path.endsWith(".apk")) {
            Notification notification = new Notification(android.R.drawable.ic_dialog_info,
                path, System.currentTimeMillis());
            notification.flags = Notification.FLAG_AUTO_CANCEL; // The notification should be canceled when click the Clear all button.
            Intent i = new Intent(getApplicationContext(), ApkValidate.class);
            Bundle bundle = new Bundle();
            bundle.putString("filepath", path);
            i.putExtras(bundle);
            logUtils.d(tag, path);
            
            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
            //PendingIntent
            PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),
                0,
                i,
                PendingIntent.FLAG_UPDATE_CURRENT);
            
            notification.setLatestEventInfo(
                    getApplicationContext(),
                    getString(R.string.apk_downloaded),
                    path,
                    contentIntent);
            notificationManager.notify(notification_number++, notification);
          }
          break;
        case FileObserver.OPEN: // 32
          logUtils.d(tag, "OPEN: " + path);
          break;
        case FileObserver.MOVED_FROM: // 64
          logUtils.d(tag, "MOVED_FROM: " + path);
          break;
        case FileObserver.MOVED_TO: // 128
          logUtils.d(tag, "MOVED_TO: " + path);
          break;
        case FileObserver.CREATE: // 256
          logUtils.d(tag, "CREATE: " + path);
          break;
        case FileObserver.DELETE: // 512
          logUtils.d(tag, "DELETE: " + path);
          break;
        case FileObserver.DELETE_SELF: // 1024
          logUtils.d(tag, "DELETE_SELF: " + path);
          break;
        case FileObserver.MOVE_SELF: // 2048
          logUtils.d(tag, "MOVE_SELF: " + path);
          break;
        default: //FileObserver.ALL_EVENTS: // 4095
          logUtils.d(tag, "ALL_EVENTS: " + path);
          break;
      }
    }
    
    /**
     * Monitor single directory and dispatch all events to its parent, with full path.
     */
    class SingleFileObserver extends FileObserver {
      String mPath; // The file path to observer.
      
      public SingleFileObserver(String path) {
        this(path, ALL_EVENTS); // Call the SingleFileObserver(String path, int mask).
        mPath = path;
      }  
      
      public SingleFileObserver(String path, int mask) {
        super(path, mask);
        mPath = path;
      }
      
      @Override
      public void onEvent(int event, String path) {
        if(!mPath.endsWith(File.separator)) { // Fix the mPath string.
          mPath += File.separator;
        }
        String newPath = mPath + path; // Construct the full path.
        
        // To unify the operation on the file event.
        RecursiveFileObserver.this.onEvent(event, newPath); // Call the RecursiveFileObserver with the full path.
      }
    }
  }
  
  /**
   * Filter the files according to the specified suffix of file.
   * @author NetWork
   * @editor Shiyao Qi
   * @date 2013.1.10
   * @email qishiyao2008@126.com
   */
  class myFileFilter implements FileFilter{
    String filter; // The file filter flag.
    
    /**
     * Constructor.
     * @param filter The file filter flag to use.
     */
    public myFileFilter(String filter) {
      this.filter = filter;
    }

    @Override
    public boolean accept(File pathname) {
      // TODO Auto-generated method stub
    
      String filename = pathname.getName().toLowerCase(); // Get the file name and lower it.
      if(filename.contains(filter)){ // Filter the file according to their names.
        return false;
      }else{
        return true;
      }
    }
  }
}




Java Source Code List

com.twlkyao.androidcloud.ApkValidate.java
com.twlkyao.androidcloud.ContactsActivity.java
com.twlkyao.androidcloud.FileListAdapter.java
com.twlkyao.androidcloud.KuaipanDiskActivity.java
com.twlkyao.androidcloud.LoginActivity.java
com.twlkyao.androidcloud.MainActivity.java
com.twlkyao.androidcloud.MessageActivity.java
com.twlkyao.androidcloud.ObserverService.java
com.twlkyao.androidcloud.RegisterActivity.java
com.twlkyao.androidcloud.SetEncryptLevelActivity.java
com.twlkyao.androidcloud.StartUpReceiver.java
com.twlkyao.dao.DaoMaster.java
com.twlkyao.dao.DaoSession.java
com.twlkyao.dao.FileInfoDao.java
com.twlkyao.dao.FileInfo.java
com.twlkyao.kuaipan.DownloadTask.java
com.twlkyao.kuaipan.MkdirTask.java
com.twlkyao.kuaipan.RequestBase.java
com.twlkyao.kuaipan.ResultBase.java
com.twlkyao.kuaipan.TransportListener.java
com.twlkyao.kuaipan.UploadTask.java
com.twlkyao.utils.ApkOperation.java
com.twlkyao.utils.ConstantVariables.java
com.twlkyao.utils.ExportSms.java
com.twlkyao.utils.FileDEncryption.java
com.twlkyao.utils.FileOperation.java
com.twlkyao.utils.ImportSms.java
com.twlkyao.utils.LogUtils.java
com.twlkyao.utils.SmsField.java
com.twlkyao.utils.SmsItem.java
com.twlkyao.utils.StringSplice.java