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.tagcanon; 18 19import com.android.apps.tag.MockNdefMessages; 20import com.google.common.base.Preconditions; 21import com.google.common.primitives.Bytes; 22 23import android.app.ListActivity; 24import android.content.Intent; 25import android.content.res.Resources; 26import android.graphics.Bitmap; 27import android.graphics.drawable.BitmapDrawable; 28import android.graphics.drawable.Drawable; 29import android.nfc.NdefMessage; 30import android.nfc.NdefRecord; 31import android.nfc.NfcAdapter; 32import android.os.Bundle; 33import android.view.View; 34import android.widget.ArrayAdapter; 35import android.widget.ListView; 36 37import java.io.ByteArrayOutputStream; 38import java.io.IOException; 39import java.nio.charset.Charset; 40import java.nio.charset.Charsets; 41import java.util.Locale; 42 43/** 44 * A test activity that launches tags as if they had been scanned. 45 */ 46public class TagCanon extends ListActivity { 47 static final String TAG = "TagCanon"; 48 static final byte[] UID = new byte[] { 0x05, 0x00, 0x03, 0x08 }; 49 50 ArrayAdapter<TagDescription> mAdapter; 51 52 public static NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) { 53 Preconditions.checkNotNull(text); 54 Preconditions.checkNotNull(locale); 55 56 byte[] langBytes = locale.getLanguage().getBytes(Charsets.US_ASCII); 57 58 Charset utfEncoding = encodeInUtf8 ? Charsets.UTF_8 : Charset.forName("UTF-16"); 59 byte[] textBytes = text.getBytes(utfEncoding); 60 61 int utfBit = encodeInUtf8 ? 0 : (1 << 7); 62 char status = (char) (utfBit + langBytes.length); 63 64 byte[] data = Bytes.concat( 65 new byte[] { (byte) status }, 66 langBytes, 67 textBytes 68 ); 69 70 return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); 71 } 72 73 public static NdefRecord newMimeRecord(String type, byte[] data) { 74 Preconditions.checkNotNull(type); 75 Preconditions.checkNotNull(data); 76 77 byte[] typeBytes = type.getBytes(Charsets.US_ASCII); 78 79 return new NdefRecord(NdefRecord.TNF_MIME_MEDIA, typeBytes, new byte[0], data); 80 } 81 82 final NdefMessage[] buildImageMessages() { 83 Resources res = getResources(); 84 Drawable drawable = res.getDrawable(R.drawable.ic_launcher_nfc); 85 Bitmap photo = ((BitmapDrawable) drawable).getBitmap(); 86 final int size = photo.getWidth() * photo.getHeight() * 4; 87 final ByteArrayOutputStream out = new ByteArrayOutputStream(size); 88 89 try { 90 photo.compress(Bitmap.CompressFormat.PNG, 100, out); 91 out.flush(); 92 byte[] payload = out.toByteArray(); 93 out.close(); 94 95 NdefRecord text = newTextRecord("There's an image below this text!", Locale.US, true); 96 NdefRecord image = newMimeRecord("image/png", payload); 97 NdefMessage[] msgs = new NdefMessage[] { 98 new NdefMessage(new NdefRecord[] { text, image }) }; 99 100 return msgs; 101 } catch (IOException e) { 102 throw new RuntimeException("Failed to compress image", e); 103 } 104 } 105 106 static final class TagDescription { 107 public String title; 108 NdefMessage[] msgs; 109 110 public TagDescription(String title, byte[] bytes) { 111 this.title = title; 112 try { 113 msgs = new NdefMessage[] { new NdefMessage(bytes) }; 114 } catch (Exception e) { 115 throw new RuntimeException("Failed to create tag description", e); 116 } 117 } 118 119 public TagDescription(String title, NdefMessage[] msgs) { 120 this.title = title; 121 this.msgs = msgs; 122 } 123 124 @Override 125 public String toString() { 126 return title; 127 } 128 } 129 130 @Override 131 public void onCreate(Bundle savedState) { 132 super.onCreate(savedState); 133 ArrayAdapter<TagDescription> adapter = new ArrayAdapter<TagDescription>(this, 134 android.R.layout.simple_list_item_1, android.R.id.text1); 135 adapter.add(new TagDescription("Image", buildImageMessages())); 136 adapter.add(new TagDescription("Real NFC message", MockNdefMessages.REAL_NFC_MSG)); 137 adapter.add(new TagDescription("Call Google", MockNdefMessages.CALL_GOOGLE)); 138 adapter.add(new TagDescription("English text", MockNdefMessages.ENGLISH_PLAIN_TEXT)); 139 adapter.add(new TagDescription("Send text message", MockNdefMessages.SEND_TEXT_MESSAGE)); 140 adapter.add(new TagDescription("SmartPoster URL & text", MockNdefMessages.SMART_POSTER_URL_AND_TEXT)); 141 adapter.add(new TagDescription("SmartPoster URL", MockNdefMessages.SMART_POSTER_URL_NO_TEXT)); 142 adapter.add(new TagDescription("VCARD", MockNdefMessages.VCARD)); 143 adapter.add(new TagDescription("URI", MockNdefMessages.URI)); 144 setListAdapter(adapter); 145 mAdapter = adapter; 146 } 147 148 @Override 149 public void onListItemClick(ListView l, View v, int position, long id) { 150 TagDescription description = mAdapter.getItem(position); 151 Intent intent = new Intent(NfcAdapter.ACTION_TAG_DISCOVERED); 152 intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, description.msgs); 153 startActivity(intent); 154 } 155} 156