英文:
android - how to get location of sytem audio
问题
目前,我通过在查询ContentResolver
时在SQLite的NOT LIKE ...
语句中将系统音频的设备和模拟器我拥有的硬编码,以避免加载这些音频。但是,我发现存储系统音频(如警报铃声和所有出厂加载的音频)的位置在所有Android设备中都没有一个标准位置。
因此,为了避免加载所有系统音频,我需要一种获取这些音频所在目录的方法。到目前为止,我已经收集了这些系统音频可能位于的位置的数据:
"/system%",
"/storage/emulated/legacy/Ringtones/%",
"/storage/emulated/0/Ringtones%",
"/product/media/audio%"
但是,由于这些可能不足够,是否有一种方法可以获取Android系统中存储系统音频的目录路径呢?
英文:
right now, I'm avoiding loading system audio for the devices and emulator I have by hardcoding them in SQLite NOT LIKE ...
statements while querying the ContentResolver
, but, what I have found that the location for the storage of sytem audio(like alarm tones and all the audio factory loaded) doesn't have a standard location in all android device.
So, to avoid loading all system audio, I need a way to fetch the directory where these audio are located, so far, I have gathered a data of these locations where the sytem audio might be:
"/system%",
"/storage/emulated/legacy/Ringtones/%",
"/storage/emulated/0/Ringtones%",
"/product/media/audio%"
but, since these might not be adequate, is there a way to fetch the directory path where the system audio is located in android?
答案1
得分: 3
使用MediaStore查询音频文件,然后使用AudioColumns筛选音频文件,对于闹钟声音,使用IS_ALARM更加具体。
正如您所说:
> 我已经发现系统音频存储的位置在所有安卓设备中并没有固定的位置。
MediaStore是一个数据库,用于保存文件的引用,它是在不同的系统存储位置中查询文件的解决方案。
英文:
Query audio files with MediaStore , then filter audio files with AudioColumns , and more specific for alarm sounds use IS_ALARM.
As you say :
> I have found that the location for the storage of sytem audio doesn't have a standard location in all android device.
MediaStore is a database which holds references of the files and it is a solution to query files in different system storage locations.
答案2
得分: 2
你可以使用类似以下的代码片段:
String[] mProjection =
{
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DATA, # 路径
MediaStore.Audio.Media.IS_ALARM,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.SIZE
};
Cursor mCursor = getContentResolver().query(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,
mProjection,
null,
null);
> 注意:对于外部存储,请使用:MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
int index_data = mCursor.getColumnIndex(MediaStore.Audio.Media.DATA);
if (mCursor != null) {
while (mCursor.moveToNext()) {
// 从列中获取值。
newData = mCursor.getString(index_data);
// 在此处插入代码以处理检索到的数据。
// 循环结束
}
} else {
// 在此处插入代码以报告如果游标为空或提供程序抛出异常的错误。
}
参考资料:
https://developer.android.com/guide/topics/providers/content-provider-basics#java
https://stackoverflow.com/a/64539937/3541319
英文:
You can use something like this:
String[] mProjection =
{
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DATA, # path
MediaStore.Audio.Media.IS_ALARM,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.SIZE
};
Cursor mCursor = getContentResolver().query(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,
mProjection,
null,
null);
> Note: for external storage use: MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
int index_data = mCursor.getColumnIndex(MediaStore.Audio.Media.DATA);
if (mCursor != null) {
while (mCursor.moveToNext()) {
// Gets the value from the column.
newData = mCursor.getString(index_data);
// Insert code here to process the retrieved data.
// end of while loop
}
} else {
// Insert code here to report an error if the cursor is null or the provider threw an exception.
}
References:
https://developer.android.com/guide/topics/providers/content-provider-basics#java
答案3
得分: 1
override fun onAttach(context: Context) {
super.onAttach(context)
val projection = arrayOf(
MediaStore.Audio.Media.IS_ALARM,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DATE_ADDED
)
val audio: Uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI
val cur = context.contentResolver.query(
audio,
projection,
"${MediaStore.Audio.Media.IS_ALARM}>0",
null,
null
) ?: return
if (cur.moveToFirst()) {
val displayNameColumn: Int = cur.getColumnIndex(
MediaStore.Audio.Media.DISPLAY_NAME
)
val dateColumn: Int = cur.getColumnIndex(
MediaStore.Audio.Media.DATE_ADDED
)
do {
val displayName = cur.getString(displayNameColumn)
val date = cur.getString(dateColumn)
Log.i(
"Listing Alarms",
" displayName=$displayName , date=$date"
)
} while (cur.moveToNext())
}
}
You need to add:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
英文:
Code to List all alarms in fragment:
override fun onAttach(context: Context) {
super.onAttach(context)
val projection = arrayOf(
MediaStore.Audio.Media.IS_ALARM,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DATE_ADDED
)
val audio: Uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI
val cur = context.contentResolver.query(
audio,
projection, // Which columns to return
"${MediaStore.Audio.Media.IS_ALARM}>0", // Which rows to return (all rows)
null, // Selection arguments (none)
null // Ordering
) ?: return
if (cur.moveToFirst()) {
val displayNameColumn: Int = cur.getColumnIndex(
MediaStore.Audio.Media.DISPLAY_NAME
)
val dateColumn: Int = cur.getColumnIndex(
MediaStore.Audio.Media.DATE_ADDED
)
do {
val displayName = cur.getString(displayNameColumn)
val date = cur.getString(dateColumn)
Log.i(
"Listing Alarms",
" displayName=$displayName , date=$date"
)
} while (cur.moveToNext())
}
You need to add
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论