Home | History | Annotate | Download | only in contacts
      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 */
     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 
     59     public NfcHandler(Context context, Uri contactUri) {
     60         mContext = context;
     61         mContactUri = contactUri;
     62     }
     63 
     64     @Override
     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