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

问题描述 投票:0回答:3

我在使用 MediaStore 时遇到了很大的问题。当 MediaStore 通过 MTP 更改时,我需要处理事件。我已经有一个用于

android.intent.action.MEDIA_SCANNER_FINISHED
操作的接收器,但它仅对通用海量存储 (UMS) 有用。扫描仪不是通过 MTP 启动的,因为 MTP 直接更改 MediaStore 数据库。

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

android events action mediastore mtp
3个回答
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。

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


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

0
投票

无论您是否选择退出范围存储,接受的解决方案都不适用于 Android 版本 10(但适用于所有其他版本)

如果您忘记在清单中添加 ACCESS_MEDIA_LOCATION 权限,@sujith-s-manjavana 给出的解决方案也不适用于 Android 版本 10(但适用于所有其他 Android 版本):

<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>

我无法添加评论或投票,因此将其添加为答案,这样如果有人在 Android 10 上遇到同样的问题,无需在互联网上搜索即可在此页面上获得解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.