2013-10-09 14 views
1

我無法調用使用ICS上的ACTION_IMAGE_CAPTURE意向內置在我的DROID RAZR M相機的應用程序,並希望其他人看到了這一點,並且知道如何解決/解決這個問題。 我的應用程序啓動相機,等待用戶捕捉並接受圖像,然後在返回時處理它。但請注意,下面的示例應用程序中沒有對圖像進行處理,問題仍然存在。這裏的關鍵要素是,我們在從Intent返回後立即重新調用攝像頭,以便用戶能夠一個接一個地繼續拍攝照片。這在很多設備(十幾種不同的設備)上工作正常,但在運行4.1.2的Droid Razr M(以及早期版本的ICS)上失敗。拍攝第二張照片後出現故障 - 相機上的所有按鈕都被禁用,只有後退按鈕可以工作。如果我們在重新啓動Intent之前在應用程序中放置了5秒或更長時間的延遲,則問題不會發生 - 但這是不可接受的。 下面是一個簡單的攝製應用程序演示該問題(注意,您將需要啓用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(在try-catch塊)之前插入下面的代碼:

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

這只是一個變通,但它使相機不掛斷。