1/* 2 * Copyright (C) 2010 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.apps.tag.record; 18 19import com.android.apps.tag.R; 20import com.android.vcard.VCardConfig; 21import com.android.vcard.VCardEntry; 22import com.android.vcard.VCardEntryConstructor; 23import com.android.vcard.VCardEntryHandler; 24import com.android.vcard.VCardParser; 25import com.android.vcard.VCardParser_V21; 26import com.android.vcard.VCardParser_V30; 27import com.android.vcard.exception.VCardException; 28import com.android.vcard.exception.VCardVersionException; 29import com.google.android.collect.Lists; 30import com.google.common.base.Preconditions; 31 32import android.app.Activity; 33import android.content.ActivityNotFoundException; 34import android.content.ContentUris; 35import android.content.Context; 36import android.content.Intent; 37import android.content.pm.PackageManager; 38import android.content.pm.ResolveInfo; 39import android.content.res.AssetFileDescriptor; 40import android.database.Cursor; 41import android.graphics.BitmapFactory; 42import android.graphics.drawable.BitmapDrawable; 43import android.graphics.drawable.Drawable; 44import android.net.Uri; 45import android.nfc.NdefRecord; 46import android.os.AsyncTask; 47import android.os.Parcel; 48import android.os.Parcelable; 49import android.provider.ContactsContract; 50import android.text.TextUtils; 51import android.util.Log; 52import android.view.LayoutInflater; 53import android.view.View; 54import android.view.View.OnClickListener; 55import android.view.ViewGroup; 56import android.widget.ImageView; 57import android.widget.TextView; 58 59import java.io.ByteArrayInputStream; 60import java.io.FileInputStream; 61import java.io.FileNotFoundException; 62import java.io.IOException; 63import java.io.InputStream; 64import java.lang.ref.WeakReference; 65import java.util.ArrayList; 66import java.util.List; 67import java.util.Locale; 68 69/** 70 * VCard Ndef Record object 71 */ 72public class VCardRecord extends ParsedNdefRecord implements OnClickListener { 73 private static final String TAG = VCardRecord.class.getSimpleName(); 74 75 public static final String RECORD_TYPE = "vcard"; 76 77 private final byte[] mVCard; 78 79 private VCardRecord(byte[] content) { 80 mVCard = content; 81 } 82 83 @Override 84 public View getView(Activity activity, LayoutInflater inflater, ViewGroup parent, int offset) { 85 86 Uri uri = activity.getIntent().getData(); 87 uri = Uri.withAppendedPath(uri, Integer.toString(offset)); 88 uri = Uri.withAppendedPath(uri, "mime"); 89 90 // TODO: parse content and display something nicer. 91 Intent intent = new Intent(Intent.ACTION_VIEW, uri); 92 93 CharSequence template = activity.getResources().getText(R.string.import_vcard); 94 String description = TextUtils.expandTemplate(template, getDisplayName()).toString(); 95 96 return RecordUtils.getViewsForIntent(activity, inflater, parent, this, intent, description); 97 } 98 99 @Override 100 public String getSnippet(Context context, Locale locale) { 101 CharSequence template = context.getResources().getText(R.string.vcard_title); 102 return TextUtils.expandTemplate(template, getDisplayName()).toString(); 103 } 104 105 public String getDisplayName() { 106 try { 107 ArrayList<VCardEntry> entries = getVCardEntries(); 108 if (!entries.isEmpty()) { 109 return entries.get(0).getDisplayName(); 110 } 111 } catch (Exception e) { 112 } 113 114 return "vCard"; 115 } 116 117 private ArrayList<VCardEntry> getVCardEntries() throws IOException, VCardException { 118 final ArrayList<VCardEntry> entries = Lists.newArrayList(); 119 120 final int type = VCardConfig.VCARD_TYPE_UNKNOWN; 121 final VCardEntryConstructor constructor = new VCardEntryConstructor(type); 122 constructor.addEntryHandler(new VCardEntryHandler() { 123 @Override public void onStart() {} 124 @Override public void onEnd() {} 125 126 @Override 127 public void onEntryCreated(VCardEntry entry) { 128 entries.add(entry); 129 } 130 }); 131 132 VCardParser parser = new VCardParser_V21(type); 133 try { 134 parser.parse(new ByteArrayInputStream(mVCard), constructor); 135 } catch (VCardVersionException e) { 136 try { 137 parser = new VCardParser_V30(type); 138 parser.parse(new ByteArrayInputStream(mVCard), constructor); 139 } finally { 140 } 141 } 142 143 return entries; 144 } 145 146 private static Intent getPickContactIntent() { 147 Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 148 intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE); 149 return intent; 150 } 151 152 public static VCardRecord parse(NdefRecord record) { 153 MimeRecord underlyingRecord = MimeRecord.parse(record); 154 155 // TODO: Add support for other vcard mime types. 156 Preconditions.checkArgument("text/x-vcard".equals(underlyingRecord.getMimeType())); 157 return new VCardRecord(underlyingRecord.getContent()); 158 } 159 160 public static NdefRecord newVCardRecord(byte[] data) { 161 return MimeRecord.newMimeRecord("text/x-vcard", data); 162 } 163 164 @Override 165 public void onClick(View view) { 166 RecordUtils.ClickInfo info = (RecordUtils.ClickInfo) view.getTag(); 167 try { 168 info.activity.startActivity(info.intent); 169 info.activity.finish(); 170 } catch (ActivityNotFoundException e) { 171 // The activity wansn't found for some reason. Don't crash, but don't do anything. 172 Log.e(TAG, "Failed to launch activity for intent " + info.intent, e); 173 } 174 } 175 176 public static boolean isVCard(NdefRecord record) { 177 try { 178 parse(record); 179 return true; 180 } catch (IllegalArgumentException e) { 181 return false; 182 } 183 } 184} 185