タグの書き込み判定処理

タグの書き込み判定処理

タグを書き込む前に取得したタグ情報に
NDEFフォーマットが含まれているか確認する

これは、書き込み対象のタグのフォーマットにより書き込み方法が変わるから

書き込み対象から取得したタグ情報に対して
getTechList()を使うと利用可能なNFCの種類がクラス名として取得できる

この中に
Ndef.class.getName()で取得できるクラス名が含まれているなら
NDEFフォーマットになり

NdefFormatable.class.getName()で取得できるクラス名が含まれているなら
NDEFフォーマットが可能なNDEFFormatableと判定できる

これをソースにすると

try{
List techList = Arrays.asList(tag.getTechList());

Array.asList()
については
http://shot606.com/?p=1094
を参考
意味は、配列をリストへ変換する

つまり、tag.getTechList()
で取得した配列をリストに変換して
techList へ格納している

次に書き込みを行うタグへNDEFデータが格納されていているか確認

if(techList.contains(Ndef.class.getName()))

contains()については
http://karetta.jp/book-node/java/230466
を参考にする
意味は、指定した要素が存在するならtrue
今回なら
Ndef.class.getName()で値が取得できたならtrueになる

これで、trueならNDEFが含まれているときの処理を書く

そして、falseだったとき、つまりNDEFでないなら
else if (techList.contains(NdefFormatable.class.getName())){
で判定し、trueなら
NdefFormatableが含まれているときの処理を書く

あとは、catchで例外処理

}catch(RuntimeException e){
Toast.makeText(this,getString(R.string.write_failure),Toast.LENGTH_SHORT).show();
}
これで、例外発生したらToastで表示する

初級ステージ編

初級ステージ編

日経Linux 2013-12にサーバー構築が掲載されている

初級ステージ編では、Ubuntu 13.04 Desktopを使っている

これは、超入門ステージ編で使った物をサーバー構築に使っている

これを改造していくけど
さすがにやり直しになる不安とかありそうなので
仮想環境を作って練習すると効率的にできるし
やりたくない心理も減らせる
実際、私の場合も仮想環境作ってから
サーバー構築の練習したおかげでスキルアップできた

仮想環境を作るには
KVM
vmware player
virtualbox
その他いろいろあるけど
オススメはvirtualbox

これは、ドットインストールの講座で見ることができるし
vmware playerみたいに英語のサイトでアカウント登録しなくてもよいから挫折率低め

virtualboxの講座は、旧版だけど
http://dotinstall.com/lessons/basic_local_development
にある

新版もあるけど
こっちは、Vagrantもつかうため
難易度があがってしまう

途中でいくつかネット公開状態が前提のものもあり、なれないと挫折するかもしれないけど

ローカルで使うなら
30 の VPNサーバー構築
31 プロキシサーバー構築
は省いてしまうのもあり

あと、電子工作が苦手なら
39 のRaspberry Piを使うとかは難しいし
極力お金はかけたくないのなら
40 のAWS は行わなくてもok

AWSは使った分だけ課金になる
クラウドサービス
ちなみに、支払いはドルなので、円安だと厳しいかも

超入門ステージ編

超入門ステージ編

日経Linux 2013-12にサーバー構築が掲載されている

超入門ステージ編では、Ubuntu 13.04 Desktopを使っている

これをサーバー構築に使っている

すでにLinuxユーザーなら基本となっているのがほとんど

サーバー構築が初めてなら
10, 11のルーター設定と、
Ubuntu設定による固定IP設定は見たほうがわかりやすい

13 でドメイン取得載っている
今回使っているのは
お名前.com
ちなみに、年間でお金がかかる

料金については
http://www.onamae.com/sp/price.html
を参考に

ローマ字とか日本語とかこだわらないのなら
年間 500円もかからない

実は、公開するサーバー構築でないなら
これはやらなくてもできる
例えば、家の中でしか使わないのなら
わざわざドメイン取得でお金かけなくてもできる

超入門ステージ編だけど
いきなり公開前提なのは微妙かも
なので、外部公開しないのなら
13 14 15 16 は行わなくてもサーバー構築はできる

個人的には、初期段階で公開はリスクがあると思うし

とりあえず、なれないうちは
ここはとばして
17 のファイアウォール設定へとんだほうがわかりやすい

ここからは端末を使うのがメインになる

ctrl + Alt + t
で端末起動するので
これで起動すると楽

端末操作ではショートカットキーがあり
http://keyamb.hatenablog.com/entry/20100520/1274364225
に掲載されているので、これを参考にする

なれないうちは、テキスト編集へ
geditを使うけど
個人的には、サーバー操作するなら
vim とか Emacs 覚えておくと
クラウドとか、レンタルサーバー使うときに役立つ

これらについては
ドットインストールの講座がわかりやすい
vimは
http://dotinstall.com/lessons/basic_vim

Emacsはつかったことないので保留です

12月11日からソースみるにはお金月880円かかるけど
参考書買うより安い
動画みるだけなら無料なので
Googleでの検索と合わせるならお財布にも優しい

初心者が引っかかるとするなら
20 のインターネットからコンテンツ参照のところの
コンテンツの配置場所
これは、ドキュメントルートという場所におくけど
これは、
DocumentRoot
で設定したフォルダーになる

あと、インターネットとは書いてあるけど
サーバーのIP調べて
http://サーバーIP/contents/
でアクセスしても同じ結果になる

マメ知識として
サブネットマスクとかゲートウエイについて書かれているので
これで足りないなら
各用語をネット検索すると効率的

もし、わからないのなら
Yahoo!知恵袋とかで質問するのもあり

Androidアプリ開発での空文字チェック

Androidアプリ開発での空文字チェック

文字列の空文字チェックは
文字数をカウントして0より多いという条件に加え、nullでないかという判定処理も付けると長くなる

こんなときに便利なのが
AndroidのTextUtilクラス

この中のTextUtilsEmpty()を使うことで
文字チェックとnullチェックを同時にできるので
コードがすっきりする

NDEF Messageは、NDEF Recordの集合体

NDEF Messageは、NDEF Recordの集合体

このため、NDEF Messageを作成するには
最低でも1つ以上のNDEF Recordを作成することになる

これは、どのコンストラクタを作るときも同じ

NdefMessage(byte[] data)
この
バイト配列を渡すコンストラクタは
NDEF RecordをDBへ保存、復元するときのように
NdefRecordのままだと使いにくいような特殊な状況下で使うときに利用する

NdefMessage(NdefRecord[] records)
このNdefRecordを配列で渡すコンストラクタは
配列化したNdefRecordクラスのインスタンスを渡す
配列として定義しないとダメだけど
NdefRecordをそのまま使えるので
ベーシックなコンストラクタとして使われる

NdefMessage(NdefRecord record , NdefRecord … record)
このコンストラクタは、配列を使わず
NdefRecordクラスを、単一、もしくは複数で渡すことができる
パラメーターに直接NdefRecordをセットできるため
直感的でわかりやすいのがメリット
ただし、使えるのがAndroid API level 16
つまり Android 4.1 からでないと使えない

NFCへの書き込み

NFCへの書き込み

NFCタグへの書き込み工程は

書き込み対象タグのタグ情報取得

書き込むタグ情報の作成

タグの書き込み判定

タグへ書き込み

となる

タグへ書き込む方法は、書き込み対象タグにより変わる

このため、事前にタグ情報取得をしている

タグ情報を読み込む理由は、2つ

1 書き込み対象タグが実在しているか?

2 書き込み対象タグのフォーマットの確認
これは、フォーマットにより書き込み方が異なるから

これらの取得したタグ情報は
インテントにふくまれるため

Intent.getParcelableExtra()のキーへ
NfcAdapter.EXTRA_TAG
を指定すれば取得できる

ソースにすると
Tag tag = Intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

UIDの取得

UIDの取得

タグはデータタイプにより読み込み方法が変わるが
UID取得は変わらない 

UIDの取得は、タグの読み込みがどういうものか知るキッカケとしては適している

NFCアプリでは、読み込んだタグに含まれるタグ情報は
インテントデータを介して受信する

このため、タグ情報を含んだインテントを
Activity上で受けとるには
onNewIntentクラスを使う

ただし、onNewIntentで受けとるインテントデータは
NFCデータだけではないから
インテントを受け取ったときに
NFCのインテントアクションか判定する必要がある

ソースにすると
protected void onNewIntent(Intent intent){
super.onNewIntent(intent);
String action = intent.getAction();

if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)){

という判定をする
.equals()を使うのはJavaではよくある
理由は、
Stringはクラスなので不等号比較ができないから

詳しくは、サーチマンさんのサイトの解説

条件式(if文)で文字列の比較はequals()メソッド
http://www.searchman.info/tips/2770.html
をみるとわかりやすい

今回のように
NFCのインテントアクションなら
インテント内にNFCのタグ情報が含まれているので
UIDを取得できる

UIDはバイト列で格納されていて
intent.getByteArrayExtra()
のキーに
NfcAdapter.EXTRA_IDを指定すれば取得できる

UIDは、バイト列での取得なので
UIDとして画面出力するには
16進数に変換しないとみてもわからない

ソースにすると
UID取得は
byte[] uid = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);

