openContactPhotoInputStream原因“java.lang.IllegalStateException:从排山坳0 0未能得到场槽” [英] openContactPhotoInputStream causes “java.lang.IllegalStateException: get field slot from row 0 col 0 failed”

查看:497
本文介绍了openContactPhotoInputStream原因“java.lang.IllegalStateException:从排山坳0 0未能得到场槽”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想检查是否接触式图像存在特定联系人(后来真正得到它,更晚)。查询应尽可能短,避免非必要的内存使用情况。

I'm trying to check if a contact image exists for a specific contact (and later to actually get it, much later). the query should be as minimal as possible and avoid un-needed memory usage.

我已经想通了,这大概是不可能用正常的方式,所以现在我使用:

I've figured out this probably isn't possible using the normal way, so for now I'm using:

final Uri lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, contactKey);
final Cursor contactCur = mContentResolver.query(lookupUri, new String[] { ContactsContract.Contacts._ID },
        null, null, null);
if (contactCur == null)
    return false;
contactCur.moveToFirst();
long contactId = 0;
if (contactCur.getCount() != 0)
    contactId = contactCur.getLong(contactCur.getColumnIndex(ContactsContract.Contacts._ID));
contactCur.close();
if (contactId == 0)
    return false;
final Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);

final InputStream inputStream;
if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH)
    inputStream = ContactsContract.Contacts.openContactPhotoInputStream(mContext.getContentResolver(),
            contactUri, bigPicture);
else
    inputStream = ContactsContract.Contacts.openContactPhotoInputStream(mContext.getContentResolver(),
            contactUri);
if (inputStream != null) {
    IOUtils.closeQuietly(inputStream);
    return true;
}
return false;

问题

好像在某些罕见的情况下,设备返回我的异常:

The problem

It seems like on some rare cases, devices return me an exception of :

java.lang.IllegalStateException:从0行山坳0获得场插槽
  在android.database.CursorWindow.getBlob_native失败(本机方法)
  在android.database.CursorWindow.getBlob(CursorWindow.java:288)在
  android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:35)
  在android.database.CursorWrapper.getBlob(CursorWrapper.java:143)在
  android.provider.ContactsContract$Contacts.openContactPhotoInputStream(ContactsContract.java:1174)

java.lang.IllegalStateException: get field slot from row 0 col 0 failed at android.database.CursorWindow.getBlob_native(Native Method) at android.database.CursorWindow.getBlob(CursorWindow.java:288) at android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:35) at android.database.CursorWrapper.getBlob(CursorWrapper.java:143) at android.provider.ContactsContract$Contacts.openContactPhotoInputStream(ContactsContract.java:1174)

事实证明,有很多关于这个问题的报告,但没有关于openContactPhotoInputStream功能。

as it turns out, there are plenty of reports on this issue, but not regarding "openContactPhotoInputStream" function.

这是我读过(例如 这里 ),这是因为引起的需要被读出的斑点过大,但在这种情况下,我有Android的code内这个问题...

from what I've read (for example here), it is caused since the blob that need to be read is too large, but in this case, I have this problem within Android's code...

什么是克服这个的最佳方式?

What's the best way to overcome this?

是否有可能它是在Android上的错误吗?

Is it possible it's a bug on Android?

我的猜测是,即使我用的try-catch,当我试图获取图像后,我会得到相同的错误,对吧?

My guess is that even if I use try-catch , when I try to get the image later I would get the same error, right?

我该如何解决这个问题?

How can I fix this?

推荐答案

如何像这样的检查,如果存在的照片(未经测试):

How about something like this for checking if a photo exists (untested):

ContentResolver cr = mContext.getContentResolver();
if (bigPicture && VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
    Uri displayPhotoUri = Uri.withAppendedPath(contactUri,
            ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
    AssetFileDescriptor fd = null;
    try {
        fd = cr.openAssetFileDescriptor(displayPhotoUri, "r");
    } catch (FileNotFoundException e) {}
    if (fd != null) {
        try {
            fd.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
}

Uri photoUri = Uri.withAppendedPath(contactUri,
        ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = cr.query(photoUri, new String[] {BaseColumns._ID},
        ContactsContract.Contacts.Photo.PHOTO + " IS NOT NULL", null, null);
if (cursor == null) {
    return false;
}
try {
    return cursor.moveToFirst();
} finally {
    cursor.close();
}

这里是 openContactPhotoInputStream()方法,它应该有可能可以加载照片缩略图,大小接近1 MB,不含问题(修改后的版本再次未测试):

And here is a modified version of the openContactPhotoInputStream() method, which should potentially be able to load a photo thumbnail with a size close to 1 MB without issues (again not tested):

public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri contactUri,
        boolean preferHighres) {
    if (preferHighres && VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
        Uri displayPhotoUri = Uri.withAppendedPath(contactUri,
                ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
        try {
            return cr.openAssetFileDescriptor(displayPhotoUri, "r").createInputStream();
        } catch (IOException e) {}
    }
    Uri photoUri = Uri.withAppendedPath(contactUri,
            ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
    try {
        return cr.openAssetFileDescriptor(displayPhotoUri, "r").createInputStream();
    } catch (IOException e) {}
    return null;
}

这应引起 ContactsProvider 来读取缩略图 BLOB 来共享内存,并发送 AssetFileDescriptor 指向它,从中我们可以直接打开一个的InputStream

This should cause the ContactsProvider to read the thumbnail BLOB to shared memory, and send an AssetFileDescriptor pointing to it, from which we can directly open an InputStream.

这篇关于openContactPhotoInputStream原因“java.lang.IllegalStateException:从排山坳0 0未能得到场槽”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