Skip to content

Commit dfc014e

Browse files
committed
Query MediaStore for media file URI for setting ringtone
Fixes #4367
1 parent 5494c67 commit dfc014e

File tree

11 files changed

+94
-19
lines changed

11 files changed

+94
-19
lines changed

app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/DeleteTask.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ protected final AsyncTaskResult<Boolean> doInBackground(
114114

115115
// delete file from media database
116116
if (!file.isSmb() && !file.isSftp())
117-
MediaConnectionUtils.scanFile(
117+
MediaConnectionUtils.scanFiles(
118118
applicationContext, files.toArray(new HybridFile[files.size()]));
119119

120120
// delete file entry from encrypted database

app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/movecopy/MoveFilesTask.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ class MoveFilesTask(
106106
for (hybridFileParcelables in files) {
107107
sourcesFiles.addAll(hybridFileParcelables)
108108
}
109-
MediaConnectionUtils.scanFile(applicationContext, sourcesFiles.toTypedArray())
110-
MediaConnectionUtils.scanFile(applicationContext, targetFiles.toTypedArray())
109+
MediaConnectionUtils.scanFiles(applicationContext, sourcesFiles.toTypedArray())
110+
MediaConnectionUtils.scanFiles(applicationContext, targetFiles.toTypedArray())
111111
}
112112

113113
// updating encrypted db entry if any encrypted file was moved

app/src/main/java/com/amaze/filemanager/asynchronous/services/CopyService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ void copyRoot(HybridFileParcelable sourceFile, HybridFile targetFile, boolean mo
468468
e);
469469
failedFOps.add(sourceFile);
470470
}
471-
MediaConnectionUtils.scanFile(c, new HybridFile[] {targetFile});
471+
MediaConnectionUtils.scanFiles(c, new HybridFile[] {targetFile});
472472
}
473473

474474
private void copyFiles(

app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1581,7 +1581,7 @@ public void restoreFromBin(Context context) {
15811581
if (!source.renameTo(dest)) {
15821582
return false;
15831583
}
1584-
MediaConnectionUtils.scanFile(context, new HybridFile[] {this});
1584+
MediaConnectionUtils.scanFiles(context, new HybridFile[] {this});
15851585
return true;
15861586
});
15871587
}

app/src/main/java/com/amaze/filemanager/filesystem/MediaStoreHack.java

+36
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import android.provider.MediaStore;
4141
import android.util.Log;
4242

43+
import androidx.annotation.NonNull;
4344
import androidx.annotation.Nullable;
4445

4546
/**
@@ -164,6 +165,41 @@ public static OutputStream getOutputStream(Context context, String str) {
164165
}
165166
}
166167

168+
public static Uri getUriForMusicMediaFrom(@NonNull String path, @NonNull Context context) {
169+
Uri retval = getUriForMusicMediaInternal(path, context);
170+
return retval;
171+
}
172+
173+
private static Uri getUriForMusicMediaInternal(@NonNull String path, @NonNull Context context) {
174+
String[] projection = {MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DATA};
175+
176+
String selection = MediaStore.Audio.Media.DATA + "=?";
177+
String[] selectionArgs = new String[] {path};
178+
179+
try (Cursor cursor =
180+
context
181+
.getContentResolver()
182+
.query(
183+
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
184+
projection,
185+
selection,
186+
selectionArgs,
187+
null)) {
188+
if (cursor != null && cursor.moveToFirst()) {
189+
int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
190+
return MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
191+
.buildUpon()
192+
.appendPath(String.valueOf(id))
193+
.build();
194+
} else {
195+
return null;
196+
}
197+
} catch (Exception e) {
198+
Log.e(TAG, "Error querying MediaStore", e);
199+
return null;
200+
}
201+
}
202+
167203
/** Returns an OutputStream to write to the file. The file will be truncated immediately. */
168204
private static int getTemporaryAlbumId(final Context context) {
169205
final File temporaryTrack;

app/src/main/java/com/amaze/filemanager/filesystem/Operations.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ protected void onPostExecute(Void aVoid) {
717717
super.onPostExecute(aVoid);
718718
if (newFile != null && oldFile != null) {
719719
HybridFile[] hybridFiles = {newFile, oldFile};
720-
MediaConnectionUtils.scanFile(context, hybridFiles);
720+
MediaConnectionUtils.scanFiles(context, hybridFiles);
721721
}
722722
}
723723
}.executeOnExecutor(executor);

