我正在运行Android Wear应用,在特定消息(由Google Play可穿戴API定义)之后,将启动运行2分钟的活动。为确保手表保持活动状态,我设置了以下设置:
设置WakeLock(尝试完整和部分)
名为getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
将android:keepScreenOn="true"
放入“查看文件”
如果在创建活动创建消息之前手表屏幕尚未开启(即明亮),则磨损应用程序将仍然随机死亡。
这是有趣的部分:LG G Watch上存在此仅的错误。经过大量测试后,Moto 360没有出现同样的错误。当活动开始时它不会打开屏幕,但如果用户打开屏幕(通过点击两次或按侧面按钮),它将完美地显示活动的视图。
我已经包含了一些代码,因此您可以尝试重现该错误:
触发活动创建的移动端代码:
NodeApi.GetConnectedNodesResult nodes =
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
for (Node node : nodes.getNodes()) {
MessageApi.SendMessageResult result;
Log.d(TAG, "Started message sending process.");
//START_TRAINING = "/start-training"
result= Wearable.MessageApi.sendMessage(
mGoogleApiClient, node.getId(), START_TRAINING, null).await(); //Since I'm calling await() don't run this on UI thread
Log.d(TAG, "Sent to node: " + node.getId() + " with display name: " + node.getDisplayName());
if (!result.getStatus().isSuccess()) {
Log.e(TAG, "ERROR: failed to send Message: " + result.getStatus());
} else {
Log.d(TAG, "Message Successfully sent.");
}
}
开始活动的磨损面服务代码:
//Do this in a class that extends WearableListenerService + declared in Manifest with BIND_LISTENER
@Override
public void onMessageReceived(MessageEvent messageEvent) {
Log.d(TAG, "Message received for path " + messageEvent.getPath());
if (messageEvent.getPath().equals(START_TRAINING)) {
Intent i = new Intent(getBaseContext(), WearTrainingActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(i);
}
最后,为手表上的活动编写了一些代码:
public class WearTrainingActivity extends Activity实现SensorEventListener {
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private Sensor mGyroscope;
private TextView mPrompt;
private TextView mProgress;
private GoogleApiClient googleApiClient;
private ArrayList<AccelerationRecord> mAccelerationRecords = new ArrayList<AccelerationRecord>();
private ArrayList<GyroscopeRecord> mGyroscopeRecords = new ArrayList<GyroscopeRecord>();
private AtomicBoolean shouldCollect = new AtomicBoolean(false);
private static final String TAG = "WearTrainingActivity";
private PowerManager.WakeLock wakeLock;
private int delay = 1000 * 120;
private int maxNumRecords = (delay / 1000) * 20;
private int recordCount = 0;
private static final int SAMPLE_RATE = 50000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_training);
//Easy way to keep watch from sleeping on me
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mProgress = (TextView) findViewById(R.id.txtProgress);
mPrompt = (TextView) findViewById(R.id.txtPrompt);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
mProgress = (TextView) findViewById(R.id.txtProgress);
mPrompt = (TextView) findViewById(R.id.txtPrompt);
}
});
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
//Collect at 20Hz (Once every 50,000 microseconds)
mSensorManager.registerListener(this, mAccelerometer, SAMPLE_RATE);
mSensorManager.registerListener(this, mGyroscope, SAMPLE_RATE);
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "Connected to phone.");
}
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "Connection to phone suspended. Code: " + i);
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Error! Connection failed: " + connectionResult);
}
})
.addApi(Wearable.API)
.build();
googleApiClient.connect();
new Thread(new CollectTask()).start();
shouldCollect.set(true);
Log.wtf(TAG, "Started collecting");
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK,
"MyWakelockTag");
wakeLock.acquire();
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SAMPLE_RATE);
mSensorManager.registerListener(this, mGyroscope, SAMPLE_RATE);
}
@Override
public void onSensorChanged(SensorEvent event) {
if (shouldCollect.get()) {
long timestamp = System.currentTimeMillis();
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
switch(event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
mAccelerationRecords.add(new AccelerationRecord(x,y,z,timestamp));
break;
case Sensor.TYPE_GYROSCOPE:
GyroscopeRecord gyro = new GyroscopeRecord(x,y,z,timestamp);
Log.wtf(TAG, "Record is: " + gyro.toString());
mGyroscopeRecords.add(gyro);
}
recordCount++;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//Not used but must be overridden
}
class CollectTask implements Runnable {
@Override
public void run() {
INFINITY: while (true) { //Labelled loop
if (recordCount > maxNumRecords) {
shouldCollect.set(false);
wakeLock.release();
Log.wtf(TAG, "Ending stream");
ByteArrayOutputStream baos = null;
ByteArrayOutputStream baosG = null;
try {
baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(mAccelerationRecords);
oos.flush();
oos.close();
//Handle Gyro
baosG = new ByteArrayOutputStream();
ObjectOutputStream oosG = new ObjectOutputStream(baosG);
oosG.writeObject(mGyroscopeRecords);
oosG.flush();
oosG.close();
byte[] data = baos.toByteArray();
byte[] gData = baosG.toByteArray();
PutDataMapRequest dataMapRequest = PutDataMapRequest.create("/data");
dataMapRequest.getDataMap().putByteArray("/accel", data);
dataMapRequest.getDataMap().putByteArray("/gyro", gData);
PutDataRequest request = dataMapRequest.asPutDataRequest();
PendingResult<DataApi.DataItemResult> pendingResult =
Wearable.DataApi.putDataItem(googleApiClient, request);
//Vibrate and tell the user to check their phone
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(500L); //Vibrate for half a second
runOnUiThread(new Runnable() {
@Override
public void run() {
mPrompt.setText("Please finish the training by opening your phone.");
mProgress.setText("");
}
});
break INFINITY; //Leave the thread
} catch (IOException e) {
Log.d(TAG, "Something happened: " + e.getMessage());
}
}
}
}
}
}
我没有包含视图代码,因为它在这里基本上不相关(只有一个TextView),但如果认为有必要可以添加它。
我正在寻求解决方法的帮助。我已经联系了LG,但我怀疑他们会回复我的消息,更别说帮我解决了。