2014-10-04 3 views
0

Я сделал приложение с простой кнопкой SOS, когда я нажимаю кнопку, он посылает сигнал SOS в морском коде из фонарика. Это прекрасно работает. Но когда я нажимаю кнопку второй раз или запускаю приложение во второй раз, он просто падает.Нажатие кнопки приложения для Android во второй раз вызывает сбой

После этого он снова работает 1 раз.

У меня нет подсказки о том, что происходит не так.

Вот мой код от основной деятельности:

public class MainActivity extends ActionBarActivity { 
public final static String SOS_MORSE = "111000111"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
} 

/** Called when the user clicks the Send button */ 
public void sendSOS(View view) { 
    /* Open the camera and get the parameters to control the flashlight */ 
    Camera cam = Camera.open(); 
    Parameters p = cam.getParameters(); 
    char prevChar = 1; 

    for (int i = 0; i < SOS_MORSE.length(); i++) { 
     /* If it's part of the S's the signal has to be faster, short on, short off */ 
     if (SOS_MORSE.charAt(i) == '1') { 
      /* The last char was a 0 so it was part of the letter O signal, so we pause for a brief time to distinguish between the signals of the O and the S */ 
      if(prevChar == '0'){ 
       try { 
        Thread.sleep(50); /* Pause for a very short time */ 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      /* Turn the camera on */ 
      p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
      cam.setParameters(p); 
      cam.startPreview(); 

      /* Short on */ 
      try { 
       Thread.sleep(120); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      /* Turn the camera off */ 
      p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 
      cam.setParameters(p); 

      /* Short off */ 
      try { 
       Thread.sleep(120); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      prevChar = SOS_MORSE.charAt(i); 
     } else { /* If it's part of the O, the signals have to be longer */ 
      /* The last char was a 1 so it was part of the letter S signal, so we pause for a brief time to distinguish between the signals of the S and the O */ 
      if(prevChar == '1'){ 
       try { 
        Thread.sleep(50); /* Pause for a very short time */ 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

      /* Turn the camera on */ 
      p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
      cam.setParameters(p); 
      cam.startPreview(); 

      /* Turn it on for a longer time */ 
      try { 
       Thread.sleep(400); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      /* Turn the camera off */ 
      p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 
      cam.setParameters(p); 

      /* Turn it off for a longer time */ 
      try { 
       Thread.sleep(400); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      prevChar = SOS_MORSE.charAt(i); 
     } 
    } 
    cam = null; 
} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 
    if (id == R.id.action_settings) { 
     return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 
} 

Это является деятельность основной XML файл:

<?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="horizontal"> 
<Button 
    android:id="@+id/buttonFlashlight" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerVertical="true" 
    android:layout_centerHorizontal="true" 
    android:onClick="sendSOS" 
    android:text="SOS" /> 

И это файл манифеста:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.myfirstapp" 
android:versionCode="1" 
android:versionName="1.0" > 

<uses-permission android:name="android.permission.CAMERA" /> 
<uses-feature android:name="android.hardware.camera" /> 

<uses-sdk 
    android:minSdkVersion="8" 
    android:targetSdkVersion="19" /> 

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" > 
    <activity 
     android:name=".MainActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

В LogCat он говорит, что не удалось подключиться к службе камеры, эта строка кода:

Camera cam = Camera.open();

ответ

0

Я думаю, вы должны следовать правилам Android при использовании Camera

Вместо

Camera cam = Camera.open(); 

Camera cam = getCameraInstance(); 
// check for null, if it is, then camera is either not available or in use 
... 
/** A safe way to get an instance of the Camera object. */ 
public static Camera getCameraInstance(){ 
    Camera c = null; 
    try { 
     c = Camera.open(); // attempt to get a Camera instance 
    } 
    catch (Exception e){ 
     // Camera is not available (in use or does not exist) 
    } 
    return c; // returns null if camera is unavailable 
} 

А также после использования Camera (если уже сделано с ним), используйте release() метод Camera` и используйте попробовать поймать блок с наконец

/** Called when the user clicks the Send button */ 
    public void sendSOS(View view) { 
     Camera cam = null; 
     try{ 
     cam = getCameraInstance(); 
     ... 
     } 
     catch(Exception e){ 
     // TODO: if camera is null 
     // find a work around 
     // either prompt user that camera is still not available 
     // or(bad idea) recursion with ProgressBar 
     // like sendSOS(view); and let the user wait using Handler 
     // if these doesnt work, add a callback to the camera 
     // `Camera.ErrorCallback` 
     // if CAMERA_ERROR_SERVER_DIED will return in `onError(int,Camera)` 
     // then In this case, the application must release the Camera object and instantiate a new one. 
     } 
     finally{ 
     // this should be in a worker thread, and use a callback if camera is already release 
     // in some cases this should work, but in order not to block the main thread 
     // we can use asynctask to release the camera resources here and use a callback 
     // whenever the onPostExecute executes, then trigger a function that camera is ready again to    
     // be opened 
     cam.release(); 
     } 
    } 

справа внизу от Guide Android, что вы должны проверить исключения, И я думаю, камера уже доступна, поэтому у вас есть исключение в вашем logcat.

Осторожно: Всегда проверяйте исключения при использовании Camera.open(). Если вы не заметите исключения, если камера используется или не существует, это приведет к отключению вашего приложения системой.

Далее читать документы here

Надежда, которая поможет :)

+0

Спасибо, что сделал это работает для меня. Но я сомневаюсь, если это не даст ошибку, если getInstance возвращает null, в конце концов вы все еще выполняете cam.release(), если cam имеет значение null, вы получаете исключение null pointerexception. Мне интересно, будет ли мое решение работать с камерой только в конце? – user3801533

+0

@ user3801533 просмотреть мое редактирование, поместить исключение catch в ваш блок catch try finally. – Spurdow

Смежные вопросы