2016-12-11 21 views
8

Tôi đang sử dụng chuyển tiếp thẳng Camera API, để tương thích ngược. Quan điểm máy ảnh riêng của mình được overlayed nhẹ một ImageView và surfaceChanged tôi thực hiện điều này:Xem trước máy ảnh màu đen trong Android 7

camera.setPreviewCallback((data, arg1) -> LiveView.this.invalidate()); 
camera.setPreviewDisplay(mHolder); 
camera.startPreview(); 

đó hoạt động tốt trên tất cả các thiết bị cũ. Tôi đặt kích thước xem trước thành kích thước có sẵn lớn nhất trước đó trong surfaceCreated. Tuy nhiên trên Android 7.1, nó đột nhiên đen (trên Nexus 6 và Moto X Play, có thể là những người khác - vì vậy trên các thiết bị khác nhau). Bản thân số SurfaceView được chuyển thành màu xám trong Layout Inspector (willNotDraw = true), nhưng VISIBLE (và phần cứng được tăng tốc). Thật lạ lùng, tôi vẫn có thể chụp ảnh, sự kiện mà không cần xem trước và dữ liệu trong cuộc gọi lại xem trước chứa một hình ảnh.

Đồng thời tôi nhận được các bản ghi sau

E/mm-camera: mct_pipeline_send_ctrl_events: Send Set Parm events 
E/QCamera2HWI: static void* qcamera::QCameraCbNotifier::cbNotifyRoutine(void*) : cb message type 32768 not enabled! 
E/QCamera2HWI: static void* qcamera::QCameraCbNotifier::cbNotifyRoutine(void*) : cb message type 32768 not enabled! 
D/QCameraParameters: setSnapshotSkipHint: preview hint 3 fps 15.019738 

Có ai khác có kinh nghiệm một hình ảnh hoàn toàn đen trong Android 7? Có sửa chữa dễ dàng nào không? (Giống như vẽ nội dung của dữ liệu trực tiếp?)

+0

Không phải bạn có nghĩa vụ sử dụng Camera2 api cho phiên bản cao hơn Android? –

Trả lời

3

Đen màn hình xuất hiện kể từ khi bạn không có quyền đăng camera trên android 7 thiết bị

Chuyển đến settings-> apps-> chọn của bạn cấp ứng dụng> permissions-> Bật phép camera và kiểm tra

bạn cũng có thể xử lý việc này bên trong mã của bạn

Add sau phép bạn manifest

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

Để xin phép bạn có thể gọi như thế này.

ActivityCompat.requestPermissions(this, 
        new String[]{Manifest.permission.CAMERA}, 
        MY_PERMISSIONS_REQUEST_CAMERA); 

Để kiểm tra quyền truy cập camera

if (ContextCompat.checkSelfPermission(this, 
      Manifest.permission.CAMERA) 
      != PackageManager.PERMISSION_GRANTED) { 
} 

Bây giờ gọi lại nếu người dùng đã thực hiện bất kỳ hành động.

@Override 
public void onRequestPermissionsResult(int requestCode, 
            String permissions[], int[] grantResults) { 
switch (requestCode) { 
    case MY_PERMISSIONS_REQUEST_CAMERA: { 
     Log.i("Camera", "G : " + grantResults[0]); 
     // If request is cancelled, the result arrays are empty. 
     if (grantResults.length > 0 
       && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

      // permission was granted, yay! Do the 
      // contacts-related task you need to do. 

      openCamera(); 

     } else { 

      // permission denied, boo! Disable the 
      // functionality that depends on this permission. 

      if (ActivityCompat.shouldShowRequestPermissionRationale 
          (this, Manifest.permission.CAMERA)) { 

       showAlert(); 

      } else { 

      } 
     } 
     return; 
    } 

    // other 'case' lines to check for other 
    // permissions this app might request 

} 
} 

Dưới đây là hoàn dụ

import android.Manifest; 
    import android.app.Activity; 
    import android.app.AlertDialog; 
    import android.content.Context; 
    import android.content.DialogInterface; 
    import android.content.Intent; 
    import android.content.SharedPreferences; 
    import android.content.pm.PackageManager; 
    import android.net.Uri; 
    import android.os.Bundle; 
    import android.provider.Settings; 
    import android.support.v4.app.ActivityCompat; 
    import android.support.v4.content.ContextCompat; 
    import android.support.v7.app.AppCompatActivity; 
    import android.support.v7.widget.Toolbar; 

    public class MainActivity extends AppCompatActivity { 

public static final int MY_PERMISSIONS_REQUEST_CAMERA = 100; 
public static final String ALLOW_KEY = "ALLOWED"; 
public static final String CAMERA_PREF = "camera_pref"; 

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

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    if (ContextCompat.checkSelfPermission(this, 
      Manifest.permission.CAMERA) 
      != PackageManager.PERMISSION_GRANTED) { 

     if (getFromPref(this, ALLOW_KEY)) { 

      showSettingsAlert(); 

     } else if (ContextCompat.checkSelfPermission(this, 
       Manifest.permission.CAMERA) 
       != PackageManager.PERMISSION_GRANTED) { 
      // Should we show an explanation? 
      if (ActivityCompat.shouldShowRequestPermissionRationale(this, 
        Manifest.permission.CAMERA)) { 
       showAlert(); 
      } else { 
       // No explanation needed, we can request the permission. 
       ActivityCompat.requestPermissions(this, 
         new String[]{Manifest.permission.CAMERA}, 
         MY_PERMISSIONS_REQUEST_CAMERA); 
      } 
     } 
    } else { 
     openCamera(); 
    } 

} 

