Android Camera 整理

xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.windowdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="15" />

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="com.example.windowdemo.MyService" >
        </service>
    </application>

</manifest>

====================================================================================

activity

package com.example.windowdemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         
        Button btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // 启动服务,在服务里开启悬浮窗
                Intent intent = new Intent(MainActivity.this,MyService.class);
                 startService(intent);
                 finish();
            }
        });
    }

}


============================================================================

service

package com.example.windowdemo;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.Service;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;

public class MyService extends Service {
    public static String TAG = "MyService";

    /**
     * 自定义窗口
     */
    private MyWindow myWindow;
    /**
     * 窗口管理者
     */
    private WindowManager mWindowManager;
    /**
     * 窗口布局参数
     */
    private LayoutParams Params;
 
    private Handler handler = new Handler() {
    @SuppressLint("NewApi")
    public void handleMessage(Message msg) {

            if (isHome()) {
                // 如果回到桌面,则显示悬浮窗
                if (!myWindow.isAttachedToWindow()) {
                    mWindowManager.addView(myWindow, Params);
                }

            } else {
                // 如果在非桌面,则去掉悬浮窗
                if (myWindow.isAttachedToWindow()) {
                    myWindow.colseCamera();
                    mWindowManager.removeView(myWindow);
                }
            }
            super.handleMessage(msg);
        };
    };

    @Override
    public IBinder onBind(Intent arg0) {

        return null;
    }

    @SuppressLint("NewApi")
    @Override
    public void onCreate() {
        super.onCreate();
        // 定时器类
        Timer timer = new Timer();
        timer.schedule(task, 1000, 1000); // 1s后执行task,经过1s再次执行
        
        Log.i(TAG, "onCreate");
        showWindow();
        //对于6.0以上的设备
//        if (Build.VERSION.SDK_INT >= 23) {
//            //如果支持悬浮窗功能
//            if (Settings.canDrawOverlays(getApplicationContext())) {
//                 showWindow();
//            } else {
//                //手动去开启悬浮窗
//                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
//                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//                getApplicationContext().startActivity(intent);
//            }
//        } else {
//                //6.0以下的设备直接开启
//                showWindow();
//        }

    }

    private void showWindow() {
        Log.i(TAG, "showWindow1");
        //创建MyWindow的实例
        myWindow = new MyWindow(getApplicationContext());
        //窗口管理者
        mWindowManager = (WindowManager) getSystemService(Service.WINDOW_SERVICE);
        //窗口布局参数
        Params = new WindowManager.LayoutParams();
        //布局坐标,以屏幕左上角为(0,0)
        Params.x = 0;
        Params.y = 0;

        //布局类型
        Params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; // 系统提示类型,重要
        
        //布局flags
        Params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 不能抢占聚焦点
        Params.flags = Params.flags | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
        Params.flags = Params.flags | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; // 排版不受限制
        Params.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;

        //布局的gravity
        Params.gravity = Gravity.LEFT | Gravity.TOP;
 
        //布局的宽和高
        Params.width =  400;
        Params.height = 400;

        myWindow.setOnTouchListener(new OnTouchListener() {
 
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                 switch (event.getAction()) {                
                 
                 case MotionEvent.ACTION_MOVE:
                    Params.x = (int) event.getRawX() - myWindow.getWidth() / 2;
                    Params.y = (int) event.getRawY() - myWindow.getHeight() / 2;
                    //更新布局位置
                    mWindowManager.updateViewLayout(myWindow, Params);
                    
                    break;
                }
                 return false;
            }
         });

    }

    //定时发送message给Handler
    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            Message message = new Message();
            handler.sendMessage(message);
        }
    };

    
    /**
     * @return 获取桌面(Launcher)的包名
     */
    private List<String> getHomes() {
        List<String> names = new ArrayList<String>();
        PackageManager packageManager = this.getPackageManager();
        
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo info : resolveInfo) {
            names.add(info.activityInfo.packageName);
        }
        return names;
    }

    /**
     * @return 判断当前是否是桌面
     */
    public boolean isHome() {
        ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);
        List<String> strs = getHomes();
        if (strs != null && strs.size() > 0) {
            return strs.contains(rti.get(0).topActivity.getPackageName());
        } else {
            return false;
        }
    }

}

 

