【问题标题】:surface view does not show camera after i gave permission在我允许后,表面视图不显示相机
【发布时间】:2018-05-14 08:47:16
【问题描述】:
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_camera, container, false);
    cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
    flipCamera = view.findViewById(R.id.flipCamera);
    flashCameraButton = view.findViewById(R.id.flash);
    captureImage = view.findViewById(R.id.captureImage);
    surfaceView = view.findViewById(R.id.surfaceView);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    flipCamera.setOnClickListener(this);
    captureImage.setOnClickListener(this);
    flashCameraButton.setOnClickListener(this);
    getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    if (Camera.getNumberOfCameras() > 1) {
        flipCamera.setVisibility(View.VISIBLE);
    }
    if (!getActivity().getBaseContext().getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA_FLASH)) {
        flashCameraButton.setVisibility(View.GONE);
    }


    return view;
}

@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void surfaceCreated(SurfaceHolder holder) {

    if (!openCamera(Camera.CameraInfo.CAMERA_FACING_BACK)) {
        alertCameraDialog();
    }

}


private boolean openCamera(int id) {
    boolean result = false;
    cameraId = id;
    releaseCamera();
    try {
        camera = Camera.open(cameraId);
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (camera != null) {
        try {
            setUpCamera(camera);
            camera.setErrorCallback(new Camera.ErrorCallback() {

                @Override
                public void onError(int error, Camera camera) {

                }
            });
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
            result = true;
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
            releaseCamera();
        }
    }
    return result;
}

private void setUpCamera(Camera c) {
    Camera.CameraInfo info = new Camera.CameraInfo();
    Camera.getCameraInfo(cameraId, info);
    rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
    int degree = 0;
    switch (rotation) {
        case Surface.ROTATION_0:
            degree = 0;
            break;
        case Surface.ROTATION_90:
            degree = 90;
            break;
        case Surface.ROTATION_180:
            degree = 180;
            break;
        case Surface.ROTATION_270:
            degree = 270;
            break;

        default:
            break;
    }

    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        // frontFacing
        rotation = (info.orientation + degree) % 330;
        rotation = (360 - rotation) % 360;
    } else {
        // Back-facing
        rotation = (info.orientation - degree + 360) % 360;
    }
    c.setDisplayOrientation(rotation);
    Camera.Parameters params = c.getParameters();

    showFlashButton(params);

    List<String> focusModes = params.getSupportedFlashModes();
    if (focusModes != null) {
        if (focusModes
                .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            params.setFlashMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        }
    }

    params.setRotation(rotation);
}

private void showFlashButton(Camera.Parameters params) {
    boolean showFlash = (getActivity().getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA_FLASH) && params.getFlashMode() != null)
            && params.getSupportedFlashModes() != null
            && params.getSupportedFocusModes().size() > 1;

    flashCameraButton.setVisibility(showFlash ? View.VISIBLE
            : View.INVISIBLE);

}

private void releaseCamera() {
    try {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.setErrorCallback(null);
            camera.stopPreview();
            camera.release();
            camera = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("error", e.toString());
        camera = null;
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
                           int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.flash:
            flashOnButton();
            break;
        case R.id.flipCamera:
            flipCamera();
            break;
        case R.id.captureImage:
            takeImage();
            break;

        default:
            break;
    }
}

