简体   繁体   English

从外部存储中删除图像后,是否有办法立即获取图像的uri?

[英]Is there a way to get the uri of an image right after it is removed from external storage?

I'm coding a gallery app and for the first time when app is launched it scans the whole external storage to retrieve all image Uris and stores them in a database so for the later launches it can load them from its own db. 我正在编写一个图库应用程序,第一次启动该应用程序时,它将扫描整个外部存储以检索所有图像Uris,并将它们存储在数据库中,以便在以后的启动中可以从其自己的数据库中加载它们。 Now my question is, when an image is removed, how can I get the deleted image Uri to notify the gallery and update the database. 现在我的问题是,当删除图像时,如何获取已删除的图像Uri来通知图库并更新数据库。

I tried JobSchecular for the case when a new Image is added through the camera and it perfectly worked. 我尝试了JobSchecular的情况,这种情况是通过相机添加了新图像,并且效果很好。

here is the code. 这是代码。

public class MediaJobSchedulerService extends JobService {

    private static final int ASJOBSERVICE_JOB_ID = 999;

    // A pre-built JobInfo we use for scheduling our job.
    private static JobInfo JOB_INFO = null;

    public static int a(Context context) {
        int schedule = (context.getSystemService(JobScheduler.class)).schedule(JOB_INFO);
        Log.i("PhotosContentJob", "JOB SCHEDULED!");
        return schedule;
    }

    // Schedule this job, replace any existing one.
    public static void scheduleJob(Context context) {
        if (JOB_INFO != null) {
            a(context);
        } else {
            JobScheduler js = context.getSystemService(JobScheduler.class);
            JobInfo.Builder builder = new JobInfo.Builder(ASJOBSERVICE_JOB_ID,
                new ComponentName(context, MediaJobSchedulerService.class));
            builder.addTriggerContentUri(new JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1));
            builder.addTriggerContentUri(new JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1));
            builder.setTriggerContentMaxDelay(500);
            JOB_INFO = builder.build();
            js.schedule(JOB_INFO);
        }
    }


    @Override
    public boolean onStartJob(final JobParameters params) {
        // Did we trigger due to a content change?
        final Context context = this;
        if (params.getTriggeredContentAuthorities() != null) {
            if (params.getTriggeredContentUris() != null) {
                // If we have details about which URIs changed, then iterate through them
                // and collect either the ids that were impacted or note that a generic
                // change has happened.
                final Repository repo = Repository.getInstance(this);
                ArrayList<String> ids = new ArrayList<>();
                for (final Uri uri : params.getTriggeredContentUris()) {
                    if (uri != null) {

                        Handler handler = new Handler();
                        handler.post(new Runnable() {
                            @Override
                            public void run() {

                                if (!uri.toString().equals("content://media/external")) {
                                    Log.i("NEW_MEDIA", getRealPathFromUri(context, uri));
                                    repo.addImage(getRealPathFromUri(context, uri));
                                }
                            }
                        });
                    }
                }
                jobFinished(params, true); // see this, we are saying we just finished the job
                // We will emulate taking some time to do this work, so we can see batching happen.
                scheduleJob(this);
            }
        }
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return false;
    }

    public static String getRealPathFromUri(Context context, Uri contentUri) {
        Cursor cursor = null;
        try {
            String[] proj = {MediaStore.Images.Media.DATA};
            cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

}

but in case when the image is removed the Uri is missing. 但是如果删除了图片,Uri会丢失。

My great appreciation towards your help. 我非常感谢您的帮助。

Android doesn't have and event for this, but you can use and FileObserver . Android没有为此提供事件,但是您可以使用和FileObserver This will catch the deletion of a file. 这将捕获文件的删除。 Example: 例:

import android.os.FileObserver;
public class FileDeletedObserver extends FileObserver {
    public String absolutePath;
    public FileDeletedObserver(String path) {
        super(path, FileObserver.DELETE);
        absolutePath = path;
    }
    @Override
    public void onEvent(int event, String path) {
        if (path == null) {
            return;
        }

        if ((FileObserver.DELETE & event)!=0) {
            //handle deleted file
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM