| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.android.emergency; |
| |
| import android.content.ContentUris; |
| import android.content.Context; |
| import android.database.Cursor; |
| import android.graphics.Bitmap; |
| import android.graphics.BitmapFactory; |
| import com.android.internal.logging.MetricsLogger; |
| import com.android.internal.logging.nano.MetricsProto.MetricsEvent; |
| import android.net.Uri; |
| import android.provider.ContactsContract; |
| import android.util.Log; |
| |
| import java.io.ByteArrayInputStream; |
| |
| /** |
| * Provides methods to read name, phone number, photo, etc. from contacts. |
| */ |
| public class EmergencyContactManager { |
| private static final String TAG = "EmergencyContactManager"; |
| |
| /** |
| * Returns a {@link Contact} that contains all the relevant information of the contact indexed |
| * by {@code @phoneUri}. |
| */ |
| public static Contact getContact(Context context, Uri phoneUri) { |
| String phoneNumber = null; |
| String phoneType = null; |
| String name = null; |
| Bitmap photo = null; |
| final Uri contactLookupUri = |
| ContactsContract.Contacts.getLookupUri(context.getContentResolver(), |
| phoneUri); |
| Cursor cursor = context.getContentResolver().query( |
| phoneUri, |
| new String[]{ContactsContract.Contacts.DISPLAY_NAME, |
| ContactsContract.CommonDataKinds.Phone.NUMBER, |
| ContactsContract.CommonDataKinds.Phone.TYPE, |
| ContactsContract.CommonDataKinds.Phone.LABEL, |
| ContactsContract.CommonDataKinds.Photo.PHOTO_ID}, |
| null, null, null); |
| try { |
| if (cursor.moveToNext()) { |
| name = cursor.getString(0); |
| phoneNumber = cursor.getString(1); |
| phoneType = ContactsContract.CommonDataKinds.Phone.getTypeLabel( |
| context.getResources(), |
| cursor.getInt(2), |
| cursor.getString(3)).toString(); |
| Long photoId = cursor.getLong(4); |
| if (photoId != null && photoId > 0) { |
| Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, |
| photoId); |
| Cursor cursor2 = context.getContentResolver().query( |
| photoUri, |
| new String[]{ContactsContract.Contacts.Photo.PHOTO}, |
| null, null, null); |
| try { |
| if (cursor2.moveToNext()) { |
| byte[] data = cursor2.getBlob(0); |
| if (data != null) { |
| photo = BitmapFactory.decodeStream(new ByteArrayInputStream(data)); |
| } |
| } |
| } finally { |
| if (cursor2 != null) { |
| cursor2.close(); |
| } |
| } |
| } |
| } |
| } finally { |
| if (cursor != null) { |
| cursor.close(); |
| } |
| } |
| return new Contact(contactLookupUri, phoneUri, name, phoneNumber, phoneType, photo); |
| } |
| |
| /** Returns whether the phone uri is not null and corresponds to an existing phone number. */ |
| public static boolean isValidEmergencyContact(Context context, Uri phoneUri) { |
| return phoneUri != null && phoneExists(context, phoneUri); |
| } |
| |
| private static boolean phoneExists(Context context, Uri phoneUri) { |
| Cursor cursor = null; |
| try { |
| cursor = context.getContentResolver().query(phoneUri, null, null, null, null); |
| if (cursor != null && cursor.moveToFirst()) { |
| MetricsLogger.action(context, MetricsEvent.ACTION_PHONE_EXISTS, 1); |
| return true; |
| } |
| } catch (SecurityException e) { |
| Log.w(TAG, "Unable to read contact information", e); |
| MetricsLogger.action(context, MetricsEvent.ACTION_PHONE_EXISTS, 2); |
| return false; |
| } finally { |
| if (cursor != null) { |
| cursor.close(); |
| } |
| } |
| MetricsLogger.action(context, MetricsEvent.ACTION_PHONE_EXISTS, 0); |
| return false; |
| } |
| |
| /** Wrapper for a contact with a phone number. */ |
| public static class Contact { |
| /** The lookup uri is necessary to display the contact. */ |
| private final Uri mContactLookupUri; |
| /** |
| * The contact uri is associated to a particular phone number and can be used to reload that |
| * number and keep the number displayed in the preferences fresh. |
| */ |
| private final Uri mPhoneUri; |
| /** The display name of the contact. */ |
| private final String mName; |
| /** The emergency contact's phone number selected by the user. */ |
| private final String mPhoneNumber; |
| /** The emergency contact's phone number type (mobile, work, home, etc). */ |
| private final String mPhoneType; |
| /** The contact's photo. */ |
| private final Bitmap mPhoto; |
| |
| /** Constructs a new contact. */ |
| public Contact(Uri contactLookupUri, |
| Uri phoneUri, |
| String name, |
| String phoneNumber, |
| String phoneType, |
| Bitmap photo) { |
| mContactLookupUri = contactLookupUri; |
| mPhoneUri = phoneUri; |
| mName = name; |
| mPhoneNumber = phoneNumber; |
| mPhoneType = phoneType; |
| mPhoto = photo; |
| } |
| |
| /** Returns the contact's CONTENT_LOOKUP_URI. Use this to display the contact. */ |
| public Uri getContactLookupUri() { |
| return mContactLookupUri; |
| } |
| |
| /** |
| * The phone uri as defined in ContactsContract.CommonDataKinds.Phone.CONTENT_URI. Use |
| * this to reload the contact. This links to a particular phone number of the emergency |
| * contact. |
| */ |
| public Uri getPhoneUri() { |
| return mPhoneUri; |
| } |
| |
| /** Returns the display name of the contact. */ |
| public String getName() { |
| return mName; |
| } |
| |
| /** Returns the phone number selected by the user. */ |
| public String getPhoneNumber() { |
| return mPhoneNumber; |
| } |
| |
| /** Returns the phone type (e.g. mobile, work, home, etc.) . */ |
| public String getPhoneType() { |
| return mPhoneType; |
| } |
| |
| /** Returns the photo assigned to this contact. */ |
| public Bitmap getPhoto() { |
| return mPhoto; |
| } |
| } |
| } |