如果文件已下载/添加到下载文件夹,则接收事件

Ant*_*hea 15 android download fileobserver

每当文件被添加到特定文件夹(例如下载文件夹)时,我都希望收到一个事件.为了达到这个目的,我尝试了3种不同的方法但没有成 目标设备是Android 15+.您是否对这3种方法中的任何一种方法有任何经验并且可以帮助提供工作样本?

方法1 - FileObserver:

在后台服务我添加了一个递归文件观察员顶层文件夹描述这里.在Android 4/5上它的工作但在Android 6上没有事件被触发(已知问题)最重要的是,在Android 4/5上,文件观察者似乎不可靠.在某些时候,会调用stopWatching()方法,从那时起不会收到任何事件.

在onStartCommand(..)的服务:

    new MyFileObserver(Constants.DOWNLOAD_PATH, true).startWatching();
Run Code Online (Sandbox Code Playgroud)

方法2 - 内容观察员:

我试图调整内容观察员我的使用情况(如描述在这里),但我从来没有收到任何事件.

在onStart服务:

 getContentResolver().registerContentObserver( Uri.parse("content://download/"), true,
            new MyObserver(myHandler));
Run Code Online (Sandbox Code Playgroud)

.

public class MyObserver extends ContentObserver {
  // left blank below constructor for this Contact observer example to work
  // or if you want to make this work using Handler then change below registering  //line
  public MyObserver(Handler handler) {
    super(handler);
  }

  @Override
  public void onChange(boolean selfChange) {
    this.onChange(selfChange, null);
    Log.e("", "~~~~~~ on change" + selfChange);
    // Override this method to listen to any changes
  }

  @Override
  public void onChange(boolean selfChange, Uri uri) {
    // depending on the handler you might be on the UI
    // thread, so be cautious!
    Log.e("", "~~~~~~ on change uri" + selfChange);
  }
}
Run Code Online (Sandbox Code Playgroud)

方法3 - BroadcastReceiver:

有了一个BroadcastReceiver我试图让ON_DOWNLOAD_COMPLETE_EVENT(如描述在这里.但什么也没有发生.

在服务的StartCommand(...)中:

 registerReceiver(new DownloadListenerService(), new IntentFilter(
            DownloadManager.ACTION_DOWNLOAD_COMPLETE));
Run Code Online (Sandbox Code Playgroud)

DownloadListenerService:

public class DownloadListenerService extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, Intent intent) {
        System.out.println("got here");
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = settings.edit();

        String action = intent.getAction();
        if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
            String downloadPath = intent.getStringExtra(DownloadManager.COLUMN_URI);
            editor.putString("downloadPath", downloadPath);
            editor.commit();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

表现:

  <receiver
            android:name=".DownloadListenerService"
            android:icon="@mipmap/ic_launcher"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
            </intent-filter>
        </receiver>
Run Code Online (Sandbox Code Playgroud)

Joh*_*fer 2

实际上,目前 Android 6.0 及更高版本还没有已知的解决方法。在 Android 4/5/5.1 中,FileObserver大部分工作正常,但对于 Android 6,当文件添加到外部目录时,您根本无法从系统获得任何类型的响应。知道这一点FileObserver在 Android 6 中完全没用。

但最终您可以使用 Content Observer 检测 Android 系统中添加的内容,该内容在 Android 6 中也运行良好。也许这可以解决您的问题,直到 Google 提供修复程序。

这就是我目前使用 ContenObserver 的方式:

mycontentobserver = new MyContentObserver(handler,**Your path**,this);
getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, mycontentobserver);
Run Code Online (Sandbox Code Playgroud)

与 MyContentOberserver.class 相比,我只检查特定路径中最后编辑的文件,如果它们不早于 5-10 秒,我认为这会触发 ContentObserver 事件。

更新编辑:

这对你来说应该是这样的:

在你的BackgroundService.class中:

mycontentobserver = new MyContentObserver(handler,**Your download folder path**,this);
getContentResolver().registerContentObserver(MediaStore.Files.getContentUri("external"), true, mycontentobserver);
Run Code Online (Sandbox Code Playgroud)

而不是在MyContentObserver.class内部:

public MyContentObserver(Handler handler, String workpath,  ContentModificationService workcontext) {
    super(handler);
    downloadfolderpath = workpath;
    contentcontext = workcontext;
}

@Override
public void onChange(boolean selfChange, Uri uri) {

   if(downloadfolderpath != null) {
      File file = new File(downloadfolder);
      if (file.isDirectory()) {
         listFile = file.listFiles();
         if (listFile != null && listFile.length > 0) {
            
            // Sort files from newest to oldest (this is not the best Method to do it, but a quick on)
            Arrays.sort(listFile, new Comparator<File>() {
               public int compare(File f1, File f2) {
               return      Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
               }
            });

            if (listFile[listFile.length - 1].lastModified() >= System.currentTimeMillis() - 5000) { //adjust the time (5000 = 5 seconds) if you want.

               //Some file was added !! Yeah!
               //Use the contentcontext to launch some Method in you Service
               //For example:
               contentcontext.SomeMethodToContinue();
            }
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

我希望这对您有帮助,如果它对您有用,请立即告诉我。它对我来说适用于 android 6.1 上的下载文件夹:)