0

我是 android 新手,这是我的第一个项目,并且有点卡在HandlersFileObservers 上。该应用程序将观察文件系统上的一个文件夹,当文件被修改时,该文件夹内的新图像将显示在 UI 上。

目前代码没有中断,但我一直在摸不着头脑,为什么我在FileObserver类中调用的处理程序只触发一次。

如果我删除Handler调用并修改监视文件夹中的多个文件,FileObserver 会获取所有更改并记录相关消息。

但是就像前面提到的那样,当我允许Handler触发FileObserver时,它只会获取对监视文件夹的第一次更改,而随后什么也没有。

主要活动

private static ImageView imgMAX;
private static ImageView imgMIN;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    imgMAX = (ImageView)findViewById(R.id.imageViewMAX);
    imgMIN = (ImageView)findViewById(R.id.imageViewMIN);
    vidAD = (VideoView)findViewById(R.id.videoViewAD);

    //Sorting out media player playback options
            MediaPlayer.OnPreparedListener PreparedListener = new MediaPlayer.OnPreparedListener(){

                 @Override
                 public void onPrepared(MediaPlayer m) {
                     try {
                            if (m.isPlaying()) {
                                m.stop();
                                m.release();
                                m = new MediaPlayer();
                            }
                            m.setVolume(0f, 0f);
                            m.setLooping(true);
                            m.start();
                        } catch (Exception e) {
                            e.printStackTrace();
                        } 
                 }
             };

    //Set up media controller for videos
    MediaController mediaController = new MediaController(this);
    mediaController.setAnchorView(vidAD);
    vidAD.setMediaController(new MediaController(this));
    vidAD.setOnPreparedListener(PreparedListener);

    //Create Message Handler
     handler = new Handler(Looper.getMainLooper()) 
     { 
        @Override
        public void handleMessage(Message msg) { 
              String type = msg.getData().getString("typeoperation"); 
              String path = msg.getData().getString("path"); 

              Log.d("MESSAGE HANDLER", "Message Recieved: "+ type + " " + path); 

              String splitchar = "/";
              String[] parts = path.split(splitchar);
              String file = parts[parts.length-1];

                  if (file.equals("min.jpg")){
                      Bitmap bmp = BitmapFactory.decodeFile(path);
                      imgMIN.setImageBitmap(bmp);

                      PathFileObserver pfo = new     PathFileObserver(filepath,handler); 
                      pfo.startWatching();  
                  } else if (file.equals("max.jpg")){
                      Bitmap bmp = BitmapFactory.decodeFile(path);
                      imgMAX.setImageBitmap(bmp);

                      PathFileObserver pfo = new PathFileObserver(filepath,handler); 
                      pfo.startWatching();  
                  } else if (file.equals("video.mp4")){
                      vidAD.stopPlayback();
                      vidAD.setVideoPath(path);
                      vidAD.requestFocus();
                      vidAD.start();
                  }
              } 
     }; 

    //Check if Storage is available
    if(isExternalStorageReadable()){
        filepath = Environment.getExternalStorageDirectory()+File.separator;
        File f = new File(Environment.getExternalStorageDirectory());
        if(f.exists()){
            Bitmap bmp = BitmapFactory.decodeFile(filepath+"max.jpg");
            imgMAX.setImageBitmap(bmp);

            bmp = BitmapFactory.decodeFile(filepath+"min.jpg");
            imgMIN.setImageBitmap(bmp);

            vidAD.setVideoPath(filepath+"video.mp4");
            vidAD.requestFocus();
            vidAD.start();

            PathFileObserver pfo = new PathFileObserver(filepath,handler); 
            pfo.startWatching(); 
        }else{
            new AlertDialog.Builder(this).setTitle("Error").setMessage("Error Loading Content.").setNeutralButton("Close", null).show();
        }   
    }
}

文件观察者

public class PathFileObserver extends FileObserver{
static final String TAG="FILEOBSERVER";
String rootPath;

static final int mask = (FileObserver.CREATE | 
        FileObserver.DELETE | 
        FileObserver.DELETE_SELF |
        FileObserver.MODIFY |
        FileObserver.MOVED_FROM |
        FileObserver.MOVED_TO |
        FileObserver.MOVE_SELF |
        FileObserver.CLOSE_WRITE);
private Handler handler; 

public PathFileObserver(String root,Handler handler){
    super(root, mask);

    if (! root.endsWith(File.separator)){
        root += File.separator;
    }
    rootPath = root;
    this.handler = handler;
}

public void onEvent(int event, String path) {

    Message msg = Message.obtain(handler); 
    Bundle b = new Bundle(); 

    switch(event){
    case FileObserver.CREATE:
        Log.d(TAG, "CREATE:" + rootPath + path);
        break;
    case FileObserver.DELETE:
        Log.d(TAG, "DELETE:" + rootPath + path);
        break;
    case FileObserver.DELETE_SELF:
        Log.d(TAG, "DELETE_SELF:" + rootPath + path);
        break;
    case FileObserver.MODIFY:
        Log.d(TAG, "MODIFY:" + rootPath + path);
        break;
    case FileObserver.MOVED_FROM:
        Log.d(TAG, "MOVED_FROM:" + rootPath + path);
        break;
    case FileObserver.MOVED_TO:
        Log.d(TAG, "MOVED_TO:" + path);
        break;
    case FileObserver.MOVE_SELF:
        Log.d(TAG, "MOVE_SELF:" + path);
        break;
    case FileObserver.CLOSE_WRITE:
        Log.d(TAG, "CLOSE_WRITE:" + path);

            b.putString("typeoperation","CLOSE_WRITE"); 
            b.putString("path",rootPath + path); 
            msg.setData(b); 
            handler.sendMessage(msg); 

        break;
    default:
        // just ignore
        break;
    }

}

public void close(){
    super.finalize();
}
}

编辑

因此,经过更多的开发和处理视频视图后,我发现通过将FileObserver中的 onevent 更改为:

case FileObserver.CLOSE_WRITE:
        Log.d(TAG, "CLOSE_WRITE:" + path);

            b.putString("typeoperation","CLOSE_WRITE"); 
            b.putString("path",rootPath + path); 
            msg.setData(b); 
            handler.sendMessage(msg); 

        break;

并在我的处理程序上为VideoView填写代码:

else if (file.equals("video.mp4")){
  Toast.makeText(getBaseContext(), "Buffering New Video...", Toast.LENGTH_LONG).show();
      vidAD.stopPlayback();
          vidAD.setVideoPath(path);
          vidAD.requestFocus();
          vidAD.start();
}

当一个新视频被加载到文件夹中并被它加载的FileObserver拾取时,视频会按预期进行,然后如果我尝试在视频之后立即加载图像,FileObserver 会立即拾取新图像,而无需创建实例文件观察者。

4

0 回答 0