feat(android): view mynteye datas

This commit is contained in:
John Zhao
2019-01-27 23:34:47 +08:00
parent 74b71dc161
commit 6988ae803b
12 changed files with 288 additions and 27 deletions

View File

@@ -1,6 +1,7 @@
package com.slightech.mynteye.demo;
import android.app.Application;
//import com.stericson.RootShell.RootShell;
import timber.log.Timber;
public class MyApplication extends Application {
@@ -16,6 +17,7 @@ public class MyApplication extends Application {
@Override public void onCreate() {
super.onCreate();
Timber.plant(new Timber.DebugTree());
//RootShell.debugMode = true;
}
@Override public void onLowMemory() {

View File

@@ -0,0 +1,123 @@
package com.slightech.mynteye.demo.camera;
import android.os.Handler;
import android.os.HandlerThread;
import com.slightech.mynteye.Device;
import com.slightech.mynteye.DeviceUsbInfo;
import com.slightech.mynteye.MotionData;
import com.slightech.mynteye.Source;
import com.slightech.mynteye.Stream;
import com.slightech.mynteye.StreamData;
import com.slightech.mynteye.StreamRequest;
import java.util.ArrayList;
public final class Mynteye implements Runnable {
private Device mDevice;
private HandlerThread mBackgroundThread;
private Handler mBackgroundHandler;
private boolean mOpened;
public interface OnStreamDataReceiveListener {
void onStreamDataReceive(Stream stream, StreamData data, Handler handler);
void onStreamLeftReceive(StreamData data, Handler handler);
void onStreamRightReceive(StreamData data, Handler handler);
}
public interface OnMotionDataReceiveListener {
void onMotionDataReceive(ArrayList<MotionData> datas, Handler handler);
}
private OnStreamDataReceiveListener mOnStreamDataReceiveListener;
private OnMotionDataReceiveListener mOnMotionDataReceiveListener;
public Mynteye(DeviceUsbInfo info) {
mDevice = Device.create(info);
mOpened = false;
}
public void setOnStreamDataReceiveListener(OnStreamDataReceiveListener l) {
mOnStreamDataReceiveListener = l;
}
public void setOnMotionDataReceiveListener(OnMotionDataReceiveListener l) {
mOnMotionDataReceiveListener = l;
}
public ArrayList<StreamRequest> getStreamRequests() {
return mDevice.getStreamRequests();
}
public void open(StreamRequest request) {
if (mOpened) return;
mOpened = true;
startBackgroundThread();
mDevice.configStreamRequest(request);
mDevice.enableMotionDatas(Integer.MAX_VALUE);
mDevice.start(Source.ALL);
mBackgroundHandler.post(this);
}
public void close() {
if (!mOpened) return;
mOpened = false;
stopBackgroundThread();
mDevice.stop(Source.ALL);
}
@Override
public void run() {
//Timber.i("wait streams");
mDevice.waitForStreams();
//Timber.i("get streams");
{
StreamData data = mDevice.getStreamData(Stream.LEFT);
if (mOnStreamDataReceiveListener != null) {
mOnStreamDataReceiveListener.onStreamDataReceive(Stream.LEFT, data, mBackgroundHandler);
mOnStreamDataReceiveListener.onStreamLeftReceive(data, mBackgroundHandler);
}
}
{
StreamData data = mDevice.getStreamData(Stream.RIGHT);
if (mOnStreamDataReceiveListener != null) {
mOnStreamDataReceiveListener.onStreamDataReceive(Stream.RIGHT, data, mBackgroundHandler);
mOnStreamDataReceiveListener.onStreamRightReceive(data, mBackgroundHandler);
}
}
//Timber.i("get motions");
{
ArrayList<MotionData> datas = mDevice.getMotionDatas();
if (mOnMotionDataReceiveListener != null) {
mOnMotionDataReceiveListener.onMotionDataReceive(datas, mBackgroundHandler);
}
}
if (mOpened) mBackgroundHandler.post(this);
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("MynteyeBackground");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
//mBackgroundThread.interrupt();
try {
mBackgroundHandler.removeCallbacksAndMessages(null);
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@@ -1,21 +1,43 @@
package com.slightech.mynteye.demo.ui;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.slightech.mynteye.Device;
import com.slightech.mynteye.DeviceUsbInfo;
import com.slightech.mynteye.Frame;
import com.slightech.mynteye.MotionData;
import com.slightech.mynteye.Stream;
import com.slightech.mynteye.StreamData;
import com.slightech.mynteye.StreamRequest;
import com.slightech.mynteye.demo.R;
import com.slightech.mynteye.demo.camera.Mynteye;
import com.slightech.mynteye.demo.util.RootUtils;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Locale;
import timber.log.Timber;
public class MainActivity extends BaseActivity {
public class MainActivity extends BaseActivity implements Mynteye.OnStreamDataReceiveListener,
Mynteye.OnMotionDataReceiveListener{
@BindView(R.id.text) TextView mTextView;
@BindView(R.id.image_left) ImageView mLeftImageView;
@BindView(R.id.image_right) ImageView mRightImageView;
private Mynteye mMynteye;
private Bitmap mLeftBitmap, mRightBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -90,6 +112,83 @@ public class MainActivity extends BaseActivity {
}
private void openDevice(DeviceUsbInfo info) {
mMynteye = new Mynteye(info);
ArrayList<StreamRequest> requests = mMynteye.getStreamRequests();
if (requests.isEmpty()) {
alert("Warning", "There are no streams to request :(");
} else {
ArrayList<String> items = new ArrayList<>();
for (StreamRequest req : requests) {
items.add(req.toString());
}
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("StreamRequests")
.create();
ListView listView = new ListView(this);
listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items));
listView.setOnItemClickListener((parent, view, position, id) -> {
dialog.dismiss();
mMynteye.setOnStreamDataReceiveListener(this);
mMynteye.setOnMotionDataReceiveListener(this);
mMynteye.open(requests.get(position));
});
dialog.setView(listView);
dialog.show();
}
}
@Override
public void onStreamDataReceive(Stream stream, StreamData data, Handler handler) {
}
@Override
public void onStreamLeftReceive(StreamData data, Handler handler) {
//Timber.i("onStreamLeftReceive");
Frame frame = data.frame();
if (mLeftBitmap == null) {
Bitmap.Config config;
switch (frame.format()) {
case GREY: config = Bitmap.Config.ALPHA_8; break;
case RGB888: config = Bitmap.Config.ARGB_8888; break;
default: Timber.e("Unaccepted stream format"); return;
}
mLeftBitmap = Bitmap.createBitmap(frame.width(), frame.height(), config);
}
mLeftBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(frame.data()));
mLeftImageView.post(() -> mLeftImageView.setImageBitmap(mLeftBitmap));
}
@Override
public void onStreamRightReceive(StreamData data, Handler handler) {
//Timber.i("onStreamRightReceive");
Frame frame = data.frame();
if (mRightBitmap == null) {
Bitmap.Config config;
switch (frame.format()) {
case GREY: config = Bitmap.Config.ALPHA_8; break;
case RGB888: config = Bitmap.Config.ARGB_8888; break;
default: Timber.e("Unaccepted stream format"); return;
}
mRightBitmap = Bitmap.createBitmap(frame.width(), frame.height(), config);
}
mRightBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(frame.data()));
mRightImageView.post(() -> mRightImageView.setImageBitmap(mRightBitmap));
}
@Override
public void onMotionDataReceive(ArrayList<MotionData> datas, Handler handler) {
if (datas.isEmpty()) return;
mTextView.post(() -> mTextView.setText(datas.get(0).imu().toString()));
}
@Override
protected void onDestroy() {
if (mMynteye != null) {
mMynteye.close();
mMynteye = null;
}
super.onDestroy();
}
private void toast(CharSequence text) {

View File

@@ -12,11 +12,35 @@
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@+id/image_left"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<ImageView
android:id="@+id/image_left"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/image_right"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text"
app:layout_constraintVertical_weight="1"
/>
<ImageView
android:id="@+id/image_right"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/image_left"
app:layout_constraintVertical_weight="1"
/>
</androidx.constraintlayout.widget.ConstraintLayout>