2010-03-16 25 views
2

我要听文件system.I发生变化之后的工作现在用 FileObserver.Here是我的代码:文件观察者停止一段时间

代码:

class MyDirObserver extends FileObserver { 
    String superPath; 
    public MyDirObserver(String path) { 
     super(path, ALL_EVENTS); 
     this.superPath = path; 
    } 


    public void onEvent(int event, String path) { 
     Log.e("onEvent of Directory", "=== onEvent ==="); 
     try { 
      _Dump("dir", event, path, superPath); 
     } catch (NullPointerException ex) { 
      Log.e("ERROR", "I am getting error"); 
     } 
    } 
} 


private void _Dump(final String tag, int event, String path, String superPath) { 
    Log.d(tag, "=== dump begin ==="); 
    Log.d(tag, "path=" + path); 
    Log.d(tag, "super path=" + superPath); 
    Log.d(tag, "event list:"); 
    if ((event & FileObserver.OPEN) != 0) { 
     Log.d(tag, " OPEN"); 
    } 
    if ((event & FileObserver.CLOSE_NOWRITE) != 0) { 
     Log.d(tag, " CLOSE_NOWRITE"); 
    } 
    if ((event & FileObserver.CLOSE_WRITE) != 0) { 


     Log.d(tag, " CLOSE_WRITE"); 
     Log.i("NEWFILEOBSERVER", "File is Modified"); 
     if (path != null) { 
      Log.d("---------FilePath", superPath + path); 
     } 


    } 
    if ((event & FileObserver.CREATE) != 0) { 
     isCreate = true; 
     Log.i("NEWFILEOBSERVER", "File is Created "); 
     if (path != null) { 
      Log.d("---------FilePath", superPath + path); 
     } 
     Log.d(tag, " CREATE"); 


    } 
    if ((event & FileObserver.DELETE) != 0) { 
     Log.i("NEWFILEOBSERVER", "File is deleted"); 
     if (path != null) { 
      Log.d("---------FilePath", superPath + path); 
     } 
     // startMyActivity("A new file is deleted thats="+superPath); 


     Log.d(tag, " DELETE"); 


    } 

    if ((event & FileObserver.DELETE_SELF) != 0) { 
     Log.d(tag, " DELETE_SELF"); 
    } 

    if ((event & FileObserver.ACCESS) != 0) { 
     Log.d(tag, " ACCESS"); 
    } 

    if ((event & FileObserver.MODIFY) != 0) { 
     if (!isModified) 
      isModified = true; 

     if (isModified && isOpen) 
      isAgainModified = true; 
     Log.d(tag, " MODIFY"); 
    } 

    if ((event & FileObserver.MOVED_FROM) != 0) { 
     Log.d(tag, " MOVED_FROM"); 
     if (path != null) { 
      Log.d("---------FilePath", superPath + path); 
     } 
    } 

    if ((event & FileObserver.MOVED_TO) != 0) { 
     Log.d(tag, " MOVED_TO"); 
     if (path != null) { 
      Log.d("---------FilePath", superPath + path); 
     } 
    } 

    if ((event & FileObserver.MOVE_SELF) != 0) { 
     Log.d(tag, " MOVE_SELF"); 
    } 

    if ((event & FileObserver.ATTRIB) != 0) { 
     Log.d(tag, " ATTRIB"); 
    } 

    Log.d(tag, "=== dump end ==="); 
} 

它经过一番停止time.I没有得到确切的时间,但没有 总是工作,虽然我在一个循环中调用startWatching()服务,该循环运行sdcard的所有文件夹,并为每个文件夹调用startWatching()。它显示不可预知的行为,并停止监听某些文件夹,并完美地运行其他文件夹。

我希望你们帮助我。我尝试了很多方法,但它完美地不起作用 。难道我做错了什么?或者还有其他方式可以做到这一点。

+0

你确定观察员还活着吗?他们运行什么线程?也许他们被垃圾堆砌机毁坏了? – cboese 2010-03-25 23:42:30

+0

你有没有得到任何解决方案? – 2016-09-20 05:58:49

回答

8

http://developer.android.com/reference/android/os/FileObserver.html

警告:如果FileObserver是垃圾回收,它会停止发送事件。为确保您继续接收事件,您必须保留对某个其他活动对象的FileObserver实例的引用。

+2

