feat(android): view mynteye datas
This commit is contained in:
parent
74b71dc161
commit
6988ae803b
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
|
@ -47,8 +47,8 @@ public:
|
|||
/** Get the datas of stream */
|
||||
virtual std::vector<std::shared_ptr<::mynteye_jni::StreamData>> GetStreamDatas(::mynteye_jni::Stream stream) = 0;
|
||||
|
||||
/** Enable cache motion datas */
|
||||
virtual void EnableCacheMotionDatas(int32_t max_size) = 0;
|
||||
/** Enable cache motion datas until get them, otherwise using callback instead */
|
||||
virtual void EnableMotionDatas(int32_t max_size) = 0;
|
||||
|
||||
/** Get the motion datas */
|
||||
virtual std::vector<std::shared_ptr<::mynteye_jni::MotionData>> GetMotionDatas() = 0;
|
||||
|
|
|
@ -81,30 +81,43 @@ void DeviceImpl::ConfigStreamRequest(
|
|||
}
|
||||
|
||||
void DeviceImpl::Start(::mynteye_jni::Source source) {
|
||||
device_->Start(from_jni(source));
|
||||
}
|
||||
|
||||
void DeviceImpl::Stop(::mynteye_jni::Source source) {
|
||||
device_->Stop(from_jni(source));
|
||||
}
|
||||
|
||||
void DeviceImpl::WaitForStreams() {
|
||||
device_->WaitForStreams();
|
||||
}
|
||||
|
||||
std::shared_ptr<::mynteye_jni::StreamData> DeviceImpl::GetStreamData(
|
||||
::mynteye_jni::Stream stream) {
|
||||
return nullptr;
|
||||
auto&& data = device_->GetStreamData(from_jni(stream));
|
||||
return std::make_shared<StreamDataImpl>(data);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<::mynteye_jni::StreamData>>
|
||||
DeviceImpl::GetStreamDatas(::mynteye_jni::Stream stream) {
|
||||
return {};
|
||||
std::vector<std::shared_ptr<::mynteye_jni::StreamData>> datas;
|
||||
for (auto&& data : device_->GetStreamDatas(from_jni(stream))) {
|
||||
datas.push_back(std::make_shared<StreamDataImpl>(data));
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
|
||||
void DeviceImpl::EnableCacheMotionDatas(int32_t max_size) {
|
||||
void DeviceImpl::EnableMotionDatas(int32_t max_size) {
|
||||
device_->EnableMotionDatas(max_size);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<::mynteye_jni::MotionData>>
|
||||
DeviceImpl::GetMotionDatas() {
|
||||
return {};
|
||||
std::vector<std::shared_ptr<::mynteye_jni::MotionData>> datas;
|
||||
for (auto&& data : device_->GetMotionDatas()) {
|
||||
datas.push_back(std::make_shared<MotionDataImpl>(data));
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
|
||||
} // namespace mynteye_jni
|
||||
|
|
|
@ -37,8 +37,8 @@ class DeviceImpl : public Device {
|
|||
/** Get the datas of stream */
|
||||
std::vector<std::shared_ptr<::mynteye_jni::StreamData>> GetStreamDatas(::mynteye_jni::Stream stream) override;
|
||||
|
||||
/** Enable cache motion datas */
|
||||
void EnableCacheMotionDatas(int32_t max_size) override;
|
||||
/** Enable cache motion datas until get them, otherwise using callback instead */
|
||||
void EnableMotionDatas(int32_t max_size) override;
|
||||
|
||||
/** Get the motion datas */
|
||||
std::vector<std::shared_ptr<::mynteye_jni::MotionData>> GetMotionDatas() override;
|
||||
|
|
|
@ -9,13 +9,13 @@ namespace mynteye_jni {
|
|||
|
||||
class MotionDataImpl : public MotionData {
|
||||
public:
|
||||
using motion_data_t = std::shared_ptr<MYNTEYE_NAMESPACE::device::MotionData>;
|
||||
using motion_data_t = MYNTEYE_NAMESPACE::device::MotionData;
|
||||
|
||||
explicit MotionDataImpl(const motion_data_t& data) : data_(data) {}
|
||||
~MotionDataImpl() {}
|
||||
|
||||
ImuData Imu() override {
|
||||
auto&& imu = data_->imu;
|
||||
auto&& imu = data_.imu;
|
||||
return {
|
||||
imu->frame_id,
|
||||
imu->flag,
|
||||
|
|
|
@ -10,13 +10,13 @@ namespace mynteye_jni {
|
|||
|
||||
class StreamDataImpl : public StreamData {
|
||||
public:
|
||||
using stream_data_t = std::shared_ptr<MYNTEYE_NAMESPACE::device::StreamData>;
|
||||
using stream_data_t = MYNTEYE_NAMESPACE::device::StreamData;
|
||||
|
||||
explicit StreamDataImpl(const stream_data_t& data) : data_(data) {}
|
||||
~StreamDataImpl() {}
|
||||
|
||||
ImgData Img() override {
|
||||
auto&& img = data_->img;
|
||||
auto&& img = data_.img;
|
||||
return {
|
||||
img->frame_id,
|
||||
static_cast<int64_t>(img->timestamp),
|
||||
|
@ -25,11 +25,11 @@ class StreamDataImpl : public StreamData {
|
|||
}
|
||||
|
||||
std::shared_ptr<::mynteye_jni::Frame> Frame() override {
|
||||
return std::make_shared<::mynteye_jni::FrameImpl>(data_->frame);
|
||||
return std::make_shared<::mynteye_jni::FrameImpl>(data_.frame);
|
||||
}
|
||||
|
||||
int64_t FrameId() override {
|
||||
return data_->frame_id;
|
||||
return data_.frame_id;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -109,12 +109,12 @@ CJNIEXPORT jobject JNICALL Java_com_slightech_mynteye_Device_00024CppProxy_nativ
|
|||
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
|
||||
}
|
||||
|
||||
CJNIEXPORT void JNICALL Java_com_slightech_mynteye_Device_00024CppProxy_native_1enableCacheMotionDatas(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jint j_maxSize)
|
||||
CJNIEXPORT void JNICALL Java_com_slightech_mynteye_Device_00024CppProxy_native_1enableMotionDatas(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jint j_maxSize)
|
||||
{
|
||||
try {
|
||||
DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef);
|
||||
const auto& ref = ::djinni::objectFromHandleAddress<::mynteye_jni::Device>(nativeRef);
|
||||
ref->EnableCacheMotionDatas(::djinni::I32::toCpp(jniEnv, j_maxSize));
|
||||
ref->EnableMotionDatas(::djinni::I32::toCpp(jniEnv, j_maxSize));
|
||||
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, )
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ public interface Device {
|
|||
@NonNull
|
||||
public ArrayList<com.slightech.mynteye.StreamData> getStreamDatas(@NonNull com.slightech.mynteye.Stream stream);
|
||||
|
||||
/** Enable cache motion datas */
|
||||
public void enableCacheMotionDatas(int maxSize);
|
||||
/** Enable cache motion datas until get them, otherwise using callback instead */
|
||||
public void enableMotionDatas(int maxSize);
|
||||
|
||||
/** Get the motion datas */
|
||||
@NonNull
|
||||
|
@ -135,12 +135,12 @@ public interface Device {
|
|||
private native ArrayList<com.slightech.mynteye.StreamData> native_getStreamDatas(long _nativeRef, com.slightech.mynteye.Stream stream);
|
||||
|
||||
@Override
|
||||
public void enableCacheMotionDatas(int maxSize)
|
||||
public void enableMotionDatas(int maxSize)
|
||||
{
|
||||
assert !this.destroyed.get() : "trying to use a destroyed object";
|
||||
native_enableCacheMotionDatas(this.nativeRef, maxSize);
|
||||
native_enableMotionDatas(this.nativeRef, maxSize);
|
||||
}
|
||||
private native void native_enableCacheMotionDatas(long _nativeRef, int maxSize);
|
||||
private native void native_enableMotionDatas(long _nativeRef, int maxSize);
|
||||
|
||||
@Override
|
||||
public ArrayList<com.slightech.mynteye.MotionData> getMotionDatas()
|
||||
|
|
|
@ -26,8 +26,8 @@ device = interface +c {
|
|||
# Get the datas of stream
|
||||
get_stream_datas(stream: stream): list<stream_data>;
|
||||
|
||||
# Enable cache motion datas
|
||||
enable_cache_motion_datas(max_size: i32);
|
||||
# Enable cache motion datas until get them, otherwise using callback instead
|
||||
enable_motion_datas(max_size: i32);
|
||||
# Get the motion datas
|
||||
get_motion_datas(): list<motion_data>;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user