标签: android-contentresolver

为什么 ContentResolver.openFileDescriptor 会抛出 IllegalArgumentException?出路?

我有两个问题,为了让我的问题在这里清晰,一个简短的代码片段:

ContentResolver resolver = context.getContentResolver();
DocumentsContract.deleteDocument(resolver, documentUri);
resolver.openFileDescriptor(documentUri, "rw");
Run Code Online (Sandbox Code Playgroud)

文档说最后一行“如果 URI 下不存在文件或模式无效,则抛出 FileNotFoundException”。

但实际上我得到java.lang.IllegalArgumentException.

(问题 1)这是一个错误还是可以?

(问题2)openFileDescriptor()显然不是测试文档是否存在的好方法。什么是“官方”方法来做到这一点?

编辑(添加错误日志):

W/System.err: java.lang.IllegalArgumentException: 无法确定 9016-4EF8:myFolder/file1.wav 是否是 9016-4EF8:myFolder: java.io.FileNotFoundException: Missing file for 9016-4EF8:myFolder/file1 .wav 在 /storage/extSdCard/myFolder/file1.wav

W/System.err: 在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)

W/System.err: 在 android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:148)

W/System.err: 在 android.content.ContentProviderProxy.openAssetFile(ContentProviderNative.java:618)

W/System.err: 在 android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:945)

W/System.err: 在 android.content.ContentResolver.openFileDescriptor(ContentResolver.java:784)

W/System.err: 在 android.content.ContentResolver.openFileDescriptor(ContentResolver.java:739)

和:

documentUri="content://com.android.externalstorage.documents/tree/9016-4EF8%3AmyFolder/document/9016-4EF8%3AmyFolder%2Ffile1.wav"

android android-contentresolver

5
推荐指数
1
解决办法
1758
查看次数

使用 ContentResolver 从表中删除所有行

我们如何使用 删除 Android 表中的所有行ContentResolver

我努力了:

  1. context.getContentResolver().delete(Abcd.CONTENT_URI, null, null);

  2. context.getContentResolver().delete(Abcd.CONTENT_URI, "1", null);

当我给出一个条件时,我知道我的 uri 是正确的:

context.getContentResolver().delete(Channel.CONTENT_URI, "name = ?", "abcd"); 该代码有效。

全部删除的正确方法是什么?

现在我正在使用一个 hack:context.getContentResolver().delete(Channel.CONTENT_URI, "name != ?", "");因为名称永远不能为空。

但我想知道最好的方法。

android android-contentresolver

5
推荐指数
1
解决办法
3245
查看次数

Android:ContentResolver 实例线程安全吗?

我们都知道ContentResolver不应在 UI 线程上执行查询,但令人惊讶的是,我ContentResolver在官方文档中找不到有关类线程安全的信息。

我知道如何编写 thread-safe ContentProvider,并且我知道SQLite默认情况下它是线程安全的(它实现了内部锁定机制)。

但是,使用ContentResolver来自多个线程的单个实例是否安全(例如,两个线程调用insert()query()在同一对象上并行)?

multithreading android thread-safety android-contentresolver

5
推荐指数
1
解决办法
1014
查看次数

Android 9 (Pie) ContentResolver 查询 MediaStore.Images.Media.EXTERNAL_CONTENT_URI 在 api 28 上返回 null

我正在获取设备中所有图像、视频和音频文件的列表。下面的代码在 android O (api 27) 之前的所有设备上都可以正常工作。但它不适用于 android Pie 设备(api 28)。Cursor 返回 nullquery

对于图像

String[] proj = {MediaStore.Images.Media._ID,
                    MediaStore.Images.Media.DATA,
                    MediaStore.Images.Media.TITLE,
                    MediaStore.Images.Media.SIZE
            };
ContentResolver cr = context.getContentResolver();

Cursor imagescursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    proj, null, null, "_size DESC");
Run Code Online (Sandbox Code Playgroud)

对于视频文件

String[] proj = {MediaStore.Video.Media._ID,
                    MediaStore.Video.Media.DATA,
                    MediaStore.Video.Media.TITLE,
                    MediaStore.Video.Media.SIZE,
                    MediaStore.Video.Media.DURATION
            };
ContentResolver cr = context.getContentResolver();

Cursor videocursor = context.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                    proj, null, null, "_size DESC");
Run Code Online (Sandbox Code Playgroud)

对于音频文件

String[] proj = {MediaStore.Audio.Media._ID,
                    MediaStore.Audio.Media.DATA,
                    MediaStore.Audio.Media.DISPLAY_NAME,
                    MediaStore.Audio.Media.SIZE,
                    MediaStore.Audio.Media.DURATION};
