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

给你一囗甜甜゛ 提交于 2019-12-17 18:11:06

问题


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_FINISHED action, but it is useful only for Universal Mass Storage(UMS). The scanner is not launched over MTP, because the MTP changes the MediaStore database directly.

Please would you be so kind and help me how to detect this events. Thank you very much for any help!


回答1:


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, ...




回答2:


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);


来源:https://stackoverflow.com/questions/12546967/android-how-to-detect-a-change-in-mediastore-when-connected-over-mtp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!