private void takeImage() {
    camera.takePicture(null, null, new Camera.PictureCallback() {

        private File imageFile;

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            try {
                // convert byte array into bitmap
                Bitmap loadedImage = null;
                Bitmap rotatedBitmap = null;
                loadedImage = BitmapFactory.decodeByteArray(data, 0, data.length);

                // rotate Image
                Matrix rotateMatrix = new Matrix();
                rotateMatrix.postRotate(rotation);
                rotatedBitmap = Bitmap.createBitmap(loadedImage, 0, 0,
                        loadedImage.getWidth(), loadedImage.getHeight(),
                        rotateMatrix, false);
                String state = Environment.getExternalStorageState();
                File folder = null;
                if (state.contains(Environment.MEDIA_MOUNTED)) {
                    folder = new File(Environment
                            .getExternalStorageDirectory() + "/Demo");
                } else {
                    folder = new File(Environment
                            .getExternalStorageDirectory() + "/Demo");
                }

                boolean success = true;
                if (!folder.exists()) {
                    success = folder.mkdirs();
                }
                if (success) {
                    java.util.Date date = new java.util.Date();
                    imageFile = new File(folder.getAbsolutePath()
                            + File.separator
                            + new Timestamp(date.getTime()).toString()
                            + "Image.jpg");

                    imageFile.createNewFile();
                    Toast.makeText(getActivity().getBaseContext(), "Image Saved", Toast.LENGTH_SHORT).show();
                    openCamera(cameraId);
                } else {
                    Toast.makeText(getActivity().getBaseContext(), "Image Not saved", Toast.LENGTH_SHORT).show();
                    return;
                }

                ByteArrayOutputStream ostream = new ByteArrayOutputStream();

                // save image into gallery
                rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);

                FileOutputStream fout = new FileOutputStream(imageFile);
                fout.write(ostream.toByteArray());
                fout.close();
                ContentValues values = new ContentValues();

                values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
                values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
                values.put(MediaStore.MediaColumns.DATA, imageFile.getAbsolutePath());
                getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    });

}


private void flipCamera() {
    int id = (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK ? Camera.CameraInfo.CAMERA_FACING_FRONT
            : Camera.CameraInfo.CAMERA_FACING_BACK);
    if (!openCamera(id)) {
        alertCameraDialog();
    }
}

private void alertCameraDialog() {
    Toast.makeText(getActivity(), "Error to open camera", Toast.LENGTH_SHORT).show();
}


private void flashOnButton() {
    if (camera != null) {
        try {
            Camera.Parameters param = camera.getParameters();
            param.setFlashMode(!flashmode ? Camera.Parameters.FLASH_MODE_TORCH
                    : Camera.Parameters.FLASH_MODE_OFF);
            camera.setParameters(param);
            flashmode = !flashmode;
        } catch (Exception e) {
            // TODO: handle exception
        }

    }
}

}

这是我的相机片段代码。当我在运行时给予许可时,surfaceview 不显示相机。它在 onResume() 或该片段中的任何按钮单击时显示相机。如何解决此问题。如何设置当我在权限中单击允许按钮时,它会自动在表面视图中显示相机。