public static void saveToPreferences(Context context, String key, 
               Boolean allowed) { 
    SharedPreferences myPrefs = context.getSharedPreferences 
           (CAMERA_PREF, Context.MODE_PRIVATE); 
    SharedPreferences.Editor prefsEditor = myPrefs.edit(); 
    prefsEditor.putBoolean(key, allowed); 
    prefsEditor.commit(); 
} 

public static Boolean getFromPref(Context context, String key) { 
    SharedPreferences myPrefs = context.getSharedPreferences 
           (CAMERA_PREF, Context.MODE_PRIVATE); 
    return (myPrefs.getBoolean(key, false)); 
} 

private void showAlert() { 
    AlertDialog alertDialog = new AlertDialog.Builder(this).create(); 
    alertDialog.setTitle("Alert"); 
    alertDialog.setMessage("App needs to access the Camera."); 
    alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "DONT ALLOW", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.dismiss(); 
        finish(); 
       } 
      }); 
    alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "ALLOW", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.dismiss(); 
        ActivityCompat.requestPermissions(MainActivity.this, 
          new String[]{Manifest.permission.CAMERA}, 
          MY_PERMISSIONS_REQUEST_CAMERA); 

       } 
      }); 
    alertDialog.show(); 
} 

private void showSettingsAlert() { 
    AlertDialog alertDialog = new AlertDialog.Builder(this).create(); 
    alertDialog.setTitle("Alert"); 
    alertDialog.setMessage("App needs to access the Camera."); 
    alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "DONT ALLOW", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.dismiss(); 
        //finish(); 
       } 
      }); 
    alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "SETTINGS", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.dismiss(); 
        startInstalledAppDetailsActivity(MainActivity.this); 

       } 
      }); 
    alertDialog.show(); 
} 


@Override 
public void onRequestPermissionsResult 
       (int requestCode, String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case MY_PERMISSIONS_REQUEST_CAMERA: { 
      for (int i = 0, len = permissions.length; i < len; i++) { 
       String permission = permissions[i]; 
       if (grantResults[i] == PackageManager.PERMISSION_DENIED) { 
        boolean showRationale = 
         ActivityCompat.shouldShowRequestPermissionRationale 
                 (this, permission); 
        if (showRationale) { 
         showAlert(); 
        } else if (!showRationale) { 
         // user denied flagging NEVER ASK AGAIN 
         // you can either enable some fall back, 
         // disable features of your app 
         // or open another dialog explaining 
         // again the permission and directing to 
         // the app setting 
         saveToPreferences(MainActivity.this, ALLOW_KEY, true); 
        } 
       } 
      } 
     } 

     // other 'case' lines to check for other 
     // permissions this app might request 

    } 
} 

public static void startInstalledAppDetailsActivity(final Activity context) { 
    if (context == null) { 
     return; 
    } 
    final Intent i = new Intent(); 
    i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 
    i.addCategory(Intent.CATEGORY_DEFAULT); 
    i.setData(Uri.parse("package:" + context.getPackageName())); 
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 
    i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 
    context.startActivity(i); 
} 

private void openCamera() { 
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); 
    startActivity(intent); 
} 

} 
+0

Nó hoạt động trên Android 6 mặc dù và tôi xin phép ... Điều đó thật kỳ lạ. Tôi sẽ điều tra sau. – domenukk

0

Giống như @apk đã nói trước đây, màn hình màu đen xuất hiện bởi vì bạn không xử lý quyền trong mã của bạn. Nếu bạn đang làm việc với targetSdkVersion 23 (và cao hơn), bạn sẽ phải yêu cầu quyền từ người dùng trong thời gian chạy.

bình luận trước giải thích bạn làm thế nào để giải quyết nó thông qua các hoạt động của SDK trực tiếp, nhưng tôi thích sử dụng một thư viện của bên thứ ba tuyệt vời cho những trường hợp này: Karumi/Dexter

Các vấn đề liên quan