Android: How to detect a change in MediaStore when connected over MTP

后端 未结 2 1074
暗喜
暗喜 2020-12-08 12:51

I have big problems with MediaStore. I need to handle events when MediaStore is changed over MTP. I already have a receiver for android.intent.action.MEDIA_SCANNER_FIN

相关标签:
2条回答
  • 2020-12-08 13:01

    Create a content observer class

    class MyObserver extends ContentObserver {
        public MyObserver(Handler handler) {
    
            super(handler);
        }
    
        @Override
        public void onChange(boolean selfChange) {
            this.onChange(selfChange, null);
        }
    
        @Override
        public void onChange(boolean selfChange, Uri uri) {
         doYourWorkHere();
        }
    }
    

    Register the observer in your activity

    Handler handler;
        MyObserver observer;
    handler = new Handler();
    observer = new MyObserver(handler);
            this.getContentResolver().
                    registerContentObserver(
                            MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                            true,
                            observer);
    

    Don't forget to unregister the observer in onDestroy() function

     this.getContentResolver().unregisterContentObserver(observer);
    
    0 讨论(0)
  • 2020-12-08 13:20

    I finally found a solution. I tried to use FileObserver but when you use it for all directories...it is quite memory consuming. So now I am using ContentObserver and it is working well:

    public static class UriObserver
    {
        private final Cursor mCursor;
        private final ContentObserver mObserver;
        private boolean mRunning = true;
    
        private class ObserverWithListener extends ContentObserver
        {
            private final OnChangeListener mListener;
    
            public ObserverWithListener(OnChangeListener listener)
            {
                super(new Handler());
    
                mListener = listener;
            }
    
            @Override
            public void onChange(boolean selfChange)
            {
                if (mRunning)
                {
                    log.d("Change triggered");
                    mListener.onChange();
                }
            }
        };
    
        public static UriObserver getInstance(ContentResolver contentResolver, Uri uri, OnChangeListener listener)
        {
            Cursor c = contentResolver.query(uri, new String[] { "*" }, null, null, null);
    
            if ((c = Dao.moveToFirst(c)) == null)
            {
                log.e("Cannot start observer for uri: " + uri);
                return null;
            }
    
            return new UriObserver(c, listener);
        }
    
        public UriObserver(Cursor c, final OnChangeListener listener)
        {
            mCursor = c;
            mObserver = new ObserverWithListener(listener);
            mCursor.registerContentObserver(mObserver);
        }
    
        public void stop()
        {
            mCursor.unregisterContentObserver(mObserver);
            Dao.closeCursor(mCursor);
            mRunning = false;
        }
    
        public interface OnChangeListener
        {
            public void onChange();
        }
    }
    

    The flag mRunning has to be there for some reason because onChange was sometimes called even if unregisterContentObserver() had been called before.

    This code I am using with Uris that I want to observe, i.e. MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, ...

    0 讨论(0)
提交回复
热议问题