Android Question AddToMediaStore error on api 30

hi
AddToMediaStore works well on api 29 but gives this error on api 30

B4X:
    File.Copy(File.DirAssets, "bounce.mp3", File.DirDefaultExternal, "bounce.mp3")
    Dim r As RingtoneManager
    Dim u As String
    u = r.AddToMediaStore(File.DirDefaultExternal, "bounce.mp3", "Bounce!", False, False, True, False)
    r.SetDefault(r.TYPE_RINGTONE, u)

log error:
java.lang.IllegalArgumentException: Unsupported MIME type audio/*
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:172)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
    at android.content.ContentProviderProxy.insert(ContentProviderNative.java:549)
    at android.content.ContentResolver.insert(ContentResolver.java:2149)
    at android.content.ContentResolver.insert(ContentResolver.java:2111)
    at anywheresoftware.b4a.phone.RingtoneManagerWrapper.AddToMediaStore(RingtoneManagerWrapper.java:108)
    at b4a.example.main._rrr(main.java:436)
    at b4a.example.main._button1_click(main.java:369)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:197)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:7448)
    at android.view.View.performClickInternal(View.java:7425)
    at android.view.View.access$3600(View.java:810)
    at android.view.View$PerformClick.run(View.java:28305)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7661)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:594)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Please help, thank you
 

Almora

Active Member
Licensed User
Longtime User
It will not work with targetSdkVersion=30. Avoid using File.DirRootExternal. Either use File.DirInternal or RuntimePermissions.GetSafeDirDefaultExternal.

 
Upvote 0

agraham

Expert
Licensed User
Longtime User
That's not the reason it's failing. He is using File.DirDefaultExternal which should be OK. In fact the copy is apparently succeeding. As he notes it is AddToMediaStore that is failing because it apparently doesn't recognize the Mime type "audio/*". Unfortunately the Mime type is set to "audio/*" by the code in AddToMediaStore and it appears to be not accepted in SDK 30 for a reason that I do not know. I think it needs Erel's wisdom on this one.

EDIT: It might be because I notice that AddToMediaStore is using absolute file paths which is not allowed under SDK 30 so maybe the venerable Phone library needs a rewrite - or maybe not! All these recent file access changes have left me somewhat confused o_O
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
RingtoneManager.AddToMediaStore cannot work in newer versions of Android. I've added a note in the documentation.

I did some tests with partial success.
This code almost works:
B4X:
Private Sub AddToMediaStore(Dir As String, FileName As String, Mime As String, Title As String, IsAlarm As Boolean, IsNotification As Boolean, _
        IsRingtone As Boolean, IsMusic As Boolean) As String
    Dim ctxt As JavaObject
    ctxt.InitializeContext
    Dim values As ContentValues
    values.Initialize
    values.PutString("_display_name", Title)
    values.PutString("title", Title)
    values.PutString("mime_type", Mime)
    values.PutBoolean("is_ringtone", IsRingtone)
    values.PutBoolean("is_notification", IsNotification)
    values.PutBoolean("is_alarm", IsAlarm)
    values.PutBoolean("is_music", IsMusic)
    Dim cr As ContentResolver
    cr.Initialize("")
    Dim MediaStoreImagesMedia As JavaObject
    MediaStoreImagesMedia.InitializeStatic("android.provider.MediaStore.Audio$Media")
    Dim EXTERNAL_CONTENT_URI As Uri = MediaStoreImagesMedia.GetField("EXTERNAL_CONTENT_URI")
    cr.Delete(EXTERNAL_CONTENT_URI, "_display_name = ?", Array As String(Title))
    Dim RingtoneUri As JavaObject = cr.Insert(EXTERNAL_CONTENT_URI, values)
    Dim in As InputStream = File.OpenInput(Dir, FileName)
    Dim out As OutputStream = ctxt.RunMethodJO("getContentResolver", Null).RunMethod("openOutputStream", Array(RingtoneUri))
    File.Copy2(in, out)
    out.Close
    Return RingtoneUri.RunMethod("toString", Null)
End Sub
It is a bit similar to: https://www.b4x.com/android/forum/threads/add-image-to-gallery-android-5-10.121992/#content
It is expected to work on newer versions of Android, however it doesn't show the new sound in the picker.
 
Upvote 0
RingtoneManager.AddToMediaStore cannot work in newer versions of Android. I've added a note in the documentation.

I did some tests with partial success.
This code almost works:
B4X:
Private Sub AddToMediaStore(Dir As String, FileName As String, Mime As String, Title As String, IsAlarm As Boolean, IsNotification As Boolean, _
        IsRingtone As Boolean, IsMusic As Boolean) As String
    Dim ctxt As JavaObject
    ctxt.InitializeContext
    Dim values As ContentValues
    values.Initialize
    values.PutString("_display_name", Title)
    values.PutString("title", Title)
    values.PutString("mime_type", Mime)
    values.PutBoolean("is_ringtone", IsRingtone)
    values.PutBoolean("is_notification", IsNotification)
    values.PutBoolean("is_alarm", IsAlarm)
    values.PutBoolean("is_music", IsMusic)
    Dim cr As ContentResolver
    cr.Initialize("")
    Dim MediaStoreImagesMedia As JavaObject
    MediaStoreImagesMedia.InitializeStatic("android.provider.MediaStore.Audio$Media")
    Dim EXTERNAL_CONTENT_URI As Uri = MediaStoreImagesMedia.GetField("EXTERNAL_CONTENT_URI")
    cr.Delete(EXTERNAL_CONTENT_URI, "_display_name = ?", Array As String(Title))
    Dim RingtoneUri As JavaObject = cr.Insert(EXTERNAL_CONTENT_URI, values)
    Dim in As InputStream = File.OpenInput(Dir, FileName)
    Dim out As OutputStream = ctxt.RunMethodJO("getContentResolver", Null).RunMethod("openOutputStream", Array(RingtoneUri))
    File.Copy2(in, out)
    out.Close
    Return RingtoneUri.RunMethod("toString", Null)
End Sub
It is a bit similar to: https://www.b4x.com/android/forum/threads/add-image-to-gallery-android-5-10.121992/#content
It is expected to work on newer versions of Android, however it doesn't show the new sound in the picker.

thank you @Erel ❤️
 
Upvote 0
Top