2013-10-09 2 views
1

У меня возникли проблемы с подключением встроенного приложения камеры на моем Droid Razr M, используя ACTION_IMAGE_CAPTURE Intent на ICS и надеялся, что кто-то еще это видел и знает, как решить/обходите проблему. Мое приложение запускает камеру, ждет пользователя, чтобы захватить и принять изображение, а затем обрабатывает его по возвращении. Но обратите внимание, что в образце приложения нет НИКАКОЙ обработки изображения, и проблема все еще происходит. Ключевым элементом здесь является то, что мы немедленно повторно вызываем камеру по возвращении от намерения, чтобы позволить пользователю продолжать делать снимки один за другим. Это отлично работает на многих устройствах (более десятка различных устройств), но не работает на Droid Razr M, работающем на 4.1.2 (а также более ранних версиях ICS). Сбой проявляется после второй фотографии - все кнопки на камере становятся отключенными, и работает только кнопка «Назад». Проблема не возникает, если мы добавили задержку в 5 или более секунд в наше приложение, прежде чем перезапустить Intent, но это неприемлемо. Вот простой репро приложение, которое демонстрирует проблему (обратите внимание, что вам необходимо для того, чтобы разрешение WRITE_EXTERNAL_STORAGE для этой работы):Droid RAZR M Камера Замораживает при вызове через ACTION_IMAGE_CAPTURE Намерение

public class MainActivity extends Activity { 

private static final int RESPONSE_SINGLE_SHOT = 45; 
private static final String TAG = "CameraTest"; 

private String mCameraFilePath = null; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    onLaunchCamera(true); //The launch is here only for simplification - it also fails in onStart() 
} 

@Override 
protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) 
{ 
    super.onActivityResult(requestCode, resultCode, intent); 
    processImage(requestCode, resultCode, intent); 
} 

public void onLaunchCamera(boolean fromUserAction) 
{ 
    final String storageState = Environment.getExternalStorageState(); 
    if (storageState.equals(Environment.MEDIA_MOUNTED)) 
    { 
     final Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
     cameraIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 

     final List<ResolveInfo> list = getPackageManager().queryIntentActivities(cameraIntent, 0); 
     //Grab the first camera in the list, this should be the camera app that came with the device: 
     final String packageName = list.get(0).activityInfo.packageName; 
     final String name = list.get(0).activityInfo.name; 

     final File publicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM); 
     final Time t = new Time(); 
     t.setToNow(); 

     File cameraFile = new File(publicDir, "/Camera/" + makePhotoFileName(t) ); 
     mCameraFilePath = cameraFile.getAbsolutePath(); 
     Log.i(TAG, "creating camera file: " + mCameraFilePath); 

     try 
     { 
      if (cameraFile.exists() == false) 
      { 
       cameraFile.getParentFile().mkdirs(); 
       if (cameraFile.createNewFile()) 
       { 
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile)); 
       } else { 
        Log.e(TAG, "failed to create file:" + cameraFile.getAbsolutePath()); 
        return; 
       } 
      } 

     } catch (IOException e) 
     { 
      Log.e(TAG, "Could not create file.", e); 
      return; 
     } 

     cameraIntent.setComponent(new ComponentName(packageName, name)); 
     startActivityForResult(cameraIntent, RESPONSE_SINGLE_SHOT); 

    } else { 
     Log.e(TAG, "SD card not present"); 
    } 
} 

private void processImage(final int requestCode, final int resultCode, final Intent intent) { 
    switch (requestCode) 
    { 
     case RESPONSE_SINGLE_SHOT: 
      if (resultCode == RESULT_OK) 
      {  
       runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         onLaunchCamera(false); //Immediately re-run camera 
        } 
       }); 
      } 
      else { 
       // delete the placeholder file we created 
       if (mCameraFilePath != null) { 
        final File cameraFile = new File(mCameraFilePath); 
        cameraFile.delete(); 
        mCameraFilePath = null; 
       } 
      } 
      break; 
     default: 
      break; 
    } 
} 

private String makePhotoFileName(final Time t) { 
    final String fileName = t.format("IMG_%Y%m%d_%H%M%S") + ".jpg"; 
    return fileName; 
} 
} 

Любая помощь очень ценится.

+0

Вы пытались выполнить обработку асинхронно? – jonstaff

+0

Может ли это быть связано с этой проблемой? http://stackoverflow.com/questions/18299661/ideas-of-source-of-qualcommcamerahardware-native-get-picture-msm-cam-ioctl-get –

+0

«но это неприемлемо» - тогда вам не следует полагаться на приложение сторонней камеры. В конце концов, их, наверное, тысяча, как предустановленная, так и загруженная. Поведение любого из них немного непредсказуемо. – CommonsWare

ответ

0

Единственное решение, которое мы смогли придумать для камеры по умолчанию на Razr M, - это не сразу вернуться к камере после захвата изображения. Мы сделали это, вставив следующий код непосредственно перед блоком примерки улова в onLaunchCamera():

if (!fromUserAction && name.equals("com.motorola.camera.Camera") && Build.MODEL.equals("XT907")) 
    return; 

Это просто работа вокруг, но держать камеру от отбоя.