app/src/main/java/com/amaze/filemanager/filesystem/files/GenericCopyUtil.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ private void startCopy(
269269
// If target file is copied onto the device and copy was successful, trigger media store
270270
// rescan
271271
if (mTargetFile != null) {
272-
MediaConnectionUtils.scanFile(mContext, new HybridFile[] {mTargetFile});
272+
MediaConnectionUtils.scanFiles(mContext, new HybridFile[] {mTargetFile});
273273
}
274274
}
275275
}

app/src/main/java/com/amaze/filemanager/filesystem/files/MediaConnectionUtils.kt

+24-4
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,14 @@ object MediaConnectionUtils {
3636
* @param hybridFiles files to be scanned
3737
*/
3838
@JvmStatic
39-
fun scanFile(
39+
fun scanFiles(
4040
context: Context,
4141
hybridFiles: Array<HybridFile>,
4242
) {
43-
val paths = arrayOfNulls<String>(hybridFiles.size)
44-
45-
for (i in hybridFiles.indices) paths[i] = hybridFiles[i].path
43+
val paths: Array<String> =
44+
hybridFiles.map {
45+
it.path
46+
}.toTypedArray()
4647

4748
MediaScannerConnection.scanFile(
4849
context,
@@ -52,4 +53,23 @@ object MediaConnectionUtils {
5253
LOG.info("MediaConnectionUtils#scanFile finished scanning path$path")
5354
}
5455
}
56+
57+
@JvmStatic
58+
fun scanFileByFileSystemPathAndMimeType(
59+
context: Context,
60+
path: String,
61+
mimeType: String? = null,
62+
callback: MediaScannerConnection.OnScanCompletedListener? = null,
63+
) {
64+
MediaScannerConnection.scanFile(
65+
context,
66+
arrayOf(path),
67+
mimeType?.let {
68+
arrayOf(it)
69+
},
70+
) { scannedPath: String, uri: Uri? ->
71+
LOG.info("Finished scanning path $scannedPath")
72+
callback?.onScanCompleted(path, uri)
73+
}
74+
}
5575
}

app/src/main/java/com/amaze/filemanager/ui/activities/MainActivityViewModel.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import com.amaze.filemanager.asynchronous.asynctasks.searchfilesystem.SearchResu
4040
import com.amaze.filemanager.asynchronous.asynctasks.searchfilesystem.searchParametersFromBoolean
4141
import com.amaze.filemanager.fileoperations.filesystem.OpenMode
4242
import com.amaze.filemanager.filesystem.HybridFile
43-
import com.amaze.filemanager.filesystem.files.MediaConnectionUtils.scanFile
43+
import com.amaze.filemanager.filesystem.files.MediaConnectionUtils.scanFiles
4444
import com.amaze.filemanager.ui.fragments.preferencefragments.PreferencesConstants.PREFERENCE_REGEX
4545
import com.amaze.filemanager.ui.fragments.preferencefragments.PreferencesConstants.PREFERENCE_REGEX_MATCHES
4646
import com.amaze.filemanager.ui.fragments.preferencefragments.PreferencesConstants.PREFERENCE_SHOW_HIDDENFILES
@@ -235,7 +235,7 @@ class MainActivityViewModel(val applicationContext: Application) :
235235
OpenMode.TRASH_BIN,
236236
originalFilePath,
237237
)
238-
scanFile(applicationContext, arrayOf(hybridFile))
238+
scanFiles(applicationContext, arrayOf(hybridFile))
239239
val intent = Intent(MainActivity.KEY_INTENT_LOAD_LIST)
240240
hybridFile.getParent(applicationContext)?.let {
241241
intent.putExtra(MainActivity.KEY_INTENT_LOAD_LIST_FILE, it)
@@ -291,7 +291,7 @@ class MainActivityViewModel(val applicationContext: Application) :
291291
OpenMode.TRASH_BIN,
292292
source,
293293
)
294-
scanFile(applicationContext, arrayOf(hybridFile))
294+
scanFiles(applicationContext, arrayOf(hybridFile))
295295
val intent = Intent(MainActivity.KEY_INTENT_LOAD_LIST)
296296
hybridFile.getParent(applicationContext)?.let {
297297
intent.putExtra(MainActivity.KEY_INTENT_LOAD_LIST_FILE, it)

app/src/main/java/com/amaze/filemanager/ui/fragments/MainFragment.java

+23-5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import com.amaze.filemanager.filesystem.FileProperties;
5959
import com.amaze.filemanager.filesystem.HybridFile;
6060
import com.amaze.filemanager.filesystem.HybridFileParcelable;
61+
import com.amaze.filemanager.filesystem.MediaStoreHack;
6162
import com.amaze.filemanager.filesystem.SafRootHolder;
6263
import com.amaze.filemanager.filesystem.files.CryptUtil;
6364
import com.amaze.filemanager.filesystem.files.EncryptDecryptUtils;
@@ -136,6 +137,7 @@
136137
import jcifs.smb.SmbFile;
137138
import kotlin.collections.ArraysKt;
138139
import kotlin.collections.CollectionsKt;
140+
import kotlin.text.StringsKt;
139141

140142
public class MainFragment extends Fragment
141143
implements BottomBarButtonPath,
@@ -574,10 +576,26 @@ public void returnIntentResults(HybridFileParcelable[] baseFiles) {
574576
HybridFileParcelable resultBaseFile = result.getKey();
575577

576578
if (requireMainActivity().mRingtonePickerIntent) {
577-
intent.setDataAndType(
578-
resultUri,
579-
MimeTypes.getMimeType(resultBaseFile.getPath(), resultBaseFile.isDirectory()));
580-
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, resultUri);
579+
// Query MediaStore to get the proper content URI for the selected audio file
580+
Uri mediaFileUri =
581+
MediaStoreHack.getUriForMusicMediaFrom(resultBaseFile.getPath(), requireContext());
582+
if (mediaFileUri != null) {
583+
String filename = resultBaseFile.getName();
584+
Uri properUri =
585+
mediaFileUri
586+
.buildUpon()
587+
.appendQueryParameter("canonical", "1")
588+
.appendQueryParameter("title", StringsKt.substringBeforeLast(filename, ".", ""))
589+
.build();
590+
// Set the proper content URI as result
591+
intent.setDataAndType(properUri, "audio/*");
592+
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, properUri);
593+
} else {
594+
Toast.makeText(requireContext(), R.string.error_mediastore_query_uri, Toast.LENGTH_LONG)
595+
.show();
596+
requireMainActivity().finish();
597+
return;
598+
}
581599
} else {
582600
LOG.debug("pickup file");
583601
intent.setDataAndType(resultUri, MimeTypes.getExtension(resultBaseFile.getPath()));
@@ -1353,7 +1371,7 @@ public void hide(String path) {
13531371
LOG.warn("failure when hiding file", e);
13541372
}
13551373
}
1356-
MediaConnectionUtils.scanFile(
1374+
MediaConnectionUtils.scanFiles(
13571375
requireMainActivity(), new HybridFile[] {new HybridFile(OpenMode.FILE, path)});
13581376
}
13591377
}

app/src/main/res/values/strings.xml

+1
Original file line numberDiff line numberDiff line change
@@ -848,5 +848,6 @@ You only need to do this once, until the next time you select a new location for
848848
<string name="trash_bin_retention_bytes_summary">Maximum data (in MBs) trash bin can store</string>
849849
<string name="trash_bin_cleanup_interval_title">Cleanup interval</string>
850850
<string name="trash_bin_cleanup_interval_summary">Trigger auto-cleanup interval (hours)</string>
851+
<string name="error.mediastore.query.uri">Error querying MediaStore for content URI of select media file. Refresh the MediaStore and try again.</string>
851852
</resources>
852853

0 commit comments

Comments
 (0)