2013年10月3日木曜日

Android NdefRecord.createMime() をバックポートするときの注意点

API Level 16 から NdefRecord に createMime() というメソッドが追加されています。

http://tools.oesf.biz/android-4.2.0_r1.0/xref/frameworks/base/core/java/android/nfc/NdefRecord.java#409 public static NdefRecord createMime(String mimeType, byte[] mimeData) { if (mimeType == null) throw new NullPointerException("mimeType is null"); // We only do basic MIME type validation: trying to follow the // RFCs strictly only ends in tears, since there are lots of MIME // types in common use that are not strictly valid as per RFC rules mimeType = normalizeMimeType(mimeType); if (mimeType.length() == 0) throw new IllegalArgumentException("mimeType is empty"); int slashIndex = mimeType.indexOf('/'); if (slashIndex == 0) throw new IllegalArgumentException("mimeType must have major type"); if (slashIndex == mimeType.length() - 1) { throw new IllegalArgumentException("mimeType must have minor type"); } // missing '/' is allowed // MIME RFCs suggest ASCII encoding for content-type byte[] typeBytes = mimeType.getBytes(Charsets.US_ASCII); return new NdefRecord(NdefRecord.TNF_MIME_MEDIA, typeBytes, null, mimeData); } このメソッドをバックポートするときに、そのままコードを移植すると実行時に IllegalArgumentException が起こる場合があります。

4.3 の HTC One では起こりませんでしたが、4.0.4 の ARROWS V では起こりました。
(Jelly Bean なら起こらない?) 10-03 19:08:40.622: E/AndroidRuntime(2218): java.lang.IllegalArgumentException: Illegal null argument 10-03 19:08:40.622: E/AndroidRuntime(2218): at android.os.Parcel.readException(Parcel.java:1351) 10-03 19:08:40.622: E/AndroidRuntime(2218): at android.os.Parcel.readException(Parcel.java:1301) 10-03 19:08:40.622: E/AndroidRuntime(2218): at android.nfc.INdefPushCallback$Stub$Proxy.createMessage(INdefPushCallback.java:95) 10-03 19:08:40.622: E/AndroidRuntime(2218): at com.android.nfc.P2pLinkManager.prepareMessageToSend(P2pLinkManager.java:241) 10-03 19:08:40.622: E/AndroidRuntime(2218): at com.android.nfc.P2pLinkManager.onLlcpActivated(P2pLinkManager.java:206) 10-03 19:08:40.622: E/AndroidRuntime(2218): at com.android.nfc.NfcService$NfcServiceHandler.llcpActivated(NfcService.java:1845) 10-03 19:08:40.622: E/AndroidRuntime(2218): at com.android.nfc.NfcService$NfcServiceHandler.handleMessage(NfcService.java:1718) 10-03 19:08:40.622: E/AndroidRuntime(2218): at android.os.Handler.dispatchMessage(Handler.java:99) 10-03 19:08:40.622: E/AndroidRuntime(2218): at android.os.Looper.loop(Looper.java:137) 10-03 19:08:40.622: E/AndroidRuntime(2218): at android.app.ActivityThread.main(ActivityThread.java:4479) 10-03 19:08:40.622: E/AndroidRuntime(2218): at java.lang.reflect.Method.invokeNative(Native Method) 10-03 19:08:40.622: E/AndroidRuntime(2218): at java.lang.reflect.Method.invoke(Method.java:511) 10-03 19:08:40.622: E/AndroidRuntime(2218): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 10-03 19:08:40.622: E/AndroidRuntime(2218): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 10-03 19:08:40.622: E/AndroidRuntime(2218): at dalvik.system.NativeStart.main(Native Method) この現象を避けるには、NdefRecord のコンストラクタの第3引数を null から new byte[0] に変えます。 public static NdefRecord createMime(String mimeType, byte[] mimeData) { ... return new NdefRecord(NdefRecord.TNF_MIME_MEDIA, typeBytes, new byte[0], mimeData); }



0 件のコメント:

コメントを投稿