在我的情况下,观察员仍然活着,但在收到32768事件后,他们没有收到任何事件。重启设备后,一切正常,但重新启动应用程序问题重现。受影响在4.4以上Android – iscariot 2014-06-10 12:10:32

+0

@iscariot在此处查看错误:https://code.google.com/p/android/issues/detail?id=29546 – StenaviN 2014-06-11 16:32:32

+0

这是GC中的一个错误,它会杀死观察者 – iscariot 2014-06-12 14:18:59

0

尝试将引用链接到您的Application类中的Observer。 这样的

private ArrayList<FileObserver> mObservers = new ArrayList<FileObserver>(); 

public void addObserver(FileObserver observer){ 
    mObservers.add(observer); 
} 

public void removeObserver(FileObserver observer){ 
    mObservers.remove(observer); 
} 

这对我有用!

0

将FileObserver声明为静态和全局,它将保留Fileobserver的实例并限制OS将服务接入垃圾回收器。

0

我会在您的应用程序中为您呈现部分代码,该代码会将您用手机拍摄的每张照片发送至预定义的电子邮件列表。发送电子邮件和接收电子邮件列表存储在共享首选项中。我使用Service类和FileObserver来观看手机的图片目录。 在我的情况下,这个方案也使用了FileObserver的问题,它在一段时间后会停止工作。

  1. 使用活动(StartServicesActivity)作为Foreground服务启动服务(FileObserverService)。
  2. 使用BroadcastReceiver类(在示例CommonReceiver中)在某些特殊情况下重新启动服务,并在它被杀死的情况下。
  3. 每次服务重新启动时(执行onStartCommand)重新创建FileObserver对象以观看图片目录。

我用这个代码在我的应用 “通过电子邮件自动图片” https://play.google.com/store/apps/details?id=com.alexpap.EmailPicturesFree

这里是CommonReceiver类。

public class CommonReceiver extends BroadcastReceiver { 

    public void onReceive(Context paramContext, Intent paramIntent) 
    { 
     paramContext.startService(new Intent(paramContext, FileObserverService.class)); 
    } 
} 

下面是它在应用程序结束标记之前的AndroidManifest.xml中的定义。

<receiver android:name="com.alexpap.services.CommonReceiver"> 
    <intent-filter> 
     <action android:name="android.intent.action.BOOT_COMPLETED"/> 
    </intent-filter> 
    <intent-filter> 
     <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> 
    </intent-filter> 
    <intent-filter> 
     <action android:name="android.intent.action.USER_PRESENT"/> 
    </intent-filter> 
</receiver> 

在StartServicesActivity活动中启动服务。

Intent iFileObserver = new Intent(StartServicesActivity.this, FileObserverService.class); 
StartServicesActivity.this.startService(iFileObserver); 

以下是服务FileObserverService的onCreate()方法。

//Class variables 
MediaFileObserver observPictures = null; 
String pathToWatchPic = ""; 

public void onCreate() { 

    pathToWatchPic = Environment.getExternalStorageDirectory().toString() + "/DCIM/100MEDIA";  

    File mediaStorageDir = new File(pathToWatchPic); 
    if (!mediaStorageDir.exists()){ 
     pathToWatchPic = Environment.getExternalStorageDirectory().toString() + "/DCIM/Camera"; 
    } 

} 

这是服务FileObserverService的onStartCommand()方法。

public int onStartCommand(Intent intent, int flags, int startId) { 

    int res = super.onStartCommand(intent, flags, startId); 

    if (observPictures != null){ 
     observPictures.stopWatching(); 
    } 
    //each time service is restarted, observPictures object is recreated 
    //and observation is restarted. This way File Observer never stops. 
    observPictures = new MediaFileObserver(this, pathToWatchPic); 
    observPictures.startWatching(); 

    startServiceForeground(intent, flags, startId); 

    return Service.START_STICKY; 
} 

public int startServiceForeground(Intent intent, int flags, int startId) { 

    Intent notificationIntent = new Intent(this, StartServicesActivity.class); 
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 

    Notification notification = new NotificationCompat.Builder(this) 
     .setContentTitle("File Observer Service") 
     .setContentIntent(pendingIntent) 
     .setOngoing(true) 
      .build(); 

    startForeground(300, notification); 

    return START_STICKY; 
} 

每次打开手机并重新启动后,服务也会重新启动。