I'm using a straight forwards Camera API, for backwards compatibility. The camera view itself is overlayed slightly by an imageview and my surfaceChanged does this:
camera.setPreviewCallback((data, arg1) -> LiveView.this.invalidate());
camera.setPreviewDisplay(mHolder);
camera.startPreview();
which works fine on all older devices. I set the preview size to the largest available size earlier in surfaceCreated
.
However on Android 7.1, it's suddenly black (on a Nexus 6 and Moto X Play, probably others - so on different devices).
The SurfaceView
itself is greyed out in the Layout Inspector
(willNotDraw = true
), but VISIBLE
(and hardware accelerated).
Strangely, I'm still able to take photos, event without preview, and the data in the preview callback contains an image.
At the same time I get the following log
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
Has anybody else experienced a completely black image in Android 7? Are there any easy fixes? (Like drawing the content of data directly?)
Black screen is appearing since you dont have camera permission on android 7 device
Goto settings->apps->select your app->permissions->Enable camera permission and check
You can also handle this inside your code
Add following permission to your manifest
<uses-permission android:name="android.permission.CAMERA" />
For asking for permission you can call like this.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
To check permission to access camera
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
}
Now the Callback if the User has performed any action.
@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
}
}
Here is complete example
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With