=================================================================

view

package com.example.windowdemo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Service;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;

public class MyWindow extends LinearLayout implements SurfaceTextureListener {
    public static String TAG = "MyWindow";
    private TextureView textureView;
    private SurfaceTexture mSurfaceTexture = null ;
    public static final int MEDIA_TYPE_IMAGE = 1;
    public static final int MEDIA_TYPE_VIDEO = 2;
    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
    private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;

 

    /**
     * 相机类
     */
    private Camera myCamera;
    private Context context;

    private WindowManager mWindowManager;

    public MyWindow(Context context) {
        super(context);
        LayoutInflater.from(context).inflate(R.layout.window, this);
        this.context = context;

        initView();
    }
    Button bt_open,bt2_pic,bt_colse;
    private void initView() {

        textureView = (TextureView) findViewById(R.id.textureView);
        bt_open = (Button) findViewById(R.id.bt_open);
        bt2_pic = (Button) findViewById(R.id.bt2_pic);
        bt_colse = (Button) findViewById(R.id.bt_colse);
        textureView.setSurfaceTextureListener(this);
        mWindowManager = (WindowManager) context.getSystemService(Service.WINDOW_SERVICE);
        bt_open.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                openCamera();
            }
        });
        bt2_pic.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                myCamera.takePicture(null, null, mPicture);
            }
        });
        bt_colse.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                colseCamera();
            }
        });
    }
    String cameraId;
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {

        //        if (myCamera == null) {
        //            // 创建Camera实例
        //            myCamera = Camera.open(0);
        //            Log.i(TAG, "myCamera:"+myCamera);
        //            try {
        //                // 设置预览在textureView上
        //                myCamera.setPreviewTexture(surface);
        //                myCamera.setDisplayOrientation(SetDegree(MyWindow.this));
        //
        //                // 开始预览
        //                myCamera.startPreview();
        //            } catch (IOException e) {
        //                e.printStackTrace();
        //            }
        //        }

        Log.d(TAG,"onSurfaceTextureAvailable-width:"+width+"-height:"+height);
        //        int cameraFacing  =CAMERA_FACING_FRONT;s
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
            Camera.getCameraInfo(i, cameraInfo);
            //               if (cameraInfo.facing == cameraFacing) {
            //                   cameraId = i;
            //               }
            Log.d(TAG,"startCamera -cameraInfo.facing:"+cameraInfo.facing);
        }

        //      // TtsUtils.systemOutPtintln("startCamera -isCameraCanUse-cameraId:"+cameraId);
        Log.d(TAG,"startCamera -isCameraCanUse-cameraId:"+cameraId);
        //       mCamera = Camera.open(cameraId);
        mSurfaceTexture = surface ;
        myCamera = Camera.open();
        Log.d(TAG,"startCamera -isCameraCanUse-myCamera:"+myCamera);
        Log.d(TAG,"startCamera -isCameraCanUse-surface:"+surface);
        if (myCamera != null) {
            try {
                myCamera.setPreviewTexture(surface);
                myCamera.startPreview();
            } catch (Exception e) {
                Log.d(TAG, e.getMessage());
            }
        }
    }

    private int SetDegree(MyWindow myWindow) {
        // 获得手机的方向
        int rotation = mWindowManager.getDefaultDisplay().getRotation();
        int degree = 0;
        // 根据手机的方向计算相机预览画面应该选择的角度
        switch (rotation) {
        case Surface.ROTATION_0:
            degree = 90;
            break;
        case Surface.ROTATION_90:
            degree = 0;
            break;
        case Surface.ROTATION_180:
            degree = 270;
            break;
        case Surface.ROTATION_270:
            degree = 180;
            break;
        }
        return degree;
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        myCamera.stopPreview(); //停止预览
        myCamera.release();     // 释放相机资源
        myCamera = null;

        return false;
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        //         int displayOrientation = getDisplayOrientation();
        //         myCamera.setDisplayOrientation(displayOrientation);
        //         List<Camera.Size> supportedPreviewSizes = myCamera.getParameters().getSupportedPreviewSizes();
        //         Camera.Size optimalPreviewSize = getOptimalPreviewSize(supportedPreviewSizes, width, height);
        //         myCamera.getParameters().setPictureSize(optimalPreviewSize.width, optimalPreviewSize.height);
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }
    public void colseCamera(){
        if(myCamera != null ){
            myCamera.stopPreview(); //停止预览
            myCamera.release();     // 释放相机资源
            myCamera = null;
        }

    }
    public void openCamera(){

        myCamera = Camera.open();
        Log.d(TAG,"startCamera -isCameraCanUse-myCamera:"+myCamera);
        Log.d(TAG,"startCamera -isCameraCanUse-surface:"+mSurfaceTexture);
        if (myCamera != null) {
            try {
                myCamera.setPreviewTexture(mSurfaceTexture);
                myCamera.startPreview();
            } catch (Exception e) {
                Log.d(TAG, e.getMessage());
            }
        }


    }

    private PictureCallback mPicture = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
            if (pictureFile == null) {
                Log.d(TAG,
                        "Error creating media file, check storage permissions: "
                                + "e.getMessage()");
                return;
            }
            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
                Log.d(TAG, "File ok getPath: " + pictureFile.getPath());
            } catch (FileNotFoundException e) {
                Log.d(TAG, "File not found: " + e.getMessage());
            } catch (IOException e) {
                Log.d(TAG, "Error accessing file: " + e.getMessage());
            }
        }
    };
    /** 为保存图片或视频创建File */
    private static File getOutputMediaFile(int type) {
        // 安全起见,在使用前应该
        // 用Environment.getExternalStorageState()检查SD卡是否已装入
        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;
            }
            Log.d("MyCameraApp", "failed to create directory");
        }
        // 创建媒体文件名
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
                .format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator
                    + "IMG_" + timeStamp + ".jpg");
        } else if (type == MEDIA_TYPE_VIDEO) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator
                    + "VID_" + timeStamp + ".mp4");
        } else {
            return null;
        }
        return mediaFile;
    }

 

}


