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 17 package com.android.contacts; 18 19 import android.app.Activity; 20 import android.content.ContentResolver; 21 import android.net.Uri; 22 import android.nfc.NdefMessage; 23 import android.nfc.NdefRecord; 24 import android.nfc.NfcAdapter; 25 import android.nfc.NfcEvent; 26 import android.provider.ContactsContract.Contacts; 27 import android.provider.ContactsContract.Profile; 28 import android.util.Log; 29 30 import com.android.contacts.detail.ContactDetailFragment; 31 32 import java.io.ByteArrayOutputStream; 33 import java.io.IOException; 34 import java.io.InputStream; 35 36 /** 37 * This class implements sharing the currently displayed 38 * contact to another device using NFC. NFC sharing is only 39 * enabled when the activity is in the foreground and resumed. 40 * When an NFC link is established, {@link #createMessage} 41 * will be called to create the data to be sent over the link, 42 * which is a vCard in this case. 43 */ 44 public class NfcHandler implements NfcAdapter.CreateNdefMessageCallback { 45 46 private static final String TAG = "ContactNfcHandler"; 47 private static final String PROFILE_LOOKUP_KEY = "profile"; 48 private final ContactDetailFragment mContactFragment; 49 50 public static void register(Activity activity, ContactDetailFragment contactFragment) { 51 NfcAdapter adapter = NfcAdapter.getDefaultAdapter(activity.getApplicationContext()); 52 if (adapter == null) { 53 return; // NFC not available on this device 54 } 55 adapter.setNdefPushMessageCallback(new NfcHandler(contactFragment), activity); 56 } 57 58 public NfcHandler(ContactDetailFragment contactFragment) { 59 mContactFragment = contactFragment; 60 } 61 62 @Override 63 public NdefMessage createNdefMessage(NfcEvent event) { 64 // Get the current contact URI 65 Uri contactUri = mContactFragment.getUri(); 66 ContentResolver resolver = mContactFragment.getActivity().getContentResolver(); 67 if (contactUri != null) { 68 final String lookupKey = Uri.encode(contactUri.getPathSegments().get(2)); 69 final Uri shareUri; 70 // TODO find out where to get this constant from, or find another way 71 // of determining this. 72 if (lookupKey.equals(PROFILE_LOOKUP_KEY)) { 73 shareUri = Profile.CONTENT_VCARD_URI.buildUpon(). 74 appendQueryParameter(Contacts.QUERY_PARAMETER_VCARD_NO_PHOTO, "true"). 75 build(); 76 } else { 77 shareUri = Contacts.CONTENT_VCARD_URI.buildUpon(). 78 appendPath(lookupKey). 79 appendQueryParameter(Contacts.QUERY_PARAMETER_VCARD_NO_PHOTO, "true"). 80 build(); 81 } 82 ByteArrayOutputStream ndefBytes = new ByteArrayOutputStream(); 83 byte[] buffer = new byte[1024]; 84 int r; 85 try { 86 InputStream vcardInputStream = resolver.openInputStream(shareUri); 87 while ((r = vcardInputStream.read(buffer)) > 0) { 88 ndefBytes.write(buffer, 0, r); 89 } 90 91 NdefRecord record = NdefRecord.createMime("text/x-vcard", ndefBytes.toByteArray()); 92 return new NdefMessage(record); 93 } catch (IOException e) { 94 Log.e(TAG, "IOException creating vcard."); 95 return null; 96 } 97 } else { 98 Log.w(TAG, "No contact URI to share."); 99 return null; 100 } 101 } 102 } 103