SensorManager Ошибка запуска потока
Я пытаюсь сделать приложение, которое использует акселерометр, чтобы обнаружить движения пользователя и вызвать некоторые события. Приложение требует большой работы, но каждый раз, когда я запускаю приложение в своем телефоне, я получаю ОШИБКУ "начало потока", но, похоже, ничего не происходит.
Вот LogCat:
04-15 17:46:21.380: E/BANANA(2516): Before sensor
04-15 17:46:21.380: D/SensorManager(2516): registerListener :: handle = 0 name= K2DM delay= 200000 Listener= com.example.rockpaperaccelerate.UseSensor@413cdf98
04-15 17:46:21.380: E/SensorManager(2516): thread start
04-15 17:46:21.520: E/BANANA(2516): AFter sensor
04-15 17:46:21.680: D/libEGL(2516): loaded /system/lib/egl/libGLES_android.so
04-15 17:46:21.800: D/libEGL(2516): loaded /system/lib/egl/libGLES_rhea.so
04-15 17:46:21.960: D/BRCM_EGL(2516): eglCreateContext() config: 18 context: 0x12e0a0, VC context 1, Thread 2516
04-15 17:46:21.960: D/BRCM_EGL(2516): eglCreateWindowSurface() surface: 0x2aa080, VC surface: 1, Thread: 2516
04-15 17:46:21.960: D/BRCM_EGL(2516): eglMakeCurrent(0x12e0a0, 0x2aa080, 0x2aa080) Thread: 2516
04-15 17:46:21.980: D/OpenGLRenderer(2516): Enabling debug mode 0
04-15 17:46:22.441: D/CLIPBOARD(2516): Hide Clipboard dialog at Starting input: finished by someone else... !
И это деятельность, где все происходит:
public class UseSensor extends Activity implements SensorEventListener{
private SensorManager mSensorManager;
private Sensor mSensor;
public int choice;
public WebView myWebView1;
public WebView myWebView2;
public TextView myTextView;
public String louts[]={"rock","paper","scissors"};
public int i=0;
public float gravity[]={0,0,0};
public float linear_acceleration[]={0,0,0};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rock_paper_accelerate_with_sensors);
Log.e("BANANA","Before sensor");
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
Log.e("BANANA","AFter sensor");
}
public void onRadioButtonClicked(View view) {
// Is the button now checked?
boolean checked = ((RadioButton) view).isChecked();
// Check which radio button was clicked
switch(view.getId()) {
case R.id.radio1:
if (checked)
// player chose rock
choice=1;
break;
case R.id.radio2:
if (checked)
// player chose paper
choice=2;
break;
case R.id.radio3:
if (checked)
// player chose scissors
choice=3;
break;
}
}
public void checkWin(int choice){
Random generator = new Random();
int machine = generator.nextInt( 3 )+1;
setContentView(R.layout.show_results);
myWebView1 = (WebView) findViewById(R.id.webView1);
myWebView2 = (WebView) findViewById(R.id.webView2);
myTextView = (TextView) findViewById(R.id.textView1);
switch (machine){
case 1: myWebView1.loadUrl("file:///android_asset/1.jpg");
break;
case 2: myWebView1.loadUrl("file:///android_asset/2.jpg");
break;
case 3: myWebView1.loadUrl("file:///android_asset/3.jpg");
break;
}
switch (choice){
case 1: myWebView2.loadUrl("file:///android_asset/1.jpg");
break;
case 2: myWebView2.loadUrl("file:///android_asset/2.jpg");
break;
case 3: myWebView2.loadUrl("file:///android_asset/3.jpg");
break;
}
if (choice==machine){
myTextView.setText("This is a tie!");
}
else if ((choice==3 && machine==2)||(choice==2 && machine==1)||(choice==1 && machine==3)){
myTextView.setText("You Win!");
}
else{
myTextView.setText("You Lose!");
}
Button myButton = (Button)findViewById(R.id.button1);
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
i=0;
Intent intent= new Intent(v.getContext(), UseSensor.class);
startActivityForResult(intent, 0);
}
});
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
final float alpha = (float) 0.8;
gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
linear_acceleration[0] = event.values[0] - gravity[0];
linear_acceleration[1] = event.values[1] - gravity[1];
linear_acceleration[2] = event.values[2] - gravity[2];
if (linear_acceleration[1]<-4.0){
if(i<3){
int findId = this.getResources().getIdentifier("com.example.rockpaperaccelerate:layout/" + louts[i], null, null);
setContentView(findId);
i=i+1;}
if (i==3){
mSensorManager.unregisterListener(this);
i=0;
checkWin(choice);
}
}
}
}
Может ли это быть ложным срабатыванием, как в этом случае, или я делаю что-то не так. Деятельность продолжается без остановки. В своей основной деятельности, которая вызывает UseSensor, я снова использую SensorManager. Фрагмент кода:
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
// Success! There's an accelerometer sensor
Intent intent= new Intent(this,UseSensor.class);
startActivity(intent);
}
Это связано с ошибкой?
Спасибо за ваше время.
----------РЕДАКТИРОВАТЬ------------------------
Ошибка остается, но она появляется только в первый раз, когда я запускаю приложение из eclipse. Если я останавливаю приложение и запускаю его снова с домашнего экрана моего телефона, оно не появляется. Приложение перестает работать иногда, но без каких-либо других ошибок, Я немного изменил свой код, добавив другой, если
if(choice !=0){
if (linear_acceleration[1]<-4.0){
if(i<3){
int findId = this.getResources().getIdentifier("com.example.rockpaperaccelerate:layout/" + louts[i], null, null);
setContentView(findId);
i=i+1;}
if (i==3){
mSensorManager.unregisterListener(this);
i=0;
checkWin(choice);
}
}
}
Я также безуспешно попробовал то, что предложил Лукас. Я также реализовал другую версию своего приложения, в которой есть только одно действие, и проблема остается. Единственное, что происходит, это то, что приложение перестает работать без каких-либо других ошибок logCat.
Вторая реализация
public class RockPaper3 extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mSensor;
public int choice=0;
public ImageView myImage1,myImage2;
public TextView myTextView;
public String louts[]={"rock","paper","scissors"};
public int i=0;
public float gravity[]={0,0,0};
public float linear_acceleration[]={0,0,0};
public boolean withSensor=true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
if (mSensor != null){
// Success! There's an accelerometer sensor
setContentView(R.layout.rock_paper_accelerate_with_sensors);
withSensor=true;
}
else {
mSensorManager.unregisterListener(this);
setContentView(R.layout.activity_rock_paper3);
withSensor=false;
}
}
public void onRadioButtonClicked(View view) {
// Is the button now checked?
boolean checked = ((RadioButton) view).isChecked();
// Check which radio button was clicked
switch(view.getId()) {
case R.id.radio1:
if (checked)
// player chose rock
choice=1;
break;
case R.id.radio2:
if (checked)
// player chose paper
choice=2;
break;
case R.id.radio3:
if (checked)
// player chose scissors
choice=3;
break;
}
if (withSensor==false){
checkWin(choice);
}
}
public void checkWin(int choice){
Random generator = new Random();
int machine = generator.nextInt( 3 )+1;
setContentView(R.layout.show_results);
myImage1 = (ImageView) findViewById(R.id.imageView1);
myImage2 = (ImageView) findViewById(R.id.imageView2);
myTextView = (TextView) findViewById(R.id.textView1);
switch (machine){
case 1: myImage1.setImageResource(R.drawable.rock);
break;
case 2: myImage1.setImageResource(R.drawable.paper);
break;
case 3: myImage1.setImageResource(R.drawable.scissors);
break;
}
switch (choice){
case 1: myImage2.setImageResource(R.drawable.rock);
break;
case 2: myImage2.setImageResource(R.drawable.paper);
break;
case 3: myImage2.setImageResource(R.drawable.scissors);
break;
}
if (choice==machine){
myTextView.setText("This is a tie!");
}
else if ((choice==3 && machine==2)||(choice==2 && machine==1)||(choice==1 && machine==3)){
myTextView.setText("You Win!");
}
else{
myTextView.setText("You Lose!");
}
Button myButton = (Button)findViewById(R.id.button1);
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
i=0;
Intent intent= new Intent(v.getContext(), RockPaper3.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
finish();
startActivity(intent);
}
});
}
/*
public void checkWin(int choice){
Random generator = new Random();
int machine = generator.nextInt( 3 )+1;
setContentView(R.layout.show_results);
myWebView1 = (WebView) findViewById(R.id.webView1);
myWebView2 = (WebView) findViewById(R.id.webView2);
myTextView = (TextView) findViewById(R.id.textView1);
switch (machine){
case 1: myWebView1.loadUrl("file:///android_asset/1.jpg");
break;
case 2: myWebView1.loadUrl("file:///android_asset/2.jpg");
break;
case 3: myWebView1.loadUrl("file:///android_asset/3.jpg");
break;
}
switch (choice){
case 1: myWebView2.loadUrl("file:///android_asset/1.jpg");
break;
case 2: myWebView2.loadUrl("file:///android_asset/2.jpg");
break;
case 3: myWebView2.loadUrl("file:///android_asset/3.jpg");
break;
}
if (choice==machine){
myTextView.setText("This is a tie!");
}
else if ((choice==3 && machine==2)||(choice==2 && machine==1)||(choice==1 && machine==3)){
myTextView.setText("You Win!");
}
else{
myTextView.setText("You Lose!");
}
Button myButton = (Button)findViewById(R.id.button1);
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
i=0;
Intent intent= new Intent(v.getContext(), RockPaper3.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
finish();
startActivity(intent);
}
});
}*/
@Override
protected void onResume(){
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
super.onResume();
}
@Override
protected void onPause(){
mSensorManager.unregisterListener(this);
super.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.rock_paper3, menu);
return true;
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
final float alpha = (float) 0.8;
gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
linear_acceleration[1] = event.values[1] - gravity[1];
if(choice !=0){
if (linear_acceleration[1]<-4.0){
if(i<3){
int findId = this.getResources().getIdentifier("com.example.rockpaperv3:layout/" + louts[i], null, null);
setContentView(findId);
i=i+1;}
if (i==3){
mSensorManager.unregisterListener(this);
i=0;
checkWin(choice);
}
}
}
}
}
Любые идеи, что означает эта ошибка и почему мое приложение иногда падает без каких-либо ошибок? Мне пришло в голову, что мой телефон может быть слишком тяжелым, чтобы справиться с этим плохо написанным приложением со всеми регистрациями акселерометра.
edit2
Ошибка возникает, когда я регистрирую слушателя
Edit3
После внесения множества изменений приложение работает без сбоев, но ошибка всегда есть. Должна быть ложная тревога, когда слушатель зарегистрирован
1 ответ
Измените свой код на:
в onResume вы должны зарегистрировать своего слушателя
в onPause вы отменяете регистрацию слушателя
сделать логическое значение isActive,
и измените ваш onclicklistener на:
Button myButton = (Button)findViewById(R.id.button1);
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
i=0;
isActive=true;
}
});
изменить свой onSensorChanged на:
@Override
public void onSensorChanged(SensorEvent event) {
if(!isActive)return;
final float alpha = (float) 0.8;
gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
linear_acceleration[1] = event.values[1] - gravity[1];
if (linear_acceleration[1]<-4.0){
if(i<3){
int findId = this.getResources().getIdentifier("com.example.rockpaperaccelerate:layout/" + louts[i], null, null);
setContentView(findId);
i=i+1;}
if (i==3){
isActive=false;
i=0;
checkWin(choice);
}
}
}
edit: или вы делаете это, как этот код ниже, но я действительно не рекомендую вам, чтобы изменить ваш слушатель по щелчку на:
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
i=0;
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
});