ContentResolver cr = context.getContentResolver();

Cursor audiocursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    proj, null, null, "_size …
Run Code Online (Sandbox Code Playgroud)

android mediastore android-contentresolver media-queries android-9.0-pie

5
推荐指数
1
解决办法
2479
查看次数

ContentResolver插入MediaStore.Audio.Media.EXTERNAL_CONTENT_URI错误

我想通过 contentResolver 获取 uri 插入音乐。

val contentValues = ContentValues()
contentValues.put(MediaStore.Audio.Media.DISPLAY_NAME, music.displayName)
contentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, contentValues)
Run Code Online (Sandbox Code Playgroud)

如果没有设置MediaStore.Audio.Media.DATA,一定是错误的。

如果使用相同的方法插入 MediaStore.Images.Media.EXTERNAL_CONTENT_URI 或 MediaStore.Video.Media.EXTERNAL_CONTENT_URI 成功。

我只想在 Android Q 上获取写入数据的 uri。

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.lastIndexOf(int)' on a null object reference
   at android.os.Parcel.createException(Parcel.java:1959)
   at android.os.Parcel.readException(Parcel.java:1921)
   at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
   at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
   at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476)
   at android.content.ContentResolver.insert(ContentResolver.java:1603)
Run Code Online (Sandbox Code Playgroud)

android android-contentresolver

5
推荐指数
1
解决办法
1028
查看次数

通过内容解析器添加日历事件后,需要记录时间才能与谷歌日历同步

通过我的应用程序,我使用创建日历事件ContentResolver。活动已成功创建,您可以在系统日历应用程序中看到它们。当用户使用 Google 日历应用程序时会出现问题。有时,事件需要几分钟的时间才会出现。此外,当该事件最终出现在 Google 日历中并且用户将其删除时,它仍然会在系统日历中再次可见几分钟。

在我的应用程序中,我想创建在 caledndar 中打开新创建的事件的意图,但由于该同步问题,它没有被显示,因为它还不可见。另外,在创建新事件之前,我会检查它是否已经存在,并且由于同步,它似乎没有被删除,并且我没有在应该创建新事件时创建新事件。

