FIleObserver 和 ContentObserver 在 Android Marshmallow 中不起作用
Posted
技术标签:
【中文标题】FIleObserver 和 ContentObserver 在 Android Marshmallow 中不起作用【英文标题】:FIleObserver and ContentObserver not working in Android Marshmallow 【发布时间】:2016-07-14 05:38:29 【问题描述】:我遇到了 FIleObserver 和 ContentObserver 在 android Marshmallow 中无法正常工作的问题。我正在使用这个东西来检测文件夹内发生的变化。我为棉花糖设置了运行时权限。但在那之后它也没有显示任何事件。它在其他版本中完美运行。请帮我解决这个问题。
首先我尝试在 Service 中使用 Content Resolver 来检测后台文件夹的变化。
public class TestService extends Service
@Override
public void onCreate()
super.onCreate();
@Override
public int onStartCommand(Intent intent, int flags, int startId)
initial();
return START_STICKY;
public void initial()
getContentResolver().registerContentObserver(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
true,
new ContentObserver(new Handler())
@Override
public boolean deliverSelfNotifications()
Log.d("hai", "deliverSelfNotifications");
return super.deliverSelfNotifications();
@Override
public void onChange(boolean selfChange)
super.onChange(selfChange);
@Override
public void onChange(boolean selfChange, Uri uri)
if (uri.toString().matches(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString() + "/[0-9]+"))
Cursor cursor = null;
try
cursor = getContentResolver().query(uri, new String[]
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATA
, null, null, null);
if (cursor != null && cursor.moveToFirst())
final String fileName = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));
final String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
// TODO: apply filter on the file name to ensure it's screen shot event
Log.d("file", "FILE CHANGE OCCURED " + fileName + " " + path);
finally
if (cursor != null)
cursor.close();
super.onChange(selfChange, uri);
);
运行时权限为:
private void getPermission()
boolean hasPermission = (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermission)
ActivityCompat.requestPermissions(this,
new String[]Manifest.permission.READ_EXTERNAL_STORAGE,
REQUEST_READ_STORAGE);
并在onRequestPermissionsResult
中收到了该权限结果。
这种方法对我不起作用。所以我尝试在该服务中使用FileObserver
。那个时候它也适用于所有其他平台,但不是 Marshmallow。
【问题讨论】:
【参考方案1】:这似乎是 Marshmallow 中的一个错误,see here。
您只能尝试通过轮询您需要的任何信息来解决它。
这对您的效果如何取决于您的用例。我发现它可用于跟踪下载进度:下载开始时开始轮询,间隔为一秒,下载完成时停止。
如果您预计更改频率非常低,您可以尝试增加间隔 - 代价是更改发生与您的应用获取它们之间的延迟可能更高。
【讨论】:
以上是关于FIleObserver 和 ContentObserver 在 Android Marshmallow 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 10 中替换 FileObserver?
Inotify与Android文件监控FileObserver原理
Android 中关于 FileObserver类监听文件状态的实践