Home | History | Annotate | Download | only in tagcanon
      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 
     17 package com.android.apps.tagcanon;
     18 
     19 import com.android.apps.tag.MockNdefMessages;
     20 import com.google.common.base.Preconditions;
     21 import com.google.common.primitives.Bytes;
     22 
     23 import android.app.ListActivity;
     24 import android.content.Intent;
     25 import android.content.res.Resources;
     26 import android.graphics.Bitmap;
     27 import android.graphics.drawable.BitmapDrawable;
     28 import android.graphics.drawable.Drawable;
     29 import android.nfc.NdefMessage;
     30 import android.nfc.NdefRecord;
     31 import android.nfc.NfcAdapter;
     32 import android.os.Bundle;
     33 import android.view.View;
     34 import android.widget.ArrayAdapter;
     35 import android.widget.ListView;
     36 
     37 import java.io.ByteArrayOutputStream;
     38 import java.io.IOException;
     39 import java.nio.charset.Charset;
     40 import java.nio.charset.StandardCharsets;
     41 import java.util.Locale;
     42 
     43 /**
     44  * A test activity that launches tags as if they had been scanned.
     45  */
     46 public 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(StandardCharsets.US_ASCII);
     57 
     58         Charset utfEncoding = encodeInUtf8 ? StandardCharsets.UTF_8 : StandardCharsets.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(StandardCharsets.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