0

Task: I want to delete files from MediaStore in a background thread, so the user can work with my app while the thread is working.


Problem: I know that every time when a process finishes, its threads finish their work as well. So, it means that I will not be able to delete all selected files from the MediaStore, if the user quickly closes the app, thus killing the process.

Possible solution: Do you think is it a good idea to implement that procedure as a separate process(task)? For example, using a Service.

Code:

 Snackbar.make(findViewById(R.id.rootView),message)
                    .setAction("UNDO", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                           //restore data
                        }
                    })
                    .addCallback(new BaseTransientBottomBar.BaseCallback<Snackbar>() {
                        @Override
                        public void onDismissed(Snackbar transientBottomBar, int event) {
                            super.onDismissed(transientBottomBar, event);
                            switch (event) {
                                case DISMISS_EVENT_SWIPE:
                                case DISMISS_EVENT_TIMEOUT:
                                    //delete the files using either a background thread, or a separate task
                                    break;
                            }
                        }
                    })
                    .show();


UPDATE:

 public static void deleteFile(Context context, File mediaFile) {
    if(!mediaFile.delete()) {
        Log.e(TAG, "Cannot delete file "+ mediaFile.getAbsoluteFile());

    }
    String[] projection = { MediaStore.Images.Media._ID };

    String selection = MediaStore.Images.Media.DATA + " = ?";
    String[] selectionArgs = new String[] { mediaFile.getAbsolutePath() };

    Uri queryUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    ContentResolver contentResolver = context.getContentResolver();
    Cursor cursor = contentResolver.query(queryUri, projection, selection, selectionArgs, null);

    if(cursor!=null) {
        if (cursor.moveToFirst()) {
            long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
            Uri deleteUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
            contentResolver.delete(deleteUri, null, null);
        }
        cursor.close();
    }
}

Thank you!

nullbyte
  • 1,178
  • 8
  • 16
  • How many files? This process is taking a significant amount of time? – weston Feb 04 '17 at 03:13
  • It depends. It can 10 or 1000. Basically, a user can delete the entire folder of files. – nullbyte Feb 04 '17 at 03:17
  • Does it take long to delete 1000 files? Particularly in a folder together. I guess you're not just deleting but updating the `MediaStore` too. – weston Feb 04 '17 at 03:19
  • It takes enough. If I want to delete 1000 files, and then I instantly close the app it will delete approximately 10-20 files. – nullbyte Feb 04 '17 at 03:23
  • Yes, that's correct, I am updating the `MediaStore` as well. I will post the code of this procedure now. – nullbyte Feb 04 '17 at 03:24

1 Answers1

1

Yes it sounds like a good candidate for a Service but when you say "as a separate process(task)" that is not what a Service is:

A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.

A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).

https://developer.android.com/reference/android/app/Service.html#WhatIsAService

This works because users do not generally close apps in a way that kills the process. Apps continue to run, even after all activities have been closed and even when swiped off of the recent apps list.

Community
  • 1
  • 1
weston
  • 54,145
  • 21
  • 145
  • 203
  • Yes, it's not. However, I can specify it as a separate process, right?That is exactly what I'm asking, does it worth doing so? – nullbyte Feb 04 '17 at 03:30
  • No, that would be harder and without any good reason. See my new edit. You can use the existing process because it sticks around after the activities have gone, particularly when there's a Service running. – weston Feb 04 '17 at 03:31
  • If I'm wrong about that however, and it's better to have it's own process, it's a simple conversion in the manifest apparently: http://stackoverflow.com/a/38318003/360211 – weston Feb 04 '17 at 03:35
  • This backs up what I am thinking though: http://stackoverflow.com/a/9434268/360211 – weston Feb 04 '17 at 03:37
  • Okay, thank you. One more question: what if users close the app during this procedure, and then reopen the app? They would still get a "stale" data because my app reads files from the `MediaStore` every time when it launches, and in this case it would provide users with wrong data, right? – nullbyte Feb 04 '17 at 03:38
  • Your app does that? or your Activity? – weston Feb 04 '17 at 03:41
  • Okay, it seems to me I start getting the sense of the problem. Thank you. – nullbyte Feb 04 '17 at 03:43
  • It's fine, but that's the difference, the Activity's getting created multiple times for each open and close, while the app is persisting throughout along with services you've started. I'm not sure what's best when it comes to this stale data problem. The only stale I see is service may already be about to delete files that user is being shown. In that case, you could find out from your service which files it still has to do and highlight them in the UI, or remove from UI. – weston Feb 04 '17 at 03:47
  • Yes, that is exactly what has just come to my mind. I can do the entire procedure using a `ProgressBar` as all other apps do, but details matter, right?:) – nullbyte Feb 04 '17 at 03:51
  • 1
    Yeah, when the activity starts, it can show the progress of any running delete service, sure. A notification progress would be excellent like this app does when copying files: https://play.google.com/store/apps/details?id=com.estrongs.android.pop&hl=en – weston Feb 04 '17 at 03:53