【问题讨论】:

    标签: android camera surfaceview runtime-permissions


    【解决方案1】:

    它对我有用:

    在获得许可或显示任何对话框之前,请将表面可见性设置为 GONE

    surfaceView.setVisibility(View.GONE);
    

    然后在获得许可或关闭对话框后将表面可见性设置为 VISIBLE

    surfaceView.setVisibility(View.VISIBLE);
    

    【讨论】:

      【解决方案2】:
      @Override
          public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
              switch (requestCode) {
                  case REQUEST_CODE:
                      for (int result : grantResults) {
                          if (result == PackageManager.PERMISSION_GRANTED) {
                              surfaceView.setVisibility(View.VISIBLE);    //   <----there u go
                              return;
                          } else {
                              if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                                      Manifest.permission.CAMERA)) {
      
                              } else {
                                  ActivityCompat.requestPermissions(MainActivity.this,
                                          new String[]{Manifest.permission.CAMERA},
                                          CODE_REQUESTED_1);
                              }
                          }
                      }
      
              }
          }
      

      【讨论】:

      • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
      【解决方案3】:

      很抱歉回答迟了,但也许它对某人有用。只需像这样在 onRequestPermissionsResult 中调用 start camera 方法:

      @Override
      public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
          super.onRequestPermissionsResult(requestCode, permissions, grantResults);
          Utils.log(TAG, "onRequestPermissionsResult call");
          if (requestCode == REQUEST_CAMERA_PERMISSION) {
              if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                  Utils.log(TAG, "Permission granted - show camera");
                  if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                      try {
                          cameraSource.start(surfaceView.getHolder());
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      }
      

      显示相机的默认方式可能如下所示:

      surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
      
          @Override
          public void surfaceCreated(SurfaceHolder holder) {
              try {
                  if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                      cameraSource.start(surfaceView.getHolder());
                      Utils.log(TAG, "Check permission: granted - start camera");
                  } else {
                      Utils.log(TAG, "Check permission: restricted - request");
                      requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
      
          }
      
          @Override
          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
          }
      
          @Override
          public void surfaceDestroyed(SurfaceHolder holder) {
              cameraSource.stop();
          }
      });
      

      【讨论】:

        【解决方案4】:

        在onCreate中设置surfaceView的可见性为INVISIBLE。

         @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_home);
        
            if (checkCameraHardware(this) == false) {
                showDialogForExit();
            }
            surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
            surfaceView.setVisibility(View.INVISIBLE);
            infoTextview = (TextView) findViewById(R.id.info_text);
            askForPermissions();
        }
        

        然后将cameraSource附加到surfaceView后,再次将surfaceView的可见性设置为VISIBLE。

                surfaceView.setVisibility(View.VISIBLE);
        

        【讨论】:

          【解决方案5】:

          使用这个类

          公共类 RunTimePermission 扩展 Activity {

          private Activity activity;
          private ArrayList<PermissionBean> arrayListPermission;
          private String[] arrayPermissions;
          private RunTimePermissionListener runTimePermissionListener;
          
          public RunTimePermission(Activity activity)
          {
              this.activity = activity;
          }
          
          public class PermissionBean
          {
          
              String permission;
              boolean isAccept;
          }
          
          public void requestPermission(String[] permissions, RunTimePermissionListener runTimePermissionListener)
          {
              this.runTimePermissionListener = runTimePermissionListener;
              arrayListPermission = new ArrayList<PermissionBean>();
          
          
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
              {
                  for (int i = 0; i < permissions.length; i++)
                  {
                      PermissionBean permissionBean = new PermissionBean();
                      if (ContextCompat.checkSelfPermission(activity, permissions[i]) == PackageManager.PERMISSION_GRANTED)
                      {
                          permissionBean.isAccept = true;
                      }
                      else
                      {
                          permissionBean.isAccept = false;
                          permissionBean.permission = permissions[i];
                          arrayListPermission.add(permissionBean);
                      }
          
          
                  }
          
                  if (arrayListPermission.size() <= 0)
                  {
                      runTimePermissionListener.permissionGranted();
                      return;
                  }
                  arrayPermissions = new String[arrayListPermission.size()];
                  for (int i = 0; i < arrayListPermission.size(); i++)
                  {
                      arrayPermissions[i] = arrayListPermission.get(i).permission;
                  }
                  activity.requestPermissions(arrayPermissions, 10);
              }
              else
              {
                  if (runTimePermissionListener != null)
                  {
                      runTimePermissionListener.permissionGranted();
                  }
              }
          }
          
          public interface RunTimePermissionListener
          {
          
              void permissionGranted();
          
              void permissionDenied();
          }
          
          private void callSettingActivity()
          {
              Intent intent = new Intent();
              intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
              Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
              intent.setData(uri);
              activity.startActivity(intent);
          
          }
          
          private void checkUpdate()
          {
              boolean isGranted = true;
              int deniedCount = 0;
              for (int i = 0; i < arrayListPermission.size(); i++)
              {
                  if (!arrayListPermission.get(i).isAccept)
                  {
                      isGranted = false;
                      deniedCount++;
                  }
              }
          
              if (isGranted)
              {
                  if (runTimePermissionListener != null)
                  {
                      runTimePermissionListener.permissionGranted();
                  }
              }
              else
              {
                  if (runTimePermissionListener != null)
                  {
          
                      setAlertMessage();
                      runTimePermissionListener.permissionDenied();
                  }
              }
          }
          
          public void setAlertMessage()
          {
              AlertDialog.Builder adb;
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                  adb = new AlertDialog.Builder(activity, android.R.style.Theme_Material_Light_Dialog_Alert);
              } else {
                  adb = new AlertDialog.Builder(activity);
              }
          
              adb.setTitle(activity.getResources().getString(R.string.app_name));
              String msg = "<p>Dear User, </p>" +
                      "<p>Seems like you have <b>\"Denied\"</b> the minimum requirement permission to access more features of application.</p>" +
                      "<p>You must have to <b>\"Allow\"</b> all permission. We will not share your data with anyone else.</p>" +
                      "<p>Do you want to enable all requirement permission ?</p>" +
                      "<p>Go To : Settings >> App > " + activity.getResources().getString(R.string.app_name) + " Permission : Allow ALL</p>";
          
              adb.setMessage(Html.fromHtml(msg));
              adb.setPositiveButton("Allow All", new AlertDialog.OnClickListener()
              {
          
                  @Override
                  public void onClick(DialogInterface dialog, int which)
                  {
                      callSettingActivity();
                      dialog.dismiss();
                  }
              });
          
              adb.setNegativeButton("Remind Me Later", new AlertDialog.OnClickListener()
              {
          
                  @Override
                  public void onClick(DialogInterface dialog, int which)
                  {
                      dialog.dismiss();
                  }
              });
              if (!((Activity) activity).isFinishing() && msg.length() > 0)
              {
                  adb.show();
              }
              else
              {
                  Log.v("log_tag", "either activity finish or message length is 0");
              }
          }
          
          private void updatePermissionResult(String permissions, int grantResults)
          {
          
              for (int i = 0; i < arrayListPermission.size(); i++)
              {
                  if (arrayListPermission.get(i).permission.equals(permissions))
                  {
                      if (grantResults == 0)
                      {
                          arrayListPermission.get(i).isAccept = true;
                      }
                      else
                      {
                          arrayListPermission.get(i).isAccept = false;
                      }
                      break;
                  }
              }
          
          }
          
          
          public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
          {
              for (int i = 0; i < permissions.length; i++)
              {
                  updatePermissionResult(permissions[i], grantResults[i]);
              }
              checkUpdate();
          }
          }
          

          在你的活动中写下这段代码的 onCreate() 方法

          getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
          
              runTimePermission = new RunTimePermission(this);
              runTimePermission.requestPermission(new String[]{Manifest.permission.CAMERA,
                      Manifest.permission.RECORD_AUDIO,
                      Manifest.permission.READ_EXTERNAL_STORAGE,
                      Manifest.permission.WRITE_EXTERNAL_STORAGE
              }, new RunTimePermission.RunTimePermissionListener() {
          
                  @Override
                  public void permissionGranted() {
                      // First we need to check availability of play services
                      initControls();
          
                      identifyOrientationEvents();
          
                      //create a folder to get image
                      folder = new File(Environment.getExternalStorageDirectory() + "/Media");
                      if (!folder.exists()) {
                          folder.mkdirs();
                      }
                      //capture image on callback
                      captureImageCallback();
                      //
                      if (camera != null) {
                          Camera.CameraInfo info = new Camera.CameraInfo();
                          if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                              imgFlashOnOff.setVisibility(View.GONE);
                          }
                      }
                  }
          
                  @Override
                  public void permissionDenied() {
                  }
              });
          

          然后在onCreate()中写出这段代码

            @Override
              public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
              if (runTimePermission != null) {
                  runTimePermission.onRequestPermissionsResult(requestCode, permissions, grantResults);
              }
              super.onRequestPermissionsResult(requestCode, permissions, grantResults);
          }
          

          【讨论】:

            【解决方案6】:

            您必须在此处收到您的许可详细信息

            @Override
                public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                        @NonNull int[] grantResults) {
                    switch (requestCode) {
                        case REQUEST_CAMERA_PERMISSION:
                            if (grantResults.length > 0
                                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                                //Here call or Open your camera;
                            }
                            break;
                        default:
                            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                    }
                }
            

            更多信息:

            链接1:https://developer.android.com/training/permissions/requesting.html

            链接2:https://www.androidhive.info/2016/11/android-working-marshmallow-m-runtime-permissions/

            【讨论】:

            • 添加此默认语句后问题仍未解决
            • 你的onRequestPermissionsResult方法被调用了吗?获得许可后...
            • 我的问题是在我授予相机表面视图权限后不显示相机。出现黑屏。当我点击像翻转相机这样的任何按钮时,它只会显示相机。我想要一个解决方案,比如当我允许表面视图自动显示相机时。
            • @VelayuthamM 您找到解决问题的方法了吗?我有同样的问题。
            猜你喜欢
            • 1970-01-01
            • 2015-01-04
            • 2011-06-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多