-1

У меня есть 2 устройства, чтобы проверить мое приложение: v370 Acer под управлением Android 4.2.2 и Samsung Galaxy S6 на 6.0.1Camera.open работает на Android 4.2.2, но не работает на 6.0.1

Приложение отлично работает на Acer, но мгновенно падает на S6. Я использую _camera = Camera.open(0); и отладка говорит, что он сбой в этот момент.

Ошибки я получаю:

09-15 11:24:33.491 15284-15284/com.user.qrReader E/AndroidRuntime: FATAL EXCEPTION: main 
    Process: com.user.qrReader, PID: 15284 
    java.lang.RuntimeException: Unable to resume activity {com.user.qrReader/com.user.qrReader.MainActivity}: 
    java.lang.RuntimeException: Fail to connect to camera service 
     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4156) 
     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250) 
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3361) 
     at android.app.ActivityThread.access$1100(ActivityThread.java:222) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:158) 
     at android.app.ActivityThread.main(ActivityThread.java:7229) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
    Caused by: java.lang.RuntimeException: Fail to connect to camera service 
     at android.hardware.Camera.<init>(Camera.java:568) 
     at android.hardware.Camera.open(Camera.java:405) 
     at com.user.qrReader.CameraPreview.openCamera(CameraPreview.java:206) 
     at com.user.qrReader.CameraPreview.captureStart(CameraPreview.java:288) 
     at com.user.qrReader.QRReaderAppManager.onResume(QRReaderAppManager.java:208) 
     at com.user.qrReader.MainActivity.onResume(MainActivity.java:187) 
     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1286) 
     at android.app.Activity.performResume(Activity.java:6987) 
     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4145) 
     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250)  
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3361)  
     at android.app.ActivityThread.access$1100(ActivityThread.java:222)  
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)  
     at android.os.Handler.dispatchMessage(Handler.java:102)  
     at android.os.Looper.loop(Looper.java:158)  
     at android.app.ActivityThread.main(ActivityThread.java:7229)  
     at java.lang.reflect.Method.invoke(Native Method)  
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)  
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

Вот разрешения в моем манифесте:

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

Я не могу использовать Camera2, потому что я должен держать приложение совместимо, по крайней мере, андроид 4, и я не знаю, в каком направлении идти. Это должно быть что-то связанное с новым андроидом, но я не могу найти что. Есть предположения ?

EDIT: Вы также можете сделать это вручную, как только APK установлен, перейдя в настройки> приложения> диспетчер приложений> {my app}> permissions> разрешить камеру. Конечно, это ужасно и бесполезно, если у вас есть решение, но это помогло мне немного, пока я отлаживался, поэтому я оставлю его здесь. Благодарим вас за ответы.

+1

может быть это из-за время выполнения разрешения в зефира –

+1

на 6.0 и необходимо проверить разрешение на время выполнения и CAMERA трудно разрешения так и нужно, чтобы проверить это – Rodriquez

+1

Возможно, [это] (HTTP : //stackoverflow.com/a/33498105/5165244) может оказать некоторую помощь. –

ответ

0

Для проверки разрешения я создал отдельный класс, как показано ниже:

public class MarshMallowPermission { 

    public static final int RECORD_PERMISSION_REQUEST_CODE = 1; 
    public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 2; 
    public static final int CAMERA_PERMISSION_REQUEST_CODE = 3; 
    Activity activity; 

    public MarshMallowPermission(Activity activity) { 
     this.activity = activity; 
    } 

    public boolean checkPermissionForRecord(){ 
     int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO); 
     if (result == PackageManager.PERMISSION_GRANTED){ 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public boolean checkPermissionForExternalStorage(){ 
     int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); 
     if (result == PackageManager.PERMISSION_GRANTED){ 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public boolean checkPermissionForCamera(){ 
     int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA); 
     if (result == PackageManager.PERMISSION_GRANTED){ 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public void requestPermissionForRecord(){ 
     if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.RECORD_AUDIO)){ 
      Toast.makeText(activity, "Microphone permission needed for recording. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show(); 
     } else { 
      ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.RECORD_AUDIO},RECORD_PERMISSION_REQUEST_CODE); 
     } 
    } 

    public void requestPermissionForExternalStorage(){ 
     if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){ 
      Toast.makeText(activity, "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show(); 
     } else { 
      ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE); 
     } 
    } 

    public void requestPermissionForCamera(){ 
     if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){ 
      Toast.makeText(activity, "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show(); 
     } else { 
      ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE); 
     } 
    } 
} 

