我正在尝试在后台监视用户磁盘上的文件夹,就像您可以使用JobScheduler和contentobserver监视库更改一样.我想为任何指定的目录执行此操作.但是,当目录有任何文件更改时,我无法弄清楚如何接收广播.
解决方法
为了创建系统范围的文件观察器,您需要做几件事.
首先
您必须创建一个将在启动时启动并始终运行的服务.
为了实现这一点,你必须创建一个BroadcastReceiver,注册它以接收ACTION_BOOT_COMPLETED和RECEIVE_BOOT_COMPLETED权限给你的清单
public class StartupReceiver extends BroadcastReceiver { @Override public void onReceive(Context context,Intent intent) { Intent myIntent = new Intent(context,FileSystemObserverService.class); context.startService(myIntent); } }
在你的清单中
<manifest > <application > <service android:name=".FileSystemObserverService" android:enabled="true" android:exported="true" > </service> <!-- Declaring broadcast receiver for BOOT_COMPLETED event. --> <receiver android:name=".StartupReceiver" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> </application> <!-- Adding the permission --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> </manifest>
其次
该服务必须实现android.os.FileObserver类.由于android.os.FileObserver只观察您发送给它的路径并且没有观察路径的子目录,因此您必须扩展它并向其添加SingleFileObserver观察者.您还必须在优先级设置为低的另一个线程中运行观察
public class FileSystemObserverService extends Service { @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public int onStartCommand(Intent intent,int flags,int startId) { observe(); return super.onStartCommand(intent,flags,startId); } public File getInternalStoragePath(){ File parent=Environment.getExternalStorageDirectory().getParentFile(); File external=Environment.getExternalStorageDirectory(); File[] files =parent.listFiles(); File internal=null; if(files!=null){ for(int i=0;i<files.length;i++){ if(files[i].getName().toLowerCase().startsWith("sdcard")&&!files[i].equals(external)){ internal=files[i]; } } } return internal; } public File getExtenerStoragePath(){ return Environment.getExternalStorageDirectory(); } public void observe(){ Thread t=new Thread(new Runnable(){ @Override public void run() { //File[] listOfFiles = new File(path).listFiles(); File str=getInternalStoragePath(); if(str!=null){ internalPath=str.getAbsolutePath(); new Obsever(internalPath).startWatching(); } str=getExtenerStoragePath(); if(str!=null){ externalPath=str.getAbsolutePath(); new Obsever(externalPath).startWatching(); } }}); t.setPriority(Thread.MIN_PRIORITY); t.start(); } class Obsever extends FileObserver{ List<SingleFileObserver> mObservers; String mPath; int mMask; public Obsever(String path) { // TODO Auto-generated constructor stub this(path,ALL_EVENTS); } public Obsever(String path,int mask) { super(path,mask); mPath =path; mMask =mask; // TODO Auto-generated constructor stub } @Override public void startWatching() { // TODO Auto-generated method stub if(mObservers!=null) return; mObservers= new ArrayList<SingleFileObserver>(); Stack<String> stack= new Stack<String>(); stack.push(mPath); while(!stack.empty()){ String parent = stack.pop(); mObservers.add(new SingleFileObserver(parent,mMask)); File path = new File(parent); File[] files = path.listFiles(); if(files==null) continue; for(int i=0;i<files.length;++i){ if(files[i].isDirectory()&&!files[i].getName().equals(".")&&!files[i].getName().equals("..")){ stack.push(files[i].getPath()); } } } for(int i=0;i<mObservers.size();i++){ mObservers.get(i).startWatching(); } } @Override public void stopWatching() { // TODO Auto-generated method stub if(mObservers==null) return; for(int i=0;i<mObservers.size();++i){ mObservers.get(i).stopWatching(); } mObservers.clear(); mObservers=null; } @Override public void onEvent(int event,final String path) { if(event==FileObserver.OPEN){ //do whatever you want } else if(event==FileObserver.CREATE){ //do whatever you want } else if(event==FileObserver.DELETE_SELF||event==FileObserver.DELETE){ //do whatever you want } else if(event==FileObserver.MOVE_SELF||event==FileObserver.MOVED_FROM||event==FileObserver.MOVED_TO){ //do whatever you want } } private class SingleFileObserver extends FileObserver{ private String mPath; public SingleFileObserver(String path,int mask) { super(path,mask); // TODO Auto-generated constructor stub mPath=path; } @Override public void onEvent(int event,String path) { // TODO Auto-generated method stub String newPath=mPath+"/"+path; Obsever.this.onEvent(event,newPath); } } }