android - 如何在 Android 上编写一个相机应用程序,供其他应用程序(如 instagram、snapchat)使用以单击图片

标签 android camera android-camera

因此,由于某些原因,我的库存相机应用程序无法使用,instagram 和 snapchat 等应用程序中的相机也无法使用。所以我写了我自己的相机应用程序并让它工作。问题是我的前置摄像头不工作,这些其他应用程序的编写方式是这些应用程序检查前置摄像头应用程序的状态,导致它崩溃。我想要做的是,每当我单击诸如 instagram 之类的应用程序的相机按钮时,打开我的相机应用程序,并将其作为“使用完成操作”中的选项提供。我添加了这个:

<intent-filter android:label="@string/take_picture">
         <action android:name="android.intent.action.GET_CONTENT" />
         <data android:mimeType="image/*" />
</intent-filter>

但即使这样也无法使我的应用程序在“使用完整操作”下可见。可能有什么问题?

这是我的代码: 主 Activity .java

public class MainActivity extends Activity{
private Camera mCamera;
private Preview mPreview;
String TAG="Camera";

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

    // Create an instance of Camera
    mCamera = getCameraInstance();

    // Create our Preview view and set it as the content of our activity.
    mPreview = new Preview(this, mCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mPreview);


 // Add a listener to the Capture button
    Button captureButton = (Button) findViewById(R.id.button_capture);
    captureButton.setOnClickListener(
        new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // get an image from the camera
                mCamera.takePicture(null, null, mPicture);
            }
        }
    );



}



private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile();
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions: " 
               );
            return;
        }

        try {



            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};


/** Create a File for saving the image */
private static File getOutputMediaFile(){

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
              Environment.DIRECTORY_PICTURES), "MyCameraApp");

    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d("MyCameraApp", "failed to create directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "IMG_"+ timeStamp + ".jpg");

    return mediaFile;
}



/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
        Camera.Parameters parameters = c.getParameters();

        parameters.setRotation(90); //set rotation to save the picture

        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);

        parameters.setJpegQuality(100);

        parameters.setPictureFormat(ImageFormat.JPEG);

        List<Size> sizes = parameters.getSupportedPictureSizes();
        Camera.Size size = sizes.get(0);
        for(int i=0;i<sizes.size();i++)
        {
            if(sizes.get(i).width > size.width)
                size = sizes.get(i);
        }
        parameters.setPictureSize(size.width, size.height);



        c.setDisplayOrientation(90); //set the rotation for preview camera

        c.setParameters(parameters);
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}




}

预览.java

public class Preview extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
String TAG="Camera";
List<Size> mSupportedPreviewSizes;
Camera.Size mPreviewSize;

public Preview(Context context, Camera camera) {
    super(context);
    mCamera = camera;

    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    mHolder = getHolder();
    mHolder.addCallback(this);
    // deprecated setting, but required on Android versions prior to 3.0
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    mSupportedPreviewSizes=mCamera.getParameters().getSupportedPreviewSizes();
}

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, now tell the camera where to draw the preview.
    try {
        mCamera.setPreviewDisplay(holder);

        mCamera.startPreview();
    } catch (IOException e) {
        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // empty. Take care of releasing the Camera preview in your activity.
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // If your preview can change or rotate, take care of those events here.
    // Make sure to stop the preview before resizing or reformatting it.

    if (mHolder.getSurface() == null){
      // preview surface does not exist
      return;
    }

    // stop preview before making changes
    try {
        mCamera.stopPreview();
    } catch (Exception e){
      // ignore: tried to stop a non-existent preview
    }

    // set preview size and make any resize, rotate or
    // reformatting changes here

    // start preview with new settings
    try {
        mCamera.setPreviewDisplay(mHolder);
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        mCamera.setParameters(parameters);
        mCamera.startPreview();


    } catch (Exception e){
        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
    setMeasuredDimension(width, height);

    if (mSupportedPreviewSizes != null) {
       mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
    }
}

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio=(double)h / w;

    if (sizes == null) return null;

    Camera.Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    for (Camera.Size size : sizes) {
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
        if (Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }

    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    return optimalSize;
}

}

最佳答案

参见 https://android.googlesource.com/platform/packages/apps/Camera2/+/master/AndroidManifest.xml .对于静止图像捕获,相关的过滤器是:

<intent-filter>
  <action android:name="android.media.action.IMAGE_CAPTURE" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
  <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

关于android - 如何在 Android 上编写一个相机应用程序,供其他应用程序(如 instagram、snapchat)使用以单击图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23407584/

相关文章:

android - 从 Activity 中调用相机,捕获图像并上传到服务器

android - 从相机捕获图像并在我们保存之前覆盖另一个位图

android - 无法设置视频大小;因 IllegalStateException 而失败。如何让它发挥作用?

android - 具有确定图像位置的无限画廊滚动

android - 摘要 : Take a picture utilizing Camera Intent and display the photo with correct orientation (works on hopefully all devices)

Android 内部外部存储

java - 切换到全屏相机 OnClick

java - 防止翻转前置摄像头

android - 是否可以在终端中使用 adb 将我正在调试的应用程序设置为 "force stop"?

android - android assets文件夹是文件系统中的真实文件夹吗