前提・実現したいこと
普段C言語で、PICマイコンと戯れております。
AndroidもJavaも初挑戦で、
Android USBホスト機能を使ってシリアル通信しようとしたら、できませんでした。
発生している問題・エラーメッセージ
AndroidのUSBホスト機能でArduinoとシリアル通信する
を、丸写ししたつもりなのですが、通信できません。
(ビルドが通るところまでは自力でがんばりました)
具体的には、通信相手をつないでもusbがNULLのままです。
該当のソースコード
MainActivity.java
activity_main.xml
(文字数が...と出たので削除)
helloworld4/app/src/main/res/xml/device_filter.xml
xml
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- 0x067B / 0x2303: USB serial232c ok --> <usb-device vendor-id="1659" product-id="8963" /> <!-- 0x067B / 0x2303: USB serial232c --> <usb-device vendor-id="1659" product-id="8963" /> <!-- 0x0403 / 0x6001: FTDI FT232R UART --> <usb-device vendor-id="1027" product-id="24577" /> <!-- 0x0403 / 0x6015: FTDI FT231X ok --> <usb-device vendor-id="1027" product-id="24597" /> <!-- 0x2341 / Arduino --> <usb-device vendor-id="9025" /> <!-- 0x16C0 / 0x0483: Teensyduino --> <usb-device vendor-id="5824" product-id="1155" /> <!-- 0x10C4 / 0xEA60: CP210x UART Bridge --> <usb-device vendor-id="4292" product-id="60000" /> <!-- 0x067B / 0x2303: Prolific PL2303 --> <usb-device vendor-id="1659" product-id="8963" /> <!-- 0x1a86 / 0x7523: Qinheng CH340 --> <usb-device vendor-id="6790" product-id="29987" /> </resources>
該当のソースコード(2019/05/29 17:00修正版)
MainActivity.java
java
package xx.xx.xxxx.helloworld5; import android.content.Context; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import java.io.*; import android.hardware.usb.*; import android.util.Log; import android.widget.TextView; import com.hoho.android.usbserial.driver.*; public class MainActivity extends AppCompatActivity { UsbSerialDriver usb; int counter = 0; int counter2 = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); usb = UsbSerialProber.acquire(manager); if (usb != null) { try{ usb.open(); usb.setBaudRate(19200); start_read_thread(); // シリアル通信を読むスレッドを起動 } catch(IOException e){ e.printStackTrace(); } counter++; String str = String.valueOf(counter); TextView my_counter = findViewById(R.id.counter_text); my_counter.setText(str); while(true) { try { usb.write("o".getBytes("UTF-8"), 1); } catch (UnsupportedEncodingException e) { // 発生し得ないが、書くしかない // https://qiita.com/niharu/items/662b130149ee180f7f34 } catch (IOException e) { e.printStackTrace(); } } } else { counter2++; String str2 = String.valueOf(counter2); TextView my_counter2 = findViewById(R.id.counter_text2); my_counter2.setText(str2); } } public void start_read_thread(){ new Thread(new Runnable(){ public void run(){ try{ while(true){ byte buf[] = new byte[256]; int num = usb.read(buf, buf.length); if(num > 0) Log.v("Arduino", new String(buf, 0, num)); // Arduinoから受信した値をlogcat出力 Thread.sleep(10); } } catch(IOException e){ e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }
AndroidManifest.xml
xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="xx.xx.xxxx.helloworld5"> <uses-feature android:name="android.hardware.usb.host" /> <!-- https://blog.integrityworks.co.jp/2017/12/20/permission-is-only-granted-to-system-app/ --> <uses-permission android:name="android.permission.MANAGE_USB" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> </intent-filter> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" /> </activity> </application> </manifest>
helloworld4/app/src/main/res/xml/device_filter.xml
は、そのままです。
試したこと
シリアルの端末がつながると、counter_textに1が入るはずなのに、
counter_text2に1が入る。
(古いソースでは、スイッチの反応がなくなるはずなのに、
ボタンをタップすると数値がインクリメントされる。)
補足情報(FW/ツールのバージョンなど)
シリアルの端末がつながると、ポップアップで許可を求めてきます。
API19
Android Studio 3.4です。
Q88というAndroid 4.4の実機で試しています。
#####ここにより詳細な情報を記載してください。
ライブラリーとして、
usb-serial-for-android-v010.jar(どこで拾ったのかわからなくなっている)
を取り込んでいます。
usb-serial-for-androidのグーグルコードが消えてしまって、情報が半分くらい
消え去っている。(githubに飛ばされた)
githubに公開されている、ライブラリのソースは読んでいない...です。すいません。
usb-serial-for-androidのgithub
次の2つのシリアル通信を試しました。
IOデータ USB-RSAQ6 usb-device vendor-id="1659" product-id="8963" 秋月電子通商のFT234X 超小型USBシリアル変換モジュール usb-device vendor-id="1027" product-id="24597"
Q88のadbがなくて、ちまちまリリース用のakpをファイル転送してテストしています。
よろしくお願いいたします。
追加情報
ソースコードをリンク先に近い形にしました。
通信相手をつないで『アプリの画面の R.id.button ボタンを
押しても』usbがNULLのまま, という解釈であっていますでしょうか.
はい。
なんのスイッチでしょう.
『アプリの画面の R.id.button ボタン』です。
どのような「許可」を求められるのでしょうか
Open アプリ名 when this USB device is connected?
□Use by default for this USB device
「Cancel」「 OK」
で、チェックマークを入れずにOKをタップした後、
ボタンの反応しますので、usbがnullと判断しています。
マニフェストに
<uses-permission android:name="android.permission.MANAGE_USB" />
を追記してみましたが、変わりませんでした。
AndroidのUSBホスト機能を緩く使ってみる
に従って、getDeviceListしてみました。
シリアル機器をUSBに接続すると
/dev/bus/001/026
と出ました。
送信ができました。(ご報告)(2019年6月中旬)
usb-serial-for-androidを使わない方法で、送信ができました。
AndroidのUSBホスト(OTG)機能を使って、接続されたArduinoとシリアル通信してみる話
を参考にしました。(ぐぐったり、null pointerに悩まされながら)
受信は、
自作のUSBデバイスを、Androidで動かす
を参考にやろうと思います。
両方できたら、「自己解決(いろいろお世話になっていますが...)」と
しようと思います。
よろしくお願いいたします。
受信ができませんでした。(ご報告)(2019July04)
いろいろ、インターネットをさまよったのですが、
serialドライバーを使わない方法での受信ができませんでした。
FTDI社のFT232RL用ドライバーを使ったら、FT234Xは通信ができた。(2019July04)
Fab蔵さんのページ:201. USB Host事前準備 から続く内容を実行したら動きました。
これをもって、自己解決としたいと思います。
まだ回答がついていません
会員登録して回答してみよう