有许多Q& A主题,但没有一个提供真正的答案,或者我找不到它。
为了确保你,我在询问之前进行了搜索:
那么有没有人知道如何使用Intent(如示例代码中所示)并插入一个Photo,它位于Bitmap中?
示例代码我现在用它来启动对话意图,让用户在保存之前插入或取消并可能编辑字段:
// PrivateContactClass c;
// Bitmap photo;
Intent inOrUp = new Intent(ContactsContract.Intents.Insert.ACTION, ContactsContract.Contacts.CONTENT_URI);
inOrUp.setType(ContactsContract.Contacts.CONTENT_TYPE);
inOrUp.putExtra(ContactsContract.Intents.Insert.NAME, ModelUtils.formatName(c));
inOrUp.putExtra(ContactsContract.Intents.Insert.PHONE, getPrimaryPhone());
inOrUp.putExtra(ContactsContract.Intents.Insert.TERTIARY_PHONE, c.getMobile());
inOrUp.putExtra(ContactsContract.Intents.Insert.EMAIL, c.getMail());
inOrUp.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, c.getFunction());
inOrUp.putExtra(ContactsContract.Intents.Insert.NOTES, getSummary());
inOrUp.putExtra(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
startActivity(inOrUp);
不仅仅使用intent,因为我怀疑我们可以传递Data ContentProvider保存的图像ID,或者直接在Intent中传递Bitmap。
从上面的代码扩展
// must be declared in class-context
private static final int CONTACT_SAVE_INTENT_REQUEST = 1;
...
startActivityForResult(inOrUp,CONTACT_SAVE_INTENT_REQUEST);
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
switch (requestCode) {
case RESULT_INSERT_CONTACT:
if (resultCode == RESULT_OK) {
trySetPhoto();
}
break;
}
}
public boolean setDisplayPhotoByRawContactId(long rawContactId, Bitmap bmp) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Uri pictureUri = Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI,
rawContactId), RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
try {
AssetFileDescriptor afd = getContentResolver().openAssetFileDescriptor(pictureUri, "rw");
OutputStream os = afd.createOutputStream();
os.write(byteArray);
os.close();
afd.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
private void trySetPhoto() {
// Everything is covered in try-catch, as this method can fail on
// low-memory or few NPE
try {
// We must have an phone identifier by which we search for
// format of phone number is not relevant, as ContentProvider will
// normalize it automatically
if (c.getMobile() != null) {
Uri lookup = Uri.withAppendedPath(
ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(c.getMobile()));
Cursor c = getContentResolver().query(lookup, null, null, null,
null);
// Remember cursor can be null in some cases
if (c != null) {
// we can obtain bitmap just once
Bitmap photo_bitmap = getPhotoBitmap();
c.moveToFirst();
// if there are multiple raw contacts, we want to set the photo for all of them
while (c.moveToNext()) {
setDisplayPhotoByRawContactId(
c.getLong(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID)),
photo_bitmap);
}
// remember to clean up after using cursor
c.close();
}
}
} catch (Exception e) {
// Logging procedures
} catch (Error e) {
// Logging procedures
}
}
答案 0 :(得分:10)
Bitmap bit = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); // your image
ArrayList<ContentValues> data = new ArrayList<ContentValues>();
ContentValues row = new ContentValues();
row.put(Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
row.put(ContactsContract.CommonDataKinds.Photo.PHOTO, bitmapToByteArray(bit));
data.add(row);
Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
intent.putParcelableArrayListExtra(Insert.DATA, data);
答案 1 :(得分:4)
为了帮助你,我找到了原始文档: http://java.llp2.dcc.ufmg.br/apiminer/docs/reference/android/provider/ContactsContract.RawContacts.DisplayPhoto.html
对我来说,一个简单的解决方案就是如果您的代码可以调用:
startActivityForResult(inOrUp, CODE_INSERT_CONTACT);
然后在&#34; onActivityResult&#34; call&#34; setDisplayPhotoByRawContactId。&#34;:
/** @return true if picture was changed false otherwise. */
public boolean setDisplayPhotoByRawContactId(long rawContactId, Bitmap bmp) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Uri pictureUri = Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI,
rawContactId), RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
try {
AssetFileDescriptor afd = getContentResolver().openAssetFileDescriptor(pictureUri, "rw");
OutputStream os = afd.createOutputStream();
os.write(byteArray);
os.close();
afd.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
通常,此代码适用于API的第14版。我不得不对这个话题进行研究。
您可以按照文档中的说明获取rawContactId:
Uri rawContactUri = RawContacts.URI.buildUpon()
.appendQueryParameter(RawContacts.ACCOUNT_NAME, accountName)
.appendQueryParameter(RawContacts.ACCOUNT_TYPE, accountType)
.build();
long rawContactId = ContentUris.parseId(rawContactUri);
我不确定,但文档会对您有所帮助。抱歉我的英文。
答案 2 :(得分:1)
接受的答案不符合问题。
请参阅使用ContactsContract.Intents.Insert.DATA
@yeo100的answer的docs - 有些模糊且难以找到:/),因为联系人照片保存在特定mimetype下的数据表:
Data.MIMETYPE
- &gt; ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
这对我有用,而且更整洁,更容易管理。
答案 3 :(得分:1)
这与yeo100的答案相同,但在Kotlin中。
//Create Intent - I use ACTION_INSERT_OR_EDIT but you could use ACTION_INSERT
val intent = Intent(Intent.ACTION_INSERT_OR_EDIT).apply {
type = ContactsContract.Contacts.CONTENT_ITEM_TYPE
}
intent.apply {
//Add name, phone numbers, etc
putExtra(ContactsContract.Intents.Insert.NAME, "John Smith")
...
/*
Start Adding Contact's Photo
*/
//Get photo from an imageView into a byteArray
var imageAsBitmap = (myImageView.drawable as BitmapDrawable).bitmap
val stream = ByteArrayOutputStream()
imageAsBitmap.compress(Bitmap.CompressFormat.PNG, 90, stream)
val imageData = stream.toByteArray()
//Add image data to an Array of ContentValues
val data = ArrayList<ContentValues>()
val row = ContentValues()
row.put(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
row.put(ContactsContract.CommonDataKinds.Photo.PHOTO, imageData)
data.add(photoRow)
//Add array to your Intent as data
putExtra(ContactsContract.Intents.Insert.DATA, data)
}
startActivity(intent)