UIDを文字列変換して表示するには
TextView txtuid =(TextView)findViewById(R.layout.txtuid);
txtuid.setText(NfcUtil.bytesToHex(uid));

OS versionごとに処理を分けるには

OS versionごとに処理を分けるには

Build.VERSION.SDK_INTを使うことで
アプリを実行している端末のOS versionを取得できる

そして、OS versionは
Build.VERSION_CODES.xxx
という形で定数として定められている

ちなみに、xxxには数値ではなく
Androidのversionを示すコードネームになる

1.6 ならDONUT ドーナツ

2.0 ならECLAIR エクレア
という感じになる

これを使い、もしAndroid OS versionごとに処理を分けたいのなら
Build.VERSION.SDK_INTの値を取得し
バージョンコードで条件式を作成すれば
処理を分けることができる

これは、NFC設定画面のリンクを作成するときに使える

ちなみに、Android 4.1は
Jelly_Beans つまりあめ玉になる

NFCの利用可否

NFCの利用可否

NFCアプリでは
端末のNFC搭載確認、
NFCが利用可能になっているか確認

非搭載ならもちろん使えないけど
搭載されていても、設定で無効になっていると使えない
これは、GPSとかBluetoothとかと同じ

NFC搭載されているか調べるには
NfcAdapterクラスのgetDefaultAdapter()を使えばいい

