2017-12-30 130 views
5

मैं पृष्ठभूमि में उपयोगकर्ता डिस्क पर एक फ़ोल्डर की निगरानी करने की कोशिश कर रहा हूं, जैसे आप JobScheduler और contentobserver के साथ गैलरी परिवर्तनों की निगरानी कैसे कर सकते हैं। मैं इसे किसी निर्दिष्ट निर्देशिका के लिए करना चाहता हूं। हालांकि, जब कोई निर्देशिका में कोई फ़ाइल बदलती है तो मैं प्रसारण प्राप्त करने का तरीका नहीं समझ सकता।पृष्ठभूमि में फ़ाइल परिवर्तनों के लिए फ़ोल्डर की निगरानी कैसे करें?

+2

'android.os.FileObserver'? – pskink

+0

पृष्ठभूमि में इसे स्वचालित रूप से ट्रिगर करने के तरीके पर एक उदाहरण दें @pskink –

+2

क्या आपने javadoc दस्तावेज़ पढ़ा था? यदि हां, तो आपको किस समस्याएं हैं? – pskink

उत्तर

2

बस एक ऐसी सेवा शुरू करें जो निर्दिष्ट निर्देशिका के लिए फ़ाइल परिवर्तनों का पता लगाने के लिए फ़ाइलब्सर्वर का उपयोग करे।

सेवा वर्ग:

public class FileObserverService extends Service { 
    private FileObserver mFileObserver; 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     if((intent.hasExtra(INTENT_EXTRA_FILEPATH))) // we store the path of directory inside the intent that starts the service 
     mFileObserver = new FileObserver(intent.getStringExtra(INTENT_EXTRA_FILEPATH)) { 
      @Override 
      public void onEvent(int event, String path) { 
       // If an event happens we can do stuff inside here 
       // for example we can send a broadcast message with the event-id   
       Log.d("FILEOBSERVER_EVENT", "Event with id " + Integer.toHexString(event) + " happened") // event identifies the occured Event in hex 
      } 
     }; 
     mFileObserver.startWatching(); // The FileObserver starts watching 
     return Service.START_NOT_STICKY; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     //TODO for communication return IBinder implementation 
     return null; 
    } 
} 

कहीं YOUR_FILEPATH/निर्देशिका के साथ अपने ऐप के अंदर से सेवा आप का पालन करना चाहते हैं शुरू करें:

कई चीजें
Intent intent = new Intent(this, FileObserverService.class); 
    intent.putExtra(INTENT_EXTRA_FILEPATH, "YOUR_FILEPATH"); 
    this.startService(intent); 
+0

यह उस भाग को याद करता है जहां मुझे किसी भी समय चलाने के लिए इसकी आवश्यकता होती है, इस पथ में फ़ाइल परिवर्तन होता है। कोई सेवा नहीं चल सकती 24/7 –

+0

यदि आपके पास कोई सेवा नहीं चल रही है, तो फर्मवेयर को संशोधित करने के अलावा, बाहरी स्टोरेज ऑपरेशंस की निरंतर निगरानी करने के लिए कोई विधि नहीं है। यहां तक ​​कि एक निर्मित सेवा संसाधनों पर भी कम हो सकती है। अन्य संभावना एक अलार्ममेनगर होगा जो उपयोगकर्ता द्वारा चुने गए मतदान अवधि के साथ समय-समय पर परिवर्तनों के लिए निर्देशिका स्कैन करता है, ताकि वे आपके ऐप द्वारा बैटरी और सीपीयू खपत को नियंत्रित कर सकें। लेकिन आप फ़ाइल परिवर्तन तुरंत पता लगाने में सक्षम नहीं हैं। – matthiasT

4

रहे हैं आप आदेश बनाने में क्या करना है एक प्रणाली व्यापक फ़ाइल पर्यवेक्षक।

सबसे पहले

आप एक सेवा है जो बूट पर शुरू होगा बनाने के लिए और निरंतर चलते रहने दिया जाएगा। इस के लिए आदेश में अपने Manifest

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

दूसरे

में अपने Manifest

public class StartupReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 

    Intent myIntent = new Intent(context, FileSystemObserverService.class); 
    context.startService(myIntent); 

    } 
} 

को RECEIVE_BOOT_COMPLETED अनुमति होने के लिए आप एक BroadcastReceiver बनाने के लिए है, रजिस्टर यह ACTION_BOOT_COMPLETED प्राप्त करने के लिए और सेवा को 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); 
        } 

       } 

     } 

यह इस कोड को आप पूरी फाइल सिस्टम का निरीक्षण करने में सक्षम हो जाएगा के साथ है कि करने के लिए प्राथमिकता सेट के साथ एक और धागा में अवलोकन चलाने के लिए है

+0

अगर सिस्टम फोरग्राउंड सेवा के रूप में नहीं चल रहा है तो क्या अंततः सिस्टम द्वारा सेवा को मार डाला नहीं जाएगा? –

संबंधित मुद्दे