Android:如何在通过MTP连接时检测MediaStore的更改

6

我在使用MediaStore时遇到了很大的问题。我需要处理当通过MTP更改MediaStore时的事件。我已经为android.intent.action.MEDIA_SCANNER_FINISHED action创建了一个接收器, 但它仅适用于通用大容量存储(UMS)。由于MTP直接更改MediaStore数据库,所以不会启动扫描程序。

请问您能否帮助我检测这些事件?非常感谢您的任何帮助!

2个回答

12

我终于找到了解决办法。我尝试使用FileObserver,但是当你将其用于所有目录时...它会消耗相当多的内存。所以现在我正在使用ContentObserver,它运行良好:

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

变量mRunning的存在是有原因的,因为即使在调用unregisterContentObserver()后,onChange有时仍会被调用。

我正在使用这段代码来观察我想要观察的Uri,即MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,...


这个答案对于检测文件删除/替换非常有效,但是通过MTP添加新文件并没有触发Observer更改,至少在我的Nexus 7上是这样的。 - Juozas Kontvainis
嗯,对我来说在这个光标上的任何操作(即MTP)都有效。这个URI仅适用于音频文件,也许你应该指定另一个URI。 - Bhiefer

4
创建一个内容观察器类。
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();
    }
}

在您的活动中注册观察者

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

不要忘记在onDestroy()函数中取消注册观察者。
 this.getContentResolver().unregisterContentObserver(observer);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接