Android:通过 MTP 连接时如何检测 MediaStore 的变化

Posted

技术标签:

【中文标题】Android:通过 MTP 连接时如何检测 MediaStore 的变化【英文标题】:Android: How to detect a change in MediaStore when connected over MTP 【发布时间】:2012-09-14 20:19:00 【问题描述】:

我对 MediaStore 有很大的问题。当 MediaStore 通过 MTP 更改时,我需要处理事件。我已经有了android.intent.action.MEDIA_SCANNER_FINISHED 操作的接收器,但它仅对通用大容量存储(UMS)有用。扫描仪不会通过 MTP 启动,因为 MTP 会直接更改 MediaStore 数据库。

请您好心帮我如何检测此事件。非常感谢您的帮助!

【问题讨论】:

【参考方案1】:

我终于找到了解决办法。我尝试使用 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。

此代码与我想观察的 Uris 一起使用,即 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,...

【讨论】:

这个答案非常适合检测文件删除/文件替换,但通过 MTP 添加新文件不会触发观察者更改,至少对我在 Nexus 7 上而言 嗯,它适用于我对这个光标的任何操作(即 MTP)。此 uri 仅适用于音频文件,也许您应该指定另一个 URI。【参考方案2】:

创建一个内容观察者类

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

【讨论】:

以上是关于Android:通过 MTP 连接时如何检测 MediaStore 的变化的主要内容,如果未能解决你的问题,请参考以下文章

任何用于检测 MTP 设备的 Windows API?

与 Android 平板电脑刷新 MTP 连接?

Android Studio 连接真实手机

关于Android手机MTP模式连接的一些设置(win7和ubuntu下,以红米1s为例)

Android:检测 USB

使用 MTP 通过 Android Storage Access Framework / DocumentProvider 遍历目录层次结构的问题