1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.contacts; 18 19import com.android.contacts.detail.ContactDetailFragment; 20 21import android.app.Activity; 22import android.content.ContentResolver; 23import android.net.Uri; 24import android.nfc.NdefMessage; 25import android.nfc.NdefRecord; 26import android.nfc.NfcAdapter; 27import android.nfc.NfcEvent; 28import android.provider.ContactsContract.Contacts; 29import android.provider.ContactsContract.Profile; 30 31import android.util.Log; 32 33import java.io.ByteArrayOutputStream; 34import java.io.IOException; 35import java.io.InputStream; 36 37/** 38 * This class implements sharing the currently displayed 39 * contact to another device using NFC. NFC sharing is only 40 * enabled when the activity is in the foreground and resumed. 41 * When an NFC link is established, {@link #createMessage} 42 * will be called to create the data to be sent over the link, 43 * which is a vCard in this case. 44 */ 45public class NfcHandler implements NfcAdapter.CreateNdefMessageCallback { 46 47 private static final String TAG = "ContactNfcHandler"; 48 private static final String PROFILE_LOOKUP_KEY = "profile"; 49 private final ContactDetailFragment mContactFragment; 50 51 public static void register(Activity activity, ContactDetailFragment contactFragment) { 52 NfcAdapter adapter = NfcAdapter.getDefaultAdapter(activity.getApplicationContext()); 53 if (adapter == null) { 54 return; // NFC not available on this device 55 } 56 adapter.setNdefPushMessageCallback(new NfcHandler(contactFragment), activity); 57 } 58 59 public NfcHandler(ContactDetailFragment contactFragment) { 60 mContactFragment = contactFragment; 61 } 62 63 @Override 64 public NdefMessage createNdefMessage(NfcEvent event) { 65 // Get the current contact URI 66 Uri contactUri = mContactFragment.getUri(); 67 ContentResolver resolver = mContactFragment.getActivity().getContentResolver(); 68 if (contactUri != null) { 69 final String lookupKey = Uri.encode(contactUri.getPathSegments().get(2)); 70 final Uri shareUri; 71 // TODO find out where to get this constant from, or find another way 72 // of determining this. 73 if (lookupKey.equals(PROFILE_LOOKUP_KEY)) { 74 shareUri = Profile.CONTENT_VCARD_URI.buildUpon(). 75 appendQueryParameter(Contacts.QUERY_PARAMETER_VCARD_NO_PHOTO, "true"). 76 build(); 77 } else { 78 shareUri = Contacts.CONTENT_VCARD_URI.buildUpon(). 79 appendPath(lookupKey). 80 appendQueryParameter(Contacts.QUERY_PARAMETER_VCARD_NO_PHOTO, "true"). 81 build(); 82 } 83 ByteArrayOutputStream ndefBytes = new ByteArrayOutputStream(); 84 byte[] buffer = new byte[1024]; 85 int r; 86 try { 87 InputStream vcardInputStream = resolver.openInputStream(shareUri); 88 while ((r = vcardInputStream.read(buffer)) > 0) { 89 ndefBytes.write(buffer, 0, r); 90 } 91 92 NdefRecord record = NdefRecord.createMime("text/x-vcard", ndefBytes.toByteArray()); 93 return new NdefMessage(record); 94 } catch (IOException e) { 95 Log.e(TAG, "IOException creating vcard."); 96 return null; 97 } 98 } else { 99 Log.w(TAG, "No contact URI to share."); 100 return null; 101 } 102 } 103} 104