对于一个设备上得到所有图片我查询ContentResolver了MediaStore.Images.现在我想添加一个选项来显示隐藏文件,以及像QuickPic这样的许多图像应用程序.
有没有比递归搜索手机上的所有目录更快的方法,并检查是否有.nomedia文件,如果是,请检查我是否可以在其中找到一些图像文件?
通过它是不可能的ContentResolver吗?
我在片段中有一个回收者视图,基本上我试图在回收者视图中加载歌曲列表.每行回收者视图包含一个imageview(用于专辑封面)和textview(用于歌曲名称).我遇到麻烦,当数据集的大小很大时,即当歌曲太多时,回收者视图滞后,应用程序最终给出ANR.我正在使用Glide在每行的imageview中加载专辑艺术.谷歌音乐播放器如何能够显示如此大量的歌曲而没有任何延迟?
编辑: 这是我的SongsFragment
public class SongsFragment extends Fragment {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
ProgressBar progressBar; // progress bar to show after every 30 items
NestedScrollView nestedScrollView; //for smooth scrolling of recyclerview as well as to detect the end of recyclerview
RecyclerView recyclerView;
ArrayList<Song> songMainList = new ArrayList<>(); //partial list in which items are added
ArrayList<Song> songAllList = new ArrayList<>(); //Complete List of songs
SongAdapter songsAdapter;
private LinearLayoutManager layoutManager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, …Run Code Online (Sandbox Code Playgroud) android mediastore recycler-adapter android-recyclerview android-glide
我想将使用我的应用程序录制的 mp3 文件存储到带有 MediaStore 的 Music 文件夹中,用于 Android 10 的新“范围存储”。
此方法效果很好,但文件以时间戳命名(例如 1576253519449),没有.mp3扩展名。
如果我使用文件管理器手动添加扩展名,则文件会被正确记录。
我如何fileName + ".mp3"用来命名文件?
String fileName; //Obtained by intent
MediaRecorder audioRecorder;
Uri audiouri;
ParcelFileDescriptor file;
private void startRecording() throws IOException {
ContentValues values = new ContentValues(4);
values.put(MediaStore.Audio.Media.TITLE, fileName);
values.put(MediaStore.Audio.Media.DATE_ADDED, (int) (System.currentTimeMillis() / 1000));
values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mp3");
values.put(MediaStore.Audio.Media.RELATIVE_PATH, "Music/Recordings/");
audiouri = getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);
file = getContentResolver().openFileDescriptor(audiouri, "w");
if (file != null) {
audioRecorder = new MediaRecorder();
audioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
audioRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
audioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
audioRecorder.setOutputFile(file.getFileDescriptor());
audioRecorder.setAudioChannels(1);
audioRecorder.prepare();
audioRecorder.start();
}
}
Run Code Online (Sandbox Code Playgroud)
另一个问题: …
我正在更新我的应用以使用 Android 10 中引入的 Scoped Storage 功能。
我的应用程序与 MediaStore 一起使用并显示图像、视频和音频文件,并为用户提供删除项目的能力。
我之前删除文件的操作:
MediaStore.MediaColumns.DATAnew File(path).delete()删除该文件现在 MediaStore.MediaColumns.DATA 不可用,我迁移到使用ContentResolver.delete()从 MediaStore 删除项目
例如,我有项目的 uri:(content://media/external/images/media/502它的有效 uri,我在网格中显示它的缩略图)。我是否在 MediaStore 或其他一些应用程序中插入了这个项目都没有关系。
我用context.getContentResolver().delete(uri, null, null). 它要么成功删除(返回 1 行),要么捕获RecoverableSecurityException用于startIntentSenderForResult()访问当前 uri,然后使用相同的内容getContentResolver().delete()将其删除onActivityResult(),然后成功删除。
无论哪种方式,该项目都会从 MediaStore 中删除,并且在我查询 MediaStore 以获取图像时也不会在结果中显示,也不会在其他应用程序中显示。
但是此文件存在于文件系统中(使用 SAF 和各种文件管理器(Google Files、Total Commander)进行检查)
有时(取决于 Android 版本和媒体类型)这些项目会在手机重启后(或打开 Google 相册后 - 它扫描文件系统)带回 MediaStore
例如:我的 Google Pixel 和 Google Pixel …
我正在开发一个简单的Android音频播放器.我想在设备中列出相册.
我试过这段代码
String where = new String();
where = MediaStore.Audio.Media.IS_MUSIC + "=1";
private Cursor managedCursor;
managedCursor = managedQuery(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[] {
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ARTIST_ID
},
where,
null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER
);
ListAdapter adapter = new AlbumListAdapter(
this,
R.layout.albumlist_item,
managedCursor,
new String[] {
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ARTIST
},
new int[] {
R.id.text_album,
R.id.text_artist
}
);
setListAdapter(adapter);
Run Code Online (Sandbox Code Playgroud)
但是这段代码列出了设备中的所有歌曲.
Android Media Store DB的结构是什么.
任何人请帮忙.
我的应用程序显示sd卡的歌曲列表.我希望能够在默认播放器上播放歌曲.我已经获得了关于这首歌的所有数据:id,title,album,artist,path ...
有没有办法启动默认播放器播放歌曲?
我尝试过的:
用Intent.CATEGORY_APP_MUSIC.我可以启动默认播放器,但无法设置歌曲.
Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, Intent.CATEGORY_APP_MUSIC)打开默认音乐应用.但是intent.setData(Uri.withAppendedPath(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id))抛出异常没有找到意图.
使用已弃用MediaStore.INTENT_ACTION_MUSIC_PLAYER.找不到活动.
Intent(MediaStore.INTENT_ACTION_MUSIC_PLAYER).setDataAndType(Uri.fromFile(songFile), "audio/*")
INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH.启动搜索,但不是歌曲,说无法准备混合播放音乐.但是,它现在可以在Google上运行,因此它可能是关键.
Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH).putExtra(SearchManager.QUERY, name)ACTION_VIEW.它有效,但它推出了一个紧凑版本的播放器,我想要完整的播放器.
注意:我想启动外部播放器,而不是在我的应用中.
更新:看起来像Google Now硬编码的Play Music和Youtube支持.
在Android Q中,MediaStore.Files.FileColumns.DATA字段已弃用,可能为null或应用可能无权读取它,因此可以使用以下方法重命名文件的文件名部分(而不是路径)仅其媒体内容Uri?
到现在为止,DATA字段可用于从已知Uri查找文件的真实路径,但是由于已弃用该文件,因此其想法是什至不尝试查找或解析真实文件路径,而仅使用其内容Uri 。
考虑到Uri将采用标准媒体内容格式(不是SAF格式):content:// media / external / images / media / 123
目的是重命名Uri指向的文件的名称。
我知道我可以更新MediaStore的TITLE和DISPLAY_NAME字段,但这不会更改文件名,并且如果用户决定将文件移至设备之外,则该文件仍将具有旧文件名。
我正在创建一个简单的图像编辑器应用程序,因此需要加载和保存图像文件。我希望保存的文件在单独的相册中显示在图库中。从Android API 28到29,应用程序可以访问存储的程度发生了巨大变化。我可以在Android Q(API 29)中做我想做的事,但是这种方式并不向后兼容。
当我想在较低的API版本中获得相同的结果时,到目前为止,我只能找到方法,这需要使用不赞成使用的代码(从API 29开始)。
这些包括:
MediaStore.Images.Media.DATA列的使用Environment.getExternalStoragePublicDirectory(...)MediaStore.Images.Media.insertImage(...)我的问题是:是否有可能以这种方式实现它,使其向后兼容,但不需要弃用的代码?如果不是,在这种情况下可以使用不赞成使用的代码,还是可以将这些方法很快从sdk中删除?无论如何,使用不推荐使用的方法感觉很不好,所以我宁愿不:)
这是我发现可与API 29一起使用的方法:
ContentValues values = new ContentValues();
String filename = System.currentTimeMillis() + ".jpg";
values.put(MediaStore.Images.Media.TITLE, filename);
values.put(MediaStore.Images.Media.DISPLAY_NAME, filename);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.RELATIVE_PATH, "PATH/TO/ALBUM");
getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);
Run Code Online (Sandbox Code Playgroud)
然后,我使用insert方法返回的URI保存位图。问题在于,在API 29中引入了RELATIVE_PATH字段,因此当我在较低版本上运行代码时,图像将放入“ Pictures”文件夹,而不是“ PATH / TO / ALBUM”文件夹。
image backwards-compatibility mediastore subdirectory android-10.0
我正在尝试从设备的外部存储中删除音频文件(例如在/storage/emulated/0/Music文件夹中)。在分析了MediaStore示例之后,我最终得到了 API 28 及更早版本的以下解决方案:
fun deleteTracks(trackIds: LongArray): Int {
val whereClause = buildWildcardInClause(trackIds.size) // _id IN (?, ?, ?, ...)
return resolver.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, whereClause, Array(trackIds.size) { trackIds[it].toString() })
}
Run Code Online (Sandbox Code Playgroud)
我注意到上面的代码只从 MediaStore 数据库中删除曲目,而不是从设备中删除(重新启动后文件会重新添加到 MediaStore)。因此,我修改了该代码以查询该Media.DATA列,然后使用该信息删除关联的文件。这按预期工作。
但是现在 Android Q 引入了 Scoped Storage,Media.DATA(和Albums.ALBUM_ART)现在已被弃用,因为应用程序可能无法访问这些文件。ContentResolver.openFileDescriptor只能用于读取文件,不能用于删除文件。
那么从 Android Q 开始,推荐的删除曲目的方法是什么?该样品不表明如何从删除多个文件MediaStore,并MediaStore.Audio.Media似乎的工作方式不同MediaStore.Images.Media。
我正在使用MediaStore 和 ContentResolver API 来保存图像文件 (jpg/png/gif) MediaStore.Images。它可以工作,但问题是所有文件都以 .jpg 扩展名保存,并且文件名始终为“millis.jpg 中的当前时间”。
以下是我在 ContentValues 中放入的内容的示例:
date_added=1575480356 _display_name=2067623.gif date_modified=1575480356 mime_type=image/gif
Run Code Online (Sandbox Code Playgroud)
但将其插入 ContentResolver 并写入文件后,显示名称更改为2067623.jpg,文件名更改为1575480356.jpg.
如何让它保留文件名和扩展名?
代码:
ContentResolver resolver = activity.getContentResolver();
Uri mediaCollection;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
mediaCollection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
} else {
mediaCollection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
ContentValues mediaDetails = new ContentValues();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
final String relativeLocation = Environment.DIRECTORY_PICTURES + File.separator + "my_folder";
mediaDetails.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
mediaDetails.put(MediaStore.Images.Media.IS_PENDING, 1);
mediaDetails.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);
}
String mimeType …Run Code Online (Sandbox Code Playgroud) java android mediastore android-contentresolver scoped-storage
mediastore ×10
android ×8
android-10.0 ×2
file ×2
albumart ×1
image ×1
java ×1
rename ×1
subdirectory ×1
uri ×1