Force media scanner on deleted file

lymey

Active Member
Licensed User
I am writing an app that deletes an image from the Camera directory.
That works fine, and my app can re-list the files and the file is no longer present.

BUT the problem is that the device default gallery/album still shows the image thumbnail and the image when you click on it.

Once the media scanner runs again....i.e when you switch the device off then on, then the image is correctly gone from the gallery/album.

How can I force the media scanner to run and update the device gallery/album in real time?

The following code only causes a broken image thumbnail in the device gallery/album and the image cannot be displayed. But its not very elegant.

B4X:
Log("Delete the original file: " & filepath & filename)
File.Delete(filepath, filename)
 'try and force the media scanner to refresh
Dim i As Intent
i.Initialize("android.intent.action.MEDIA_SCANNER_SCAN_FILE", "file://" & File.Combine(filepath, filename))
Dim p As Phone
p.SendBroadcastIntent(i)
Bottom line question then:
How do I make the media scanner rescan and display the correct images in the device gallery/album in real time?
 

lymey

Active Member
Licensed User
Actually its worse

What I have just discovered that, the scan of the file only appears to work once. So I can force a scan of a file, it causes a broken image in the Gallery/Album, but when I try a second time, the scan of the file leaves the thumbnail and image behind.
:BangHead:
 

lymey

Active Member
Licensed User
Success

Thanks Erel,
I just changed the code to:
B4X:
File.Delete(filepath, filename)
 'try and force the media scanner to refresh
Dim i As Intent
' i.Initialize("android.intent.action.MEDIA_SCANNER_SCAN_FILE", "file://" & File.Combine(filepath, filename)) i.Initialize("android.intent.action.MEDIA_MOUNTED", "file://" & File.DirRootExternal)
Dim p As Phone
p.SendBroadcastIntent(i)
And it works like a charm!
Thank you!!
 

lymey

Active Member
Licensed User
I mean:

B4X:
File.Delete(filepath, filename)
'try and force the media scanner to refresh
Dim i As Intent
i.Initialize("android.intent.action.MEDIA_MOUNTED", "file://" & File.DirRootExternal)
Dim p As Phone
p.SendBroadcastIntent(i)
 

frankb4a

Member
Licensed User
nice ist works at my rooted HTC One X and my HTC One m7 (not rooted), but NOT at my Nexus 10 (not rooted).

It gives me an Error:
Java.lang.SecurityExeption: Permission Denial not allowed to send broadcast android.intent.action.MEDIA_Mounted from pid....

Edit: i tried "Rescan-Media" from Playstore, and it also Crash at start at my Nexus 10.
is this a config thingy ? or cause it's not a phone ?
 
Last edited:

Erel

Administrator
Staff member
Licensed User
Seems like this method will not work with Android 4.4+ (or maybe 4.3)

Try this code instead:
B4X:
Dim context As JavaObject
context = context.InitializeStatic("anywheresoftware.b4a.BA").GetField("applicationContext")
Dim paths() As String = Array As String(File.Combine(...)) 'files to scan
Dim mediaScanner As JavaObject
mediaScanner.InitializeStatic("android.media.MediaScannerConnection")
mediaScanner.RunMethod("scanFile", Array As Object(context, paths, Null, Null))
Requires JavaObject v1.00.
 

frankb4a

Member
Licensed User
thanks !
but with the same result. Works on the Phones (4.11 and 4.3), but not at the Tablet (4.4.2).

B4X:
Dim context As JavaObject
context = context.InitializeStatic("anywheresoftware.b4a.BA").GetField("applicationContext")
Dim paths() As String = Array As String(File.DirRootExternal) 'files to scan
Dim mediaScanner As JavaObject
mediaScanner.InitializeStatic("android.media.MediaScannerConnection")
mediaScanner.RunMethod("scanFile", Array As Object(context, paths, Null, Null))
I only exchanged file.combine to File.DirRootExternal which works at the Phone like a charm.
But at the Phone the DirRootExternal is = /storage/sdcard0 and at Tablet it's /storage/emulated/0 . may thats the Problem ???
 
Last edited:

frankb4a

Member
Licensed User
up to now, i tried many things to fix it, but i had no luck.

I got it working only at my phone, not at the tablet. But i got no error anymore. It goes through as it did it, but it doesn't.

btw. at the tablet i am the Admin and i have two extra users (Wife, Dau). The Phone's have only single Admins.
 