这是我创建事件的方式:

     fun addEventToCalendar(context: Context,
                           title: String,
                           description: String?,
                           startDateMillis: Long,
                           endDateInMillis: Long,
                           tag: String): Long? {

        val timeZone = TimeZone.getDefault()

        val values = ContentValues().apply {
            put(CalendarContract.Events.DTSTART, startDateMillis)
            put(CalendarContract.Events.DTEND, endDateInMillis)
            put(CalendarContract.Events.TITLE, title)
            description?.let { put(CalendarContract.Events.DESCRIPTION, description) }
            put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.id)
            put(CalendarContract.Events.CALENDAR_ID, getCalendarId(context))
            put(CalendarContract.Events.UID_2445, tag)
        }


        val uri = context.contentResolver.insert(CalendarContract.Events.CONTENT_URI, values)
        return uri?.lastPathSegment?.toLong()
    }

    fun checkIfEventAlreadyExist(context: Context, tag: String): Long? {
        val projection = arrayOf(CalendarContract.Events._ID, CalendarContract.Events.DTSTART, CalendarContract.Events.DTEND, CalendarContract.Events.UID_2445)

        val cursor = context.contentResolver.query(
                CalendarContract.Events.CONTENT_URI, …
Run Code Online (Sandbox Code Playgroud)

android android-contentresolver android-calendar

5
推荐指数
0
解决办法
929
查看次数

如何在 Android 中使用联系人列表分页

我正在尝试使用分页库在 RecyclerView 中显示具有搜索功能的联系人。https://github.com/anujmiddha/paged-list-demo我关注这个 GitHub 项目。以下是我的项目中的代码片段。我正在尝试使用 pagedList 适配器逐渐获取联系人。但这个 LIMIT 和 OFFSET 在某些 Android 版本(例如 Android 9.0)中无法按预期工作。有什么替代方案吗?

private val PROJECTION = arrayOf(
                ContactsContract.Contacts.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER
        )
    val cursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    PROJECTION,
                    null,
                    null,
                    ContactsContract.Contacts.DISPLAY_NAME +
                            " ASC LIMIT " + limit + " OFFSET " + offset) 
Run Code Online (Sandbox Code Playgroud)

另外,我尝试了另一种方法,如下所示。

val queryArgs = Bundle()
        val cursor: Cursor?
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, offset)
            queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, limit)

            cursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    PROJECTION,
                    queryArgs,
                    null)
        } else {
            cursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    PROJECTION,
                    null,
                    null,
                    ContactsContract.Contacts.DISPLAY_NAME + …
Run Code Online (Sandbox Code Playgroud)

android android-contentresolver android-contentprovider android-architecture-components android-paging-library

5
推荐指数
0
解决办法
1146
查看次数

Android 11.ContentResolver.query 返回空光标

我已经在我的应用程序中实现了从电话簿中选择联系人的功能。为了使动作 PICK 的意图在 android 11 上工作,我将其添加到我的清单中:

  <queries>
  <intent>
            <action android:name="android.intent.action.PICK" />
            <data android:mimeType="vnd.android.cursor.dir/phone_v2" />
        </intent>
</queries>
Run Code Online (Sandbox Code Playgroud)

该代码在 Android 版本 10 及更低版本上运行良好。但在 Android 版本 11 上,我从电话簿中选择的联系人不会插入到我的应用程序的文本字段中,因为 ContentResolver.query 返回空光标。it.moveToFirst() 返回 false 这是我的代码:

  Constants.START_PICK_CONTACT_ACTION -> {
                data?.data?.let { uri ->
                    activity.contentResolver.query(uri, null, null, null, null)?.use {
                                if (it.moveToFirst()) {
                                    val number: String? = it.getString(it.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                                        etPhoneNumber.setText(number)
                                    }
                                }
                            }
            }
Run Code Online (Sandbox Code Playgroud)

请帮我。

android manifest android-contentresolver android-11

5
推荐指数
1
解决办法
2198
查看次数

Android 10:contentResolver.delete() 未从文件系统中删除文件

我正在使用 MediaStore.Files 在 InternalStorage/Documents/MyFolderName/xyz.pdf 中创建文件

使用

ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, fileName);
        contentValues.put(MediaStore.Files.FileColumns.MIME_TYPE, fileType);
        contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 1);
        contentValues.put(MediaStore.Files.FileColumns.RELATIVE_PATH, dstPublicDirectory + File.separator + dstSubDirectory);

        // Getting content uri for the file

        Uri dstFileUri = resolver.insert(MediaStore.Files.getContentUri("external"), contentValues);
Run Code Online (Sandbox Code Playgroud)

我能够创建该 xyz.pdf 文件

但是,为了删除我正在使用的文件

 getActivity().getContentResolver().delete(fileUriToDelete, null, null);
Run Code Online (Sandbox Code Playgroud)

以上已从 MediaStore.Files 的数据库中删除,但无法删除文件系统中的该文件。

由于该文件仍然在以下位置可用:InternalStorage/Documents/MyFolderName 这种情况仅在 Android 10 中发生。在 Android 11 中,该文件将从文件系统以及 MediaStore.Files db 中删除

android mediastore android-contentresolver

5
推荐指数
1
解决办法
1377
查看次数

未经READ_CONTACTS权限如何获取Android联系人详细信息

根据https://developer.android.com/guide/components/intents-common#Contacts上的官方文档

您可以使用选择意图

public void selectContact() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivityForResult(intent, REQUEST_SELECT_CONTACT);
}
Run Code Online (Sandbox Code Playgroud)

}

有关在获取联系人URI后如何检索联系人详细信息的信息,请阅读检索联系人的详细信息。记住,当你检索联系人URI与上面的意图,你不会需要READ_CONTACTS权限读取该联系人的详细信息。

它指向https://developer.android.com/training/contacts-provider/retrieve-details以获取联系人的详细信息

当我按照上面链接中的说明进行操作时,我得到

Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/data from pid=5313, uid=10087 requires android.permission.READ_CONTACTS, or grantUriPermission()
Run Code Online (Sandbox Code Playgroud)

我试图通过获取联系方式

  • 加载程序(如链接说明中所述)
  • getContentResolver()。query()
  • 尝试使用lookupKey并获取联系人ID

每一种方式都需要require android.permission.READ_CONTACTS异常。是否有一个示例可以按照文档中的说明工作?

最小,完整和可验证的示例,位于

https://github.com/aaronvargas/ContactsSSCCE

要测试是否使用READ_CONTACTS,必须在“系统应用设置”中进行更改

- 编辑

在Android问题跟踪器上通过https://issuetracker.google.com/issues/118400813创建了问题

android android-contentresolver contactscontract android-contacts android-permissions

4
推荐指数
2
解决办法
810
查看次数