Тогда для получения

MarshMallowPermission marshMallowPermission = new MarshMallowPermission(this); 


public void getPhotoFromCamera() { 

    if (!marshMallowPermission.checkPermissionForCamera()) { 
     marshMallowPermission.requestPermissionForCamera(); 
    } else { 
     if (!marshMallowPermission.checkPermissionForExternalStorage()) { 
      marshMallowPermission.requestPermissionForExternalStorage(); 
     } else { 
      Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
      File mediaStorageDir = new File(
        Environment.getExternalStorageDirectory() 
          + File.separator 
          + getString(R.string.directory_name_corp_chat) 
          + File.separator 
          + getString(R.string.directory_name_images) 
      ); 

      if (!mediaStorageDir.exists()) { 
       mediaStorageDir.mkdirs(); 
      } 

      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", 
        Locale.getDefault()).format(new Date()); 
      try { 
       mediaFile = File.createTempFile(
         "IMG_" + timeStamp, /* prefix */ 
         ".jpg",   /* suffix */ 
         mediaStorageDir  /* directory */ 
       ); 
       takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile)); 
       startActivityForResult(takePictureIntent, PICK_FROM_CAMERA); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 
+0

Спасибо, это сработало! –

+0

На самом деле это сработало, когда я использовал только одно разрешение (я использовал сканирование QRCode в реальном времени, поэтому мне не нужна запись или внешнее хранилище), но теперь он не работает: если я попрошу предоставить 2 разрешения, я получаю W/Activity: Can reqeust only one set of permissions at a time, с опечаткой! Я не нашел его в вашем коде, поэтому не знаю, откуда он. В любом случае, я не могу запросить 2 разрешения подряд :( –

+0

Решенный, я сделал новый запрос, следующий за [этой ссылкой] (http://stackoverflow.com/questions/34040355/how-to-check-the-multiple- разрешение-на-одном-запрос-в-android-m) со всеми моими разрешениями внутри. Другой запрос затем устарел. –

0

«Примечание: если вы используете приложения M и выше и объявляете с использованием разрешения CAMERA, которое не предоставляется, то попытка использовать это действие приведет к исключению SecurityException».

Это действительно странно. Не имеешь смысла. Приложение объявляет разрешение камеры, используя намерение с действием IMAGE_CAPTURE, просто запускается в SecurityException. Но если ваше приложение не объявляет разрешение камеры, используя намерение с действием, IMAGE_CAPTURE может запускать приложение для камеры без проблем.

Обходным решением будет проверка, что приложение имеет разрешение камеры, включенное в манифест, если оно есть, запросите разрешение камеры перед запуском намерения.

Вот как проверить, включено ли разрешение в манифест, не имеет значения, предоставлено разрешение или нет.

public boolean hasPermissionInManifest(Context context, String permissionName) { 
final String packageName = context.getPackageName(); 
try { 
    final PackageInfo packageInfo = context.getPackageManager() 
      .getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); 
    final String[] declaredPermisisons = packageInfo.requestedPermissions; 
    if (declaredPermisisons != null && declaredPermisisons.length > 0) { 
     for (String p : declaredPermisisons) { 
      if (p.equals(permissionName)) { 
       return true; 
      } 
     } 
    } 
} catch (NameNotFoundException e) { 

} 
return false; 

}

+0

Спасибо, я попробую. Я предполагаю, что я делаю "if (hasPermissionInManifest (...)) camera.open (0);" ? –

0

класс камеры является устаревшим, поскольку API 21.

Camera class documentation

рекомендуется использовать новый android.hardware.camera2 API для новых приложений .

К сожалению, я еще не испытал этого, поэтому больше не смогу помочь.

Еще несовершеннолетний шанс взять, попробовать:

Camera.open(); // Without argument 

С уважением

+0

Я отредактировал сообщение, я не могу использовать camera2, потому что он был введен в API уровня 21. Я пробовал без аргументов без успеха. –

0

это в Деятельности. Я проверяю разрешения и сохраняю их, изменяю некоторые мои разрешения на разрешение CAMERA. Это рабочий пример.

private static final int REQUEST_CODE_GET_ACCOUNTS = 101; 
    private static final int REQUEST_AUDIO_PERMISSION = 102; 

@TargetApi(23) 
public void checkAudioPermission() { 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 
     playerFragment.setupVisualizerFxAndUI(); 
     return; 
    } 
    if (this.checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager 
      .PERMISSION_GRANTED) { 
     requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, 
       REQUEST_AUDIO_PERMISSION); 
    } else { 
     playerFragment.setupVisualizerFxAndUI(); 
    } 
} 

