約 2000 バイト/秒でデータを出力する Bluetooth GPS があります。アプリを最初に起動したときは、この速度に追いつくことができますが、約 5 ~ 10 秒以内に速度が 500 バイト/秒まで低下します。そこから上下します (通常は 300 バイト/秒から 700 バイト/秒の間ですが、追いつこうとすると 6000 バイト/秒の急激なスパイクが見られます)。ストリームはますます遅れていき、データがドロップされてしまいます (GPS は 1 秒あたり 10 サンプルを出力しており、数秒分のデータを見逃すところまで来ています)。
ラップトップからBluetooth経由でこの同じデバイスに接続すると、実行時間に関係なくすべてのデータが取得されます。したがって、デバイス自体がこの速度で送信できることはわかっています。しかし、アンドロイド (HTC Droid DNA) では、すぐに遅れをとってしまいます。スレッドの優先順位を上げてみましたが、役に立ちませんでした。アプリは、画面がオンになっている間ずっとフォアグラウンドにとどまります。速度が低下し、それでも同じ問題が発生する場合に備えて、電話をデバッガーに接続せずに試しました。これがBluetoothスタック速度の問題なのか、スレッドの優先度の問題なのか、それとも何なのかわかりません。何か案は?
更新:Galaxy Tab 10.1 で同じコードをテストしたところ、約 2000 バイト/秒を無期限に維持できます。次に、古い Motorola Photon 4G でテストしましたが、データ レートも維持できます。Droid DNA では、WiFi を無効にしてテストし、Bluetooth のパフォーマンスが低下しているかどうかを確認しましたが、違いはありませんでした。そして、DNA は 5 ~ 6 秒間高いレートを実行できるため、ハードウェアにはその能力があると思います。その後なぜか落ちていく…。
OutputStream mmOutputStream;
InputStream mmInputStream;
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //Standard SerialPortService ID
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
dataReader();
...
...
void dataReader()
{
worker = new Thread(new Runnable()
{
public void run()
{
int priority = Process.getThreadPriority(Process.myTid());
Log.d("testApp", String.format("data thread priority %d", priority));
Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
priority = Process.getThreadPriority(Process.myTid());
Log.d("testApp", String.format("data thread priority %d", priority));
int bufferSize = 1024;
byte[] readBuffer = new byte[bufferSize];
long time1 = System.currentTimeMillis();
long time2 = 0;
long datacount = 0;
while(!Thread.currentThread().isInterrupted() && !stopWorker)
{
try
{
// read what we can
int bytesRead = mmInputStream.read(readBuffer);
datacount += bytesRead;
time2 = System.currentTimeMillis();
// every second output the data rate
if (time2 - time1 > 1000)
{
final float rate = ((float)datacount * 1000.0F) / (float)(time2 - time1);
handler.post(new Runnable() {
public void run()
{
String text = String.format("%.1f bytes/sec", rate);
myLabel.setText(text);
}
});
time1 = time2;
datacount = 0;
}
}
catch (IOException ex)
{
stopWorker = true;
}
}
}
}
}