我在模拟器甚至真正的 android 手机上运行我的应用程序时遇到问题,即使没有语法错误,当我运行虚拟手机时,它会打开,但应用程序不起作用,我收到"can't initialize HUB"
如图所示的消息,并且我在控制台上看到以下日志:
08-14 19:40:23.271 2342-2357/com.thalmic.android.sample.helloworld V/RenderScript: 0xae4be000 Launching thread(s), CPUs 2
08-14 19:40:24.090 2342-2357/com.thalmic.android.sample.helloworld E/Surface: getSlotFromBufferLocked: unknown buffer: 0xae4b12a0
08-14 23:40:24.165 5064-5078/com.thalmic.android.sample.helloworld D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
[ 08-14 23:40:24.192 5064: 5064 D/ ]
HostConnection::get() New Host Connection established 0xaa9e81f0, tid 5064
08-14 23:40:24.556 5064-5078/com.thalmic.android.sample.helloworld I/OpenGLRenderer: Initialized EGL, version 1.4
08-14 23:40:25.289 5064-5078/com.thalmic.android.sample.helloworld V/RenderScript: 0xae5b7000 Launching thread(s), CPUs 2
08-14 23:40:25.433 5064-5078/com.thalmic.android.sample.helloworld E/Surface: getSlotFromBufferLocked: unknown buffer: 0xae4b12a0
08-14 23:40:28.898 5064-5070/com.thalmic.android.sample.helloworld W/art: Suspending all threads took: 65.953ms
08-14 23:40:28.950 5064-5064/com.thalmic.android.sample.helloworld E/Hub: Bluetooth not supported
08-14 23:40:30.344 5064-5064/com.thalmic.android.sample.helloworld I/Choreographer: Skipped 52 frames! The application may be doing too much work on its main thread.
08-14 23:40:31.042 5064-5078/com.thalmic.android.sample.helloworld E/Surface: getSlotFromBufferLocked: unknown buffer: 0xae4b10e0
我的源代码是:
/*
* Copyright (C) 2014 Thalmic Labs Inc.
* Distributed under the Myo SDK license agreement. See LICENSE.txt for details.
*/
package com.thalmic.android.sample.helloworld;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import com.thalmic.myo.AbstractDeviceListener;
import com.thalmic.myo.Arm;
import com.thalmic.myo.DeviceListener;
import com.thalmic.myo.Hub;
import com.thalmic.myo.Myo;
import com.thalmic.myo.Pose;
import com.thalmic.myo.Quaternion;
import com.thalmic.myo.XDirection;
import com.thalmic.myo.scanner.ScanActivity;
public class HelloWorldActivity extends Activity {
private TextView mLockStateView;
private TextView mTextView;
// Classes that inherit from AbstractDeviceListener can be used to receive events from Myo devices.
// If you do not override an event, the default behavior is to do nothing.
private DeviceListener mListener = new AbstractDeviceListener() {
// onConnect() is called whenever a Myo has been connected.
@Override
public void onConnect(Myo myo, long timestamp) {
// Set the text color of the text view to cyan when a Myo connects.
mTextView.setTextColor(Color.CYAN);
}
// onDisconnect() is called whenever a Myo has been disconnected.
@Override
public void onDisconnect(Myo myo, long timestamp) {
// Set the text color of the text view to red when a Myo disconnects.
mTextView.setTextColor(Color.RED);
}
// onArmSync() is called whenever Myo has recognized a Sync Gesture after someone has put it on their
// arm. This lets Myo know which arm it's on and which way it's facing.
@Override
public void onArmSync(Myo myo, long timestamp, Arm arm, XDirection xDirection) {
mTextView.setText(myo.getArm() == Arm.LEFT ? R.string.arm_left : R.string.arm_right);
}
// onArmUnsync() is called whenever Myo has detected that it was moved from a stable position on a person's arm after
// it recognized the arm. Typically this happens when someone takes Myo off of their arm, but it can also happen
// when Myo is moved around on the arm.
@Override
public void onArmUnsync(Myo myo, long timestamp) {
mTextView.setText(R.string.hello_world);
}
// onUnlock() is called whenever a synced Myo has been unlocked. Under the standard locking
// policy, that means poses will now be delivered to the listener.
@Override
public void onUnlock(Myo myo, long timestamp) {
mLockStateView.setText(R.string.unlocked);
}
// onLock() is called whenever a synced Myo has been locked. Under the standard locking
// policy, that means poses will no longer be delivered to the listener.
@Override
public void onLock(Myo myo, long timestamp) {
mLockStateView.setText(R.string.locked);
}
// onOrientationData() is called whenever a Myo provides its current orientation,
// represented as a quaternion.
@Override
public void onOrientationData(Myo myo, long timestamp, Quaternion rotation) {
// Calculate Euler angles (roll, pitch, and yaw) from the quaternion.
float roll = (float) Math.toDegrees(Quaternion.roll(rotation));
float pitch = (float) Math.toDegrees(Quaternion.pitch(rotation));
float yaw = (float) Math.toDegrees(Quaternion.yaw(rotation));
// Adjust roll and pitch for the orientation of the Myo on the arm.
if (myo.getXDirection() == XDirection.TOWARD_ELBOW) {
roll *= -1;
pitch *= -1;
}
// Next, we apply a rotation to the text view using the roll, pitch, and yaw.
mTextView.setRotation(roll);
mTextView.setRotationX(pitch);
mTextView.setRotationY(yaw);
}
// onPose() is called whenever a Myo provides a new pose.
@Override
public void onPose(Myo myo, long timestamp, Pose pose) {
// Handle the cases of the Pose enumeration, and change the text of the text view
// based on the pose we receive.
switch (pose) {
case UNKNOWN:
mTextView.setText(getString(R.string.hello_world));
break;
case REST:
case DOUBLE_TAP:
int restTextId = R.string.hello_world;
switch (myo.getArm()) {
case LEFT:
restTextId = R.string.arm_left;
break;
case RIGHT:
restTextId = R.string.arm_right;
break;
}
mTextView.setText(getString(restTextId));
break;
case FIST:
mTextView.setText(getString(R.string.pose_fist));
break;
case WAVE_IN:
mTextView.setText(getString(R.string.pose_wavein));
break;
case WAVE_OUT:
mTextView.setText(getString(R.string.pose_waveout));
break;
case FINGERS_SPREAD:
mTextView.setText(getString(R.string.pose_fingersspread));
break;
}
if (pose != Pose.UNKNOWN && pose != Pose.REST) {
// Tell the Myo to stay unlocked until told otherwise. We do that here so you can
// hold the poses without the Myo becoming locked.
myo.unlock(Myo.UnlockType.HOLD);
// Notify the Myo that the pose has resulted in an action, in this case changing
// the text on the screen. The Myo will vibrate.
myo.notifyUserAction();
} else {
// Tell the Myo to stay unlocked only for a short period. This allows the Myo to
// stay unlocked while poses are being performed, but lock after inactivity.
myo.unlock(Myo.UnlockType.TIMED);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello_world);
mLockStateView = (TextView) findViewById(R.id.lock_state);
mTextView = (TextView) findViewById(R.id.text);
// First, we initialize the Hub singleton with an application identifier.
Hub hub = Hub.getInstance();
if (!hub.init(this, getPackageName())) {
// We can't do anything with the Myo device if the Hub can't be initialized, so exit.
Toast.makeText(this, "Couldn't initialize Hub", Toast.LENGTH_SHORT).show();
finish();
return;
}
// Next, register for DeviceListener callbacks.
hub.addListener(mListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
// We don't want any callbacks when the Activity is gone, so unregister the listener.
Hub.getInstance().removeListener(mListener);
if (isFinishing()) {
// The Activity is finishing, so shutdown the Hub. This will disconnect from the Myo.
Hub.getInstance().shutdown();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (R.id.action_scan == id) {
onScanActionSelected();
return true;
}
return super.onOptionsItemSelected(item);
}
private void onScanActionSelected() {
// Launch the ScanActivity to scan for Myos to connect to.
Intent intent = new Intent(this, ScanActivity.class);
startActivity(intent);
}
}