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
  1. public static NdefRecord createMime(String mimeType, byte[] mimeData) {  
  2.     if (mimeType == null)  
  3.         throw new NullPointerException("mimeType is null");  
  4.   
  5.     // We only do basic MIME type validation: trying to follow the  
  6.     // RFCs strictly only ends in tears, since there are lots of MIME  
  7.     // types in common use that are not strictly valid as per RFC rules  
  8.     mimeType = normalizeMimeType(mimeType);  
  9.     if (mimeType.length() == 0)  
  10.         throw new IllegalArgumentException("mimeType is empty");  
  11.     int slashIndex = mimeType.indexOf('/');  
  12.     if (slashIndex == 0)  
  13.         throw new IllegalArgumentException("mimeType must have major type");  
  14.     if (slashIndex == mimeType.length() - 1) {  
  15.         throw new IllegalArgumentException("mimeType must have minor type");  
  16.     }  
  17.     // missing '/' is allowed  
  18.   
  19.     // MIME RFCs suggest ASCII encoding for content-type  
  20.     byte[] typeBytes = mimeType.getBytes(Charsets.US_ASCII);  
  21.     return new NdefRecord(NdefRecord.TNF_MIME_MEDIA, typeBytes, null, mimeData);  
  22. }  
このメソッドをバックポートするときに、そのままコードを移植すると実行時に IllegalArgumentException が起こる場合があります。

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




0 件のコメント:

コメントを投稿