接收事件,如果文件已下载/已添加到下载文件夹 [英] Receiving Event, if a file was downloaded/ added to download folder

查看:112
本文介绍了接收事件,如果文件已下载/已添加到下载文件夹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无论何时将文件添加到特定文件夹(例如,下载文件夹。为此,我尝试了3种不同的方法,但均未成功。目标设备是Android 15+。您是否对这三种方法有任何经验,可以为您提供一个可行的示例?

I would like to receive an event whenever a file was added to a specific folder, e.g. the download folder. To reach this I tried 3 different approaches without any success. The target devices are Android 15+. Do you have any experience with any of these 3 approaches and could help out with a working sample?

APPROACH 1-FileObserver:

在后台服务中,如此处。在Android 4/5上可以正常运行,但在Android 6上则不会触发任何事件( 最重要的是,在Android 4/5上,文件查看器似乎并不可靠。在某些时候,将调用stopWatching()方法,此后将不再接收任何事件。

In a background service I add a recursive file observer for the top folder as described here. On Android 4/5 its working but on Android 6 no events are fired (known issue) On top of that it seems that on Android 4/5 the file observer is not reliable. At some point the stopWatching() method gets called and from then on no event will be received.

在服务的onStartCommand(..)中:

in onStartCommand(..) of the service:

    new MyFileObserver(Constants.DOWNLOAD_PATH, true).startWatching();

方法2-内容观察者:

我尝试调整用例的内容观察器(如此处),但我从未收到任何事件。

I tried to tweak the content observer for my use case (as described here), but I never receive any events.

在服务启动时:

 getContentResolver().registerContentObserver( Uri.parse("content://download/"), true,
            new MyObserver(myHandler));

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

方法3-BroadcastReceiver:

我使用BroadcastReceiver尝试获取ON_DOWNLOAD_COMPLETE_EVENT(如此处。但是什么也没发生。

With a BroadcastReceiver I try to get the ON_DOWNLOAD_COMPLETE_EVENT (as described here. But nothing happens.

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

in on StartCommand(...) of the service:

 registerReceiver(new DownloadListenerService(), new IntentFilter(
            DownloadManager.ACTION_DOWNLOAD_COMPLETE));

DownloadListenerService:

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

清单:

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


推荐答案

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

Actually, right now there is no known work-around for Android 6.0 and above. In Android 4/5/5.1 the FileObserver is working fine mostly, but for Android 6 you simply can't get any kind of response from the system when a file is added to an external directory. Knowing this FileObserver is completely useless in Android 6.

但是最终,您可以使用Content Observer来检测Android系统中添加的内容。在Android 6中也可以正常工作。也许这可以解决您的问题,直到Google提供修复程序为止。

But eventually you can detect added content in the Android system, with the Content Observer which is also working fine in Android 6. Maybe this can solve your problem until Google provides a fix.

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

This is how I currently use the ContenObserver:

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

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

An than the MyContentOberserver.class I just check for last edited files in my specific path and if they are not older than 5-10 seconds I assume that this triggered the ContentObserver Event.

这是为您工作的方式:

在您的 BackgroundService.class 中:

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

而不是在 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();
            }
         }
      }
   }
}

希望对您有所帮助,请让我现在使用。它适用于android 6.1上的下载文件夹:)

I hope this helps, let me now If it works for you. It work's for me with the download folder on android 6.1 :)

这篇关于接收事件,如果文件已下载/已添加到下载文件夹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