このgetDefaultAdapter()を使うことで
NFC搭載端末なら
NfcAdapterのインスタンスが生成されるけど
NFC非搭載端末ならnullが返ってくる

このため、返り値がnullなら
NFC非搭載端末と判断できる

ソースにすると
onCreate()の中へ記述するので

まずNFCインスタンス取得
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);

この返り値で、搭載か非搭載か判断できる

次に、NFCが利用可能になっているか確認する
これは、NfcAdapter.isEnabled()を使う

これは、単純に返り値がtrueとなっていればNFCが利用可能となる

ソースにすると
//NFC搭載かチェック
if(mNfcAdapter != null){

//NFCが有効かチェック
if(!mNfcAdapter.isEnabled()){

//NFCが無効なことをtoastで表示
Toast.makeText(getApplicationContext(), getString(R.string.error_nfc_disable),Toast.LENGTH_SHORT).show();
}

//NFC非搭載なので、ユーザーに通知
}else{
Toast.makeText(getApplicationContext(),getString(R.string.error_nfc_nosupported),Toast.LENGTH_SHORT).show();
}

実際に配布するアプリにするなら
これらのアプリの利用可能の判定に加えて
アプリのメニュー内にNFC設定画面に誘導するようなリンクを追加するなどユーザビリティも意識すること

NFC設定画面については
Android 4.0以下ならACTION_WIRELESS_SETTING
というインテントアクションを

Android 4.1以上なら
ACTION_NFC_SETTING
というインテントアクションを使い
startActivity()を呼び出すことで
NFC機能の設定画面を起動できる

ソースにすると
if(Build.VERSION_SDK_INT >= Build.VERSION_CODES.JELLY_BEANS){
//Android 4.1以上なら、直接NFC設定画面を呼び出すIntent アクションを使う
startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));

}else{
//Android 4.0以下ならwireless設定画面を呼び出すIntentアクションを使う
startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
}

NFCインテント

NFCインテント

NFCインテントの種類は以下のようになる

ACTION_NDEF_DISCOVERED
NDEFペイロードが存在する場合実行される
MIME-TypeやURIスキームを指定することで、細かく設定することができる

ACTION_TECH_DISCOVERED
タグが見つかり、その中に含まれるNFCの種類に起因して発行される
NFCの種類は、xmlファイルを用意し
そこに指定したものがフィルター対象となる

ACTION_TAG_DISCOVERED
タグが見つかったときに発行される