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.content.Context;
22 import android.net.Uri;
23 import android.nfc.NdefMessage;
24 import android.nfc.NdefRecord;
25 import android.nfc.NfcAdapter;
26 import android.nfc.NfcEvent;
27 import android.provider.ContactsContract.Contacts;
28 import android.provider.ContactsContract.Profile;
29 import android.util.Log;
30 
31 import java.io.ByteArrayOutputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 
35 /**
36   * This class implements sharing the currently displayed
37   * contact to another device using NFC. NFC sharing is only
38   * enabled when the activity is in the foreground and resumed.
39   * When an NFC link is established, {@link #createMessage}
40   * will be called to create the data to be sent over the link,
41   * which is a vCard in this case.
42   */
43 public class NfcHandler implements NfcAdapter.CreateNdefMessageCallback {
44 
45     private static final String TAG = "ContactNfcHandler";
46     private static final String PROFILE_LOOKUP_KEY = "profile";
47     private final Context mContext;
48     private final Uri mContactUri;
49 
50     /* Register NFC handler. This should be called in activities' onCreate(), or similar methods */
register(Activity activity, Uri contactUri)51     public static void register(Activity activity, Uri contactUri) {
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(activity, contactUri), activity);
57     }
58 
NfcHandler(Context context, Uri contactUri)59     public NfcHandler(Context context, Uri contactUri) {
60         mContext = context;
61         mContactUri = contactUri;
62     }
63 
64     @Override
createNdefMessage(NfcEvent event)65     public NdefMessage createNdefMessage(NfcEvent event) {
66         ContentResolver resolver = mContext.getContentResolver();
67         if (mContactUri != null) {
68             final String lookupKey = Uri.encode(mContactUri.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