Skip to content

Commit

Permalink
Support contact Uri bumptech#394
Browse files Browse the repository at this point in the history
  • Loading branch information
R4md4c authored and Ahmed Ibrahim Khalil committed Apr 8, 2016
1 parent cb47a64 commit 3ba7ce9
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package com.bumptech.glide.load.data;

import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;

import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.Context;
import android.content.UriMatcher;
import android.net.Uri;
import android.os.Build;
import android.provider.ContactsContract;

import java.io.FileNotFoundException;
import java.io.IOException;
Expand All @@ -12,17 +19,74 @@
* Fetches an {@link java.io.InputStream} for a local {@link android.net.Uri}.
*/
public class StreamLocalUriFetcher extends LocalUriFetcher<InputStream> {
/** A lookup uri (e.g. content://com.android.contacts/contacts/lookup/3570i61d948d30808e537) */
private static final int ID_LOOKUP = 1;
/** A contact thumbnail uri (e.g. content://com.android.contacts/contacts/38/photo) */
private static final int ID_THUMBNAIL = 2;
/** A contact uri (e.g. content://com.android.contacts/contacts/38) */
private static final int ID_CONTACT = 3;
/**
* A contact display photo (high resolution) uri
* (e.g. content://com.android.contacts/5/display_photo)
*/
private static final int ID_DISPLAY_PHOTO = 4;


private static final UriMatcher URI_MATCHER;

static {
URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
URI_MATCHER.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*/#", ID_LOOKUP);
URI_MATCHER.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*", ID_LOOKUP);
URI_MATCHER.addURI(ContactsContract.AUTHORITY, "contacts/#/photo", ID_THUMBNAIL);
URI_MATCHER.addURI(ContactsContract.AUTHORITY, "contacts/#", ID_CONTACT);
URI_MATCHER.addURI(ContactsContract.AUTHORITY, "contacts/#/display_photo", ID_DISPLAY_PHOTO);
}

public StreamLocalUriFetcher(Context context, Uri uri) {
super(context, uri);
}

@Override
protected InputStream loadResource(Uri uri, ContentResolver contentResolver) throws FileNotFoundException {
final int matchedUri = URI_MATCHER.match(uri);
if (matchedUri != UriMatcher.NO_MATCH) {
return loadResourceFromContactUri(uri, contentResolver, matchedUri);
}
return contentResolver.openInputStream(uri);
}

@Override
protected void close(InputStream data) throws IOException {
data.close();
}

private InputStream loadResourceFromContactUri(Uri contactUri, ContentResolver contentResolver, int matchedUri)
throws FileNotFoundException {
switch (matchedUri) {
case ID_LOOKUP:
case ID_CONTACT:
// If it was a Lookup uri then resolve it first, then continue loading the contact uri.
if (matchedUri == ID_LOOKUP) {
contactUri = ContactsContract.Contacts.lookupContact(contentResolver, contactUri);
if (contactUri == null) {
throw new FileNotFoundException("Contact cannot be found");
}
}
return openContactPhotoInputStream(contentResolver, contactUri);
case ID_THUMBNAIL:
case ID_DISPLAY_PHOTO:
default:
return contentResolver.openInputStream(contactUri);
}
}

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private InputStream openContactPhotoInputStream(ContentResolver contentResolver, Uri contactUri) {
if (SDK_INT < ICE_CREAM_SANDWICH) {
return ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, contactUri);
} else {
return ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, contactUri, true);
}
}
}
21 changes: 21 additions & 0 deletions samples/contacturi/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apply plugin: 'com.android.application'

dependencies {
compile project(':library')
compile "com.android.support:support-v4:${SUPPORT_V4_VERSION}"
compile "com.android.support:appcompat-v7:${SUPPORT_V7_VERSION}"
}

android {
compileSdkVersion COMPILE_SDK_VERSION as int
buildToolsVersion BUILD_TOOLS_VERSION as String

defaultConfig {
applicationId "com.bumptech.glide.samples.contacturi"
minSdkVersion MIN_SDK_VERSION as int
targetSdkVersion TARGET_SDK_VERSION as int

versionCode 1
versionName "1.0"
}
}
24 changes: 24 additions & 0 deletions samples/contacturi/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bumptech.glide.samples.contacturi" >

<uses-permission android:name="android.permission.READ_CONTACTS" />

<application
android:allowBackup="true"
android:icon="@android:drawable/sym_def_app_icon"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat" >
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.bumptech.glide.samples.contacturi;

import android.app.Activity;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.ImageView;

import com.bumptech.glide.Glide;

/**
* An activity that demonstrates loading photos using content uris through Glide.
* It works by making the user to choose a contact when presses a button, and after he chooses a contact with photo,
* We try to load both a high res image and thumbnail image of that contact.
*/
public class MainActivity extends Activity {
private static final int REQUEST_CONTACT = 1;

private ImageView imageViewHighRes;
private ImageView imageViewThumbnail;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

imageViewHighRes = (ImageView) findViewById(R.id.image_highres);
imageViewThumbnail = (ImageView) findViewById(R.id.image_thumbnail);

findViewById(R.id.button_pick_contact).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, REQUEST_CONTACT);
}
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CONTACT && resultCode == RESULT_OK) {
final Cursor cursor =
getContentResolver().query(data.getData(), null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
// Get ID of the contact
final long id = cursor.getLong(cursor.getColumnIndex(ContactsContract.Contacts._ID));

final Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
final Uri thumbnailPhotoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo
.CONTENT_DIRECTORY);

Glide.with(this).load(contactUri).into(imageViewHighRes);
Glide.with(this).load(thumbnailPhotoUri).into(imageViewThumbnail);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
}
32 changes: 32 additions & 0 deletions samples/contacturi/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:padding="@dimen/activity_horizontal_margin"
tools:context="com.bumptech.glide.samples.contacturi.MainActivity">

<Button
android:id="@+id/button_pick_contact"
android:layout_width="wrap_content"
android:text="Pick Contact"
android:layout_height="wrap_content"/>

<ImageView
android:id="@+id/image_highres"
android:layout_width="160dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_height="160dp"/>

<ImageView
android:id="@+id/image_thumbnail"
android:layout_width="48dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/image_highres"
android:scaleType="fitCenter"
android:layout_height="48dp" />
</RelativeLayout>
6 changes: 6 additions & 0 deletions samples/contacturi/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="fab_margin">16dp</dimen>
</resources>
4 changes: 4 additions & 0 deletions samples/contacturi/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<resources>
<string name="app_name">ContactUri Sample</string>
<string name="action_settings">Settings</string>
</resources>
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ include ':third_party:gif_encoder'
include ':samples:flickr'
include ':samples:giphy'
include ':samples:svg'
include ':samples:contacturi'
include ':integration'
include ':integration:volley'
include ':integration:okhttp'
Expand Down

0 comments on commit 3ba7ce9

Please sign in to comment.