- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试简单地添加音频文件。我的解决方案大多有效。但它不起作用的地方是文件已经存在于 MediaStore
中。一旦我更仔细地查看,仅存在于 MediaStore
中,设备上的该位置没有文件。
val values = ContentValues().apply {
put(MediaStore.Audio.Media.RELATIVE_PATH, libraryPart.rootFolderRelativePath) // JDrop/1/1
put(MediaStore.Audio.Media.DISPLAY_NAME, remoteLibraryEntry.getFilename()) //12.mp3
put(MediaStore.Audio.Media.IS_PENDING, 1)
if(mimeType != null)
put(MediaStore.Audio.Media.MIME_TYPE, mimeType) // audio/mpeg3
}
val collection = MediaStore.Audio.Media
.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
var uri = ctx.contentResolver.insert(collection, values) // returns null for around 300/2000 files consistently
当尝试插入该新文件时,Logcat 输出以下内容。
2020-01-24 22:27:33.724 4015-7707/? E/SQLiteDatabase: Error inserting title_key= bucket_display_name=1 owner_package_name=shio.at.jdrop parent=79657 volume_name=external_primary title_resource_uri=null _display_name=12.mp3 mime_type=audio/mpeg3 _data=/storage/emulated/0/Music/JDrop/1/1/12.mp3 title= group_id=1569 artist_id=322 is_pending=1 date_added=1579901253 album_id=2958 primary_directory=Music secondary_directory=JDrop bucket_id=687581593 media_type=2 relative_path=Music/JDrop/1/1/ from {P:30220;U:10165}
android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: files._data (code 2067 SQLITE_CONSTRAINT_UNIQUE)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:879)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1639)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1494)
at com.android.providers.media.MediaProvider.insertFile(MediaProvider.java:3050)
at com.android.providers.media.MediaProvider.insertInternal(MediaProvider.java:3452)
at com.android.providers.media.MediaProvider.insert(MediaProvider.java:3240)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:325)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:164)
at android.os.Binder.execTransactInternal(Binder.java:1032)
at android.os.Binder.execTransact(Binder.java:1005)
所以 files._data
意味着该文件已经存在于 MediaStore
中。 JDrop/1/1/12.mp3
中没有文件,它就在 MediaStore
中,我需要以某种方式删除它或获取现有的 OutputStream MediaStore
条目并相应地更新它。
我尝试使用以下代码在 MediaStore
中查询 ID
但没有成功。找出 ID
或 URI
都可以。此外,从 SDK 29 开始,MediaStore.Audio.Media.DATA
已被弃用。所以我想在不使用它的情况下查询它。
if(uri == null) {
val id: Long = ctx.contentResolver.query(
collection,
arrayOf(BaseColumns._ID),
"${MediaStore.Audio.Media.RELATIVE_PATH}=? AND ${MediaStore.Audio.Media.DISPLAY_NAME}=?",
arrayOf(libraryPart.rootFolderRelativePath, remoteLibraryEntry.getFilename()),
null)?.use {
if (it.moveToNext())
it.getLong(it.getColumnIndex(BaseColumns._ID))
else null
} ?: return false
uri = Uri.withAppendedPath(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id!!.toString())
}
我现在还尝试使用我知道无法插入的硬编码路径查询 _data
,但没有取得太大成功。
val id: Long = ctx.contentResolver.query(
collection,
arrayOf(BaseColumns._ID),
"${MediaStore.Audio.Media.DATA}=?",
arrayOf("/storage/emulated/0/Music/JDrop/1/1/12.mp3"),
null)?.use {
if (it.moveToNext())
it.getLong(it.getColumnIndex(BaseColumns._ID))
else null
} ?: return false
也返回 null 并返回 false。
我尝试按照建议对整个集合进行一些测试查询。
class TestQueryObject(val id: Long, val relativePath: String, val displayName: String)
val results = mutableListOf<TestQueryObject>()
ctx.contentResolver.query(
collection,
arrayOf(MediaStore.Audio.Media._ID, MediaStore.Audio.Media.RELATIVE_PATH, MediaStore.Audio.Media.DISPLAY_NAME),
null,
null,
null)?.use {
while (it.moveToNext()) {
results.add(TestQueryObject(
id = it.getLong(it.getColumnIndex(MediaStore.Audio.Media._ID)),
relativePath = it.getString(it.getColumnIndex(MediaStore.Audio.Media.RELATIVE_PATH)),
displayName = it.getString(it.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME))
))
}
}
var find12 = results.find { it.displayName == "12.mp3" }
它返回一个包含 2557 个条目的列表。例如第一个名称是 "5.mp3"
id 是 79658
相对路径是 "Music/JDrop/1/1"
。前面有一个我不知道的Music/
。但是 find12 仍然是空的。
可能还值得注意的是,它不会发生在我使用 android 10 创建的 Android 模拟器上。但它会在我的 OnePlus 6 上发生,其中包含大约 300 个文件,并且适用于所有其他文件。我已经在 Android 9 上使用该程序,然后升级到 Android 10。我在某个地方读到,当您升级到 10 时,来自 Android 9 的文件可能被认为是孤立的,而不是属于您的应用程序(至少当您卸载创建它们的应用程序)。所以我可能无法再访问我正在寻找的媒体存储条目?不过,我也想过。现在,任何应用程序都可以在未经任何许可的情况下访问阅读媒体。因此,如果这是一个访问问题,则在尝试写入时应该会失败。不是在阅读或找到它时。
此外,正如@CommonsWare 提到的,IS_PENDING
仍可能设置为 1
。我确实在我发布的代码下方将其设置回 0
。但是,每当我在调试时关闭程序时,该代码可能永远不会执行,因为它会在下载和写入文件的部分执行 9/10 次,因为这花费了到目前为止最长的时间程序中发生的任何事情。
最佳答案
我现在想通了这个问题。感谢@CommonsWare 提及未决位。我可能花了更长的时间才弄明白。
有一个方法 Uri MediaStore.setIncludePending(Uri uri)
,你可以输入你的 uri,然后你会得到一个 uri,你可以查询包含的待处理项目。
使用我从这个方法得到的新 Uri 成功返回我的 find12
东西!
val collection = MediaStore.Audio.Media
.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
var uri = ctx.contentResolver.insert(collection, values)
if(uri == null) {
class TestQueryObject(val id: Long, val relativePath: String, val displayName: String)
val results = mutableListOf<TestQueryObject>()
ctx.contentResolver.query(
MediaStore.setIncludePending(collection),
arrayOf(MediaStore.Audio.Media._ID, MediaStore.Audio.Media.RELATIVE_PATH, MediaStore.Audio.Media.DISPLAY_NAME),
null,
null,
null)?.use {
while (it.moveToNext()) {
results.add(TestQueryObject(
id = it.getLong(it.getColumnIndex(MediaStore.Audio.Media._ID)),
relativePath = it.getString(it.getColumnIndex(MediaStore.Audio.Media.RELATIVE_PATH)),
displayName = it.getString(it.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME))
))
}
}
var find12 = results.find { it.displayName == "12.mp3" }
}
现在我可以开始让它再次正常工作了。
编辑Android11
出现在 Android11 上的 MediaStore.setIncludePending(collection)
现已弃用,我们应该改为 use a different query method that accepts a bundle .
所以就变成了这个样子
val queryCollection =
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
MediaStore.setIncludePending(collection)
else collection
val queryProjection = arrayOf(MediaStore.Audio.Media._ID)
val querySelection = "${MediaStore.Audio.Media.RELATIVE_PATH}=? AND ${MediaStore.Audio.Media.DISPLAY_NAME}=?"
val querySelectionArgs = arrayOf("someRelativePath", "someFilename")
val queryBundle = Bundle().apply {
putString(ContentResolver.QUERY_ARG_SQL_SELECTION, querySelection)
putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, querySelectionArgs)
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
queryBundle.putInt(MediaStore.QUERY_ARG_MATCH_PENDING, MediaStore.MATCH_INCLUDE)
ctx.contentResolver.query(queryCollection, queryProjection, queryBundle, null)?.use {
... Do something
}
在 android 11 之前,那些用于在 bundle 中包含待定项目的变量不可用。
为 android 10 支持启用传统存储并像 android < 10 一样使用它并且只在 android 10 上实现范围存储可能是一个更好的主意。该选项在 android 11 上被忽略,但如果应用程序运行仍然有效在安卓 10 上。
关于android - 从 RELATIVE_PATH + DISPLAY_NAME 获取媒体的 URI 或 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59904243/
我需要您在以下方面提供帮助。近一个月来,我一直在阅读有关任务和异步的内容。 我想尝试在一个简单的 wep api 项目中实现我新获得的知识。我有以下方法,并且它们都按预期工作: public Htt
我的可执行 jar 中有一个模板文件 (.xls)。不需要在运行时我需要为这个文件创建 100 多个副本(稍后将唯一地附加)。用于获取 jar 文件中的资源 (template.xls)。我正在使用
我在查看网站的模型代码时对原型(prototype)有疑问。我知道这对 Javascript 中的继承很有用。 在这个例子中... define([], function () { "use
影响我性能的前三项操作是: 获取滚动条 获取偏移高度 Ext.getStyle 为了解释我的应用程序中发生了什么:我有一个网格,其中有一列在每个单元格中呈现网格。当我几乎对网格的内容做任何事情时,它运
我正在使用以下函数来获取 URL 参数。 function gup(name, url) { name = name.replace(/[\[]/, '\\\[').replace(/[\]]/,
我最近一直在使用 sysctl 来做很多事情,现在我使用 HW_MACHINE_ARCH 变量。我正在使用以下代码。请注意,当我尝试获取其他变量 HW_MACHINE 时,此代码可以完美运行。我还认为
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 9 年前。 要求提供代码的问题必须表现出对所解决问题的最低限度的理解。包括尝试过的解决方案、为什么
由于使用 main-bower-files 作为使用 Gulp 的编译任务的一部分,我无法使用 node_modules 中的 webpack 来require 模块code> dir 因为我会弄乱当
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我使用 Gridlayout 在一行中放置 4 个元素。首先,我有一个 JPanel,一切正常。对于行数变大并且我必须能够向下滚动的情况,我对其进行了一些更改。现在我的 JPanel 上添加了一个 J
由于以下原因,我想将 VolumeId 的值保存在变量中: #!/usr/bin/env python import boto3 import json import argparse import
我正在将 MSAL 版本 1.x 更新为 MSAL-browser 的 Angular 。所以我正在尝试从版本 1.x 迁移到 2.X.I 能够成功替换代码并且工作正常。但是我遇到了 acquireT
我知道有很多关于此的问题,例如 Getting daily averages with pandas和 How get monthly mean in pandas using groupby但我遇到
This is the query string that I am receiving in URL. Output url: /demo/analysis/test?startDate=Sat+
我正在尝试使用 javascript 中的以下代码访问 Geoserver 层 var gkvrtWmsSource =new ol.source.ImageWMS({ u
API 需要一个包含授权代码的 header 。这就是我到目前为止所拥有的: var fullUrl = 'https://api.ecobee.com/1/thermostat?json=\{"s
如何获取文件中的最后一个字符,如果是某个字符,则删除它而不将整个文件加载到内存中? 这就是我目前所拥有的。 using (var fileStream = new FileStream("file.t
我是这个社区的新手,想出了我的第一个问题。 我正在使用 JSP,我成功地创建了 JSP-Sites,它正在使用jsp:setParameter 和 jsp:getParameter 具有单个字符串。
在回答 StoreStore reordering happens when compiling C++ for x86 @Peter Cordes 写过 For Acquire/Release se
我有一个函数,我们将其命名为 X1,它返回变量 Y。该函数在操作 .on("focusout", X1) 中使用。如何获取变量Y?执行.on后X1的结果? 最佳答案 您可以更改 Y 的范围以使其位于函
我是一名优秀的程序员,十分优秀!