@TargetApi(23) 
public void checkGmailPermission() { 
    if (isDeviceOnline()) { 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 
      showGmailRecFragment(true); 
      return; 
     } 
     if (this.checkSelfPermission(Manifest.permission.GET_ACCOUNTS) != PackageManager 
       .PERMISSION_GRANTED) { 
      requestPermissions(new String[]{Manifest.permission.GET_ACCOUNTS}, 
        REQUEST_CODE_GET_ACCOUNTS); 
      return; 
     } else { 
      showGmailRecFragment(true); 
     } 
    } else { 
     Utils.showToast(this, getString(R.string.no_internet)); 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] 
     grantResults) { 
    switch (requestCode) { 
     case REQUEST_CODE_GET_ACCOUNTS: 
      if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       showGmailRecFragment(true); 
      } else { 
       Utils.showToast(this, getString(R.string.accounts_permision_denied)); 
      } 
      break; 
     case REQUEST_AUDIO_PERMISSION: 
      if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       playerFragment.setupVisualizerFxAndUI(); 
      } else { 
       Utils.showToast(this, getString(R.string.audio_permission_denied)); 
      } 
     default: 
      super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
      break; 
    } 
} 

, и это фрагмент, когда я хочу снова получить разрешение на проверку, или если пользователь отрицает это. Кроме того, это сохранить разрешения

private void setupViewVisualizer() { 
    if (!isLiveTv && !homeVideo.isVideoType()) { 
     ((PlayerActivity) activity).checkAudioPermission(); 
    } else { 
     return; 
    } 
} 
+0

Я не уверен, что это то, что я ищу. Я только говорю это, потому что я имеют аналогичный проект, используя тот же уровень API и тот же самый camera.open(), который отлично работает. Странно, что в одном из всех случаев «камера» пересекаются, а не в другом, и я не знаю почему. m Конечно, если бы я нашел, какая разница, камера будет работать. Я сделал несколько снимков экрана: i.imgur.com/LS5Y4v9.png Как вы можете видеть, код тот же, но камера пересечена во втором проекте. i.imgur. com/jfWCE50.png вот манифест, поскольку я подозреваю, что он имеет какое-то отношение к уровням и версиям API. –

+0

Эти два проекта очень похожи и были построены из та же основа, но один падает, а не другой. Я не нашел ничего о том, «почему скрестили камеру», как в том, как заставить Android Studio «принять это», все решения очень сложны и устраняют корень проблемы (по моему честному мнению, я могу ошибаться) –

+0

Оказывается один из них «@SuppressWarnings (« устаревание »)», а не другой. Это не решило проблему того, почему кто-то работает, а не другой, но это –

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