frankb4a

Member
Licensed User
thanks !

i guessed it and had a try after i posted here.

But the scan by a "single File" works only at the Tablet (4.4) not at the Phone (4.1 / 4.3)

The Phones work fine with File.DirRootExternal as "all over" in the end of the Routine.

Well, i do now both to capture both worlds.

Frank
 

frankb4a

Member
Licensed User
additional to my last post.

1. It means, on >= 4.4 there is no "over all" scan possible anymore.

2. "scanFile" runs async, so i have now to wait a longer while at the end of my scanprocess
before i Exit the App.
If i do quit to early, the scan process is interupted and the file entries are not removed from the Gallerie.
if i give it 30 sec., all is fine.

I've seen "android.media.MediaScannerConnection" has a, right now not used, Callback at "scanFile".
Can we use this callback, and how ?
 

slydog43

Member
Licensed User
I'm having trouble with my program that has 2 activities in it. 1st one browses through a database and displays a pic. If I click on the camera button it goes to another activity and takes a picture. the program is the at the picture is not getting updated on my 1st activity. If I end the program and rerun it it shows the new pic. my pics are being stored in \\mypics on the sd card

here are the 3 methods that I tried, but nothing seemed to work.

any ideas (erel?) Does it have to do with storing them in the sd card?

myDir = File.DirRootExternal & "/myPics/"
myPicFilename = "1.jpg"


'send a broadcast intent to the media scanner to force it to scan the saved file.
Dim Phone As Phone
Dim i As Intent
i.Initialize("android.intent.action.MEDIA_SCANNER_SCAN_FILE", _
"file://" & File.Combine(myDir, myPicFilename))
Phone.SendBroadcastIntent(i)
'------------------------------------------------

' Dim i As Intent
' i.Initialize("android.intent.action.MEDIA_MOUNTED", "file://" & File.Combine(myDir, myPicFilename))
' Dim p As Phone
' p.SendBroadcastIntent(i)
'----------------------------------------------

' Dim context As JavaObject
' context = context.InitializeStatic("anywheresoftware.b4a.BA").GetField("applicationContext")
' Dim paths() As String = Array As String(File.Combine(myDir, myPicFilename)) 'files to scan
' Dim mediaScanner As JavaObject
' mediaScanner.InitializeStatic("android.media.MediaScannerConnection")
' mediaScanner.RunMethod("scanFile", Array As Object(context, paths, Null, Null))
 

yiankos1

Active Member
Licensed User
Seems like this method will not work with Android 4.4+ (or maybe 4.3)

Try this code instead:
B4X:
Dim context As JavaObject
context = context.InitializeStatic("anywheresoftware.b4a.BA").GetField("applicationContext")
Dim paths() As String = Array As String(File.Combine(...)) 'files to scan
Dim mediaScanner As JavaObject
mediaScanner.InitializeStatic("android.media.MediaScannerConnection")
mediaScanner.RunMethod("scanFile", Array As Object(context, paths, Null, Null))
Requires JavaObject v1.00.
I tried this solution to 4.4.4 Samsung Note 4, but with no luck on deleted photos. Still creates a "broken" thumbnail, as described at first post. Do we have any solution about this? Maybe put part of #Java code should solve that problem.
 
Last edited:

yiankos1

Active Member
Licensed User
After two days of search at stackoverflow, i found out this solution(of course in java): http://stackoverflow.com/a/25086535
Does anyone know how to implement this in a b4a project, or translate it to b4a language?
Thanks in advance for your time.
 

yiankos1

Active Member
Licensed User
You are right Erel. I share my solution here:
B4X:
Sub ForceGallery

    Dim Phone As Phone
    If Phone.SdkVersion<19 Then
        Dim i As Intent
        i.Initialize("android.intent.action.MEDIA_MOUNTED", "file://" & File.Combine(dir2, filename))
        Phone.SendBroadcastIntent(i)
    Else
        Dim context As JavaObject
        context = context.InitializeStatic("anywheresoftware.b4a.BA").GetField("applicationContext")
        Dim paths() As String = Array As String(File.Combine(dir2,filename)) 'files to scan
        Dim mediaScanner As JavaObject
        mediaScanner.InitializeStatic("android.media.MediaScannerConnection")
        mediaScanner.RunMethod("scanFile", Array As Object(context, paths, Null, Null))
    End If

End Sub
 
Last edited:
Top