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

后端 未结 2 1076
暗喜
暗喜 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: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, ...

提交回复
热议问题