=====================================================================

main xml

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="开启悬浮窗" />

</RelativeLayout>


view xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <TextureView
            android:id="@+id/textureView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/bt_open"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="#00ffff"
            android:text="照相机"
            android:layout_weight="1"
            android:textSize="30sp" />

        <Button
            android:id="@+id/bt2_pic"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="#00ffff"
            android:layout_weight="1"
            android:text="拍照"
            android:textSize="30sp" />
        <Button
            android:id="@+id/bt_colse"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="#00ffff"
            android:layout_weight="1"
            android:text="关闭"
            android:textSize="30sp" />
    </LinearLayout>

</LinearLayout>

 

======================================

探讨在打开摄像头预览时这两个方法的作用
关于:setPreviewCallbackWithBuffer()

    Installs a callback to be invoked for every preview frame, using buffers supplied with addCallbackBuffer(byte[]), in addition to displaying them on the screen.
    在摄像头开启时增加一个回调函数,在每一帧出现时调用.通过addCallbackBuffer(byte[])使用一个缓存容器来显示这些数据.

其实就是通过内存复用来提高预览的效率,但是如果没有调用这个方法addCallbackBuffer(byte[]),帧回调函数就不会被调用,也就是说在每一次回调函数调用后都必须调用addCallbackBuffer(byte[]).(所以可以直接在onPreviewFrame中调用addCallbackBuffer(byte[]),即camera.addCallbackBuffer(data);),复用这个原来的内存地址即可.
使用步骤:
1 在打开摄像头预览前先分配一个buffer地址

camera.setPreviewCallbackWithBuffer(h264Encoder);
camera.addCallbackBuffer(mPreviewSize.width* mPreviewSize.height*3 / 2);
camera.startPreview();

    1
    2
    3

2 然后只用在onPreviewFrame中调用addCallbackBuffer(data)即可了,就可以一直复用原来开辟的那个内存空间了,视频数据data永远都只会保持在一个地址中,只是其中的内容在不断的变化

 

 

 

=======================

package com.example.windowdemo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Service;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.PreviewCallback;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;

public class MyWindow extends LinearLayout implements SurfaceTextureListener{//PreviewCallback
    public static String TAG = "MyWindow";
    private TextureView textureView;
    private SurfaceTexture mSurfaceTexture = null ;
    public static final int MEDIA_TYPE_IMAGE = 1;
    public static final int MEDIA_TYPE_VIDEO = 2;
    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
    private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;

 

    /**
     * 相机类
     */
    private Camera myCamera;
    private Context context;

    private WindowManager mWindowManager;

    public MyWindow(Context context) {
        super(context);
        LayoutInflater.from(context).inflate(R.layout.window, this);
        this.context = context;

        initView();
    }
    Button bt_open,bt2_pic,bt_colse;
    private void initView() {

        textureView = (TextureView) findViewById(R.id.textureView);
        bt_open = (Button) findViewById(R.id.bt_open);
        bt2_pic = (Button) findViewById(R.id.bt2_pic);
        bt_colse = (Button) findViewById(R.id.bt_colse);
        textureView.setSurfaceTextureListener(this);
        mWindowManager = (WindowManager) context.getSystemService(Service.WINDOW_SERVICE);
        bt_open.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                openCamera();
            }
        });
        bt2_pic.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                myCamera.takePicture(null, null, mPicture);
            }
        });
        bt_colse.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                colseCamera();
            }
        });
    }
    String cameraId;
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {

        //        if (myCamera == null) {
        //            // 创建Camera实例
        //            myCamera = Camera.open(0);
        //            Log.i(TAG, "myCamera:"+myCamera);
        //            try {
        //                // 设置预览在textureView上
        //                myCamera.setPreviewTexture(surface);
        //                myCamera.setDisplayOrientation(SetDegree(MyWindow.this));
        //
        //                // 开始预览
        //                myCamera.startPreview();
        //            } catch (IOException e) {
        //                e.printStackTrace();
        //            }
        //        }

        Log.d(TAG,"onSurfaceTextureAvailable-width:"+width+"-height:"+height);
        //        int cameraFacing  =CAMERA_FACING_FRONT;s
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
            Camera.getCameraInfo(i, cameraInfo);
            //               if (cameraInfo.facing == cameraFacing) {
            //                   cameraId = i;
            //               }
            Log.d(TAG,"startCamera -cameraInfo.facing:"+cameraInfo.facing);
        }

        //      // TtsUtils.systemOutPtintln("startCamera -isCameraCanUse-cameraId:"+cameraId);
        Log.d(TAG,"startCamera -isCameraCanUse-cameraId:"+cameraId);
        //       mCamera = Camera.open(cameraId);
        mSurfaceTexture = surface ;
        myCamera = Camera.open();
        Log.d(TAG,"startCamera -isCameraCanUse-myCamera:"+myCamera);
        Log.d(TAG,"startCamera -isCameraCanUse-surface:"+surface);
        if (myCamera != null) {
            try {
                

                
                //Callback buffer was too small! Expected 460800 bytes, but got 217200 bytes!
                myCamera.addCallbackBuffer(new byte[((800 * 480) * 3) / 2] );
//                myCamera.addCallbackBuffer(new byte[((800 * 480) * ImageFormat.getBitsPerPixel(ImageFormat.NV21)) / 8]);
                myCamera.setPreviewCallbackWithBuffer(myPreviewCallback);
                
                myCamera.setPreviewTexture(surface);
                myCamera.startPreview();
            } catch (Exception e) {
                Log.d(TAG, e.getMessage());
            }
        }
    }

    private int SetDegree(MyWindow myWindow) {
        // 获得手机的方向
        int rotation = mWindowManager.getDefaultDisplay().getRotation();
        int degree = 0;
        // 根据手机的方向计算相机预览画面应该选择的角度
        switch (rotation) {
        case Surface.ROTATION_0:
            degree = 90;
            break;
        case Surface.ROTATION_90:
            degree = 0;
            break;
        case Surface.ROTATION_180:
            degree = 270;
            break;
        case Surface.ROTATION_270:
            degree = 180;
            break;
        }
        return degree;
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        myCamera.stopPreview(); //停止预览
        myCamera.release();     // 释放相机资源
        myCamera = null;

        return false;
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        //         int displayOrientation = getDisplayOrientation();
        //         myCamera.setDisplayOrientation(displayOrientation);
        //         List<Camera.Size> supportedPreviewSizes = myCamera.getParameters().getSupportedPreviewSizes();
        //         Camera.Size optimalPreviewSize = getOptimalPreviewSize(supportedPreviewSizes, width, height);
        //         myCamera.getParameters().setPictureSize(optimalPreviewSize.width, optimalPreviewSize.height);
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }
    public void colseCamera(){
        if(myCamera != null ){
            myCamera.stopPreview(); //停止预览
            myCamera.release();     // 释放相机资源
            myCamera = null;
        }

    }
    public void openCamera(){

        myCamera = Camera.open();
        Log.d(TAG,"startCamera -isCameraCanUse-myCamera:"+myCamera);
        Log.d(TAG,"startCamera -isCameraCanUse-surface:"+mSurfaceTexture);
        if (myCamera != null) {
            try {
                
                myCamera.setPreviewTexture(mSurfaceTexture);
                myCamera.startPreview();
                
                myCamera.setPreviewCallbackWithBuffer(myPreviewCallback);
            } catch (Exception e) {
                Log.d(TAG, e.getMessage());
            }
        }


    }

    private PictureCallback mPicture = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
            if (pictureFile == null) {
                Log.d(TAG,
                        "Error creating media file, check storage permissions: "
                                + "e.getMessage()");
                return;
            }
            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
                Log.d(TAG, "File ok getPath: " + pictureFile.getPath());
            } catch (FileNotFoundException e) {
                Log.d(TAG, "File not found: " + e.getMessage());
            } catch (IOException e) {
                Log.d(TAG, "Error accessing file: " + e.getMessage());
            }
        }
    };
    /** 为保存图片或视频创建File */
    private static File getOutputMediaFile(int type) {
        // 安全起见,在使用前应该
        // 用Environment.getExternalStorageState()检查SD卡是否已装入
        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;
            }
            Log.d("MyCameraApp", "failed to create directory");
        }
        // 创建媒体文件名
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
                .format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator
                    + "IMG_" + timeStamp + ".jpg");
        } else if (type == MEDIA_TYPE_VIDEO) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator
                    + "VID_" + timeStamp + ".mp4");
        } else {
            return null;
        }
        return mediaFile;
    }

    
    private PreviewCallback myPreviewCallback = new PreviewCallback() {

        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            // TODO Auto-generated method stub
            Log.e(TAG, "onPreviewFrame2");
            if (data == null ) {
                camera.addCallbackBuffer(data);
                return;
            }else{
                camera.addCallbackBuffer(data);
            }    
        }
    };


}


====缓冲(w*h)*3/2

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值