android之利用surfaceView实现自定义水印相机
知识点
1、自定义相机+预览相机
2、截屏拍照加水印
3、关于不使用intent来传输图片
4、关于大家说要demo的,因为这里是项目里头的,不方便弄出来,大家可以直接复制代码过去,就差不多的了。
俗话说,有图有真相。很多人都是喜欢直接看图,不像我,比较喜欢文字多点,经常看看散文什么的陶冶一下情操。
好了,说到这里,就引出我们今天要做的这个功能,那就是水印相机。水印相机说白了,就是在拍照的图片上面加上自己想要的各种信息,包括文字,图片或者其它你想要的信息。
在这里,我自己定义了一个类WaterCameraActivity,是自定义的相机的,然后还有一个类ViewPhoto,是用来查看你拍照后的图片的,有使用图片和取消/重新拍照功能。
3、关于不使用intent来传输图片
因为intent最大的传输数据为1m,一张图片随便都有3,4m,再加之读取到内存中,就可能变成2倍3倍大了,很容易造成oom。所以我们还是利用本地储存来进行,只要传输一个路径就OK了,这样做的问题就是,老是要读取本地图片,性能不是很好呢。关于这个,如果各位有好的建议可以提出来一起探讨。
下面我们直接上代码,毕竟还是代码说事比较清楚,代码里面都注释好了,各位可以认真去看。
WaterCameraActivity的布局:布局很简单,就是一个SurfaceView+需要加入的水印信息,如下图
布局
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><!--这是用来预览相机的空间,大家可以去好好了解一下,这里我就不详细讲了--><SurfaceViewandroid:id="@+id/sfv_camera"android:layout_width="match_parent"android:layout_height="match_parent" /><!--想要的信息放在surfaceview之上就OK了,下面是我想要加入的信息--><RelativeLayoutandroid:id="@+id/rl_setting"android:layout_width="match_parent"android:layout_height="60dp"android:background="@null"android:gravity="center_vertical"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_marginLeft="5dp"android:orientation="vertical"><TextViewandroid:id="@+id/tv_time"android:layout_width="wrap_content"android:layout_height="wrap_content"android:shadowColor="#000"android:shadowDx="3"android:shadowDy="3"android:shadowRadius="2"android:text="08:27"android:textColor="#fff"android:textSize="25sp" /><TextViewandroid:id="@+id/tv_date"android:layout_width="wrap_content"android:layout_height="wrap_content"android:shadowColor="#000"android:shadowDx="3"android:shadowDy="3"android:shadowRadius="2"android:text="/07/24"android:textColor="#fff"android:textSize="15sp" /></LinearLayout><ImageButtonandroid:id="@+id/imgvBtn_switchFlash"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_marginRight="20dp"android:background="@null"android:paddingLeft="10dp"android:paddingRight="10dp" /><ImageButtonandroid:id="@+id/imgvBtn_switchCamera"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_marginRight="20dp"android:background="@null"android:paddingLeft="10dp"android:paddingRight="10dp"android:visibility="gone" /></RelativeLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="75dp"android:layout_marginRight="3dp"android:gravity="right"android:orientation="vertical"><TextViewandroid:id="@+id/tv_operation"style="@style/textView_water"android:drawableLeft="@drawable/operation"android:text="点击操作" /><TextViewandroid:id="@+id/tv_username"style="@style/textView_water"android:drawableLeft="@drawable/user_icon"android:text="钓鱼的小木匠" /><TextViewandroid:id="@+id/tv_address"style="@style/textView_water"android:drawableLeft="@drawable/address"android:text="广东省惠州市惠城区鹅岭南路6号TCL工业大厦" /></LinearLayout><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="75dp"android:layout_alignParentBottom="true"android:layout_gravity="center_vertical"><!--android:background="@drawable/take_photo_selector"定义一个根据点击状态改变的xml文件--><ImageButtonandroid:id="@+id/btn_takePic"android:layout_width="64dp"android:layout_height="64dp"android:layout_centerInParent="true"android:background="@drawable/take_photo_selector" /><Buttonandroid:id="@+id/imgvBtn_back"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_marginLeft="20dp"android:background="@null"android:text="取 消"android:textColor="#0f0"android:textSize="20sp" /></RelativeLayout></RelativeLayout></RelativeLayout>
WaterCameraActivity类
/*** 启动自定义水印相机** Created by tanksu on 16/6/28.*/public class WaterCameraActivity extends BaseActivity implements SurfaceHolder.Callback {private Context mContext;private SurfaceView mSurfaceView;private ImageButton imgvBtn_takePic, imgvBtn_switchFlash, imgvBtn_switchCamera;private Button btn_back;private TextView tv_time, tv_username, tv_address, tv_date, tv_operation;private SurfaceHolder mSurfaceHolder;private Camera mCamera;private String curDate = "", curTime = "", curAddress = "", userName = "", userOperation = "";private final int REQUEST_CODE = 1001;private Camera.CameraInfo cameraInfo = new Camera.CameraInfo();private int mCameraId;private long currentTimeMillis = 0;private Intent waterIntent;/*** 这是点击surfaceview聚焦所调用的方法*/private Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback(){@Overridepublic void onAutoFocus(boolean success, Camera camera) {//success = true,聚焦成功,否则聚焦失败//在这里我们可以在点击相机后是否聚焦成功,然后做我们的一些操作,这里我就省略了,大家自行根据需要添加}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.watercamera_layout);initViews();initData();initListener();}/*** 初始化控件*/private void initViews() {mSurfaceView = (SurfaceView) findViewById(R.id.sfv_camera);imgvBtn_takePic = (ImageButton) findViewById(R.id.btn_takePic);tv_time = (TextView) findViewById(R.id.tv_time);tv_username = (TextView) findViewById(R.id.tv_username);tv_address = (TextView) findViewById(R.id.tv_address);tv_date = (TextView) findViewById(R.id.tv_date);tv_operation = (TextView) findViewById(R.id.tv_operation);imgvBtn_switchFlash = (ImageButton) findViewById(R.id.imgvBtn_switchFlash);imgvBtn_switchFlash.setImageResource(R.drawable.camera_setting_flash_off_normal);imgvBtn_switchCamera = (ImageButton) findViewById(R.id.imgvBtn_switchCamera);imgvBtn_switchCamera.setImageResource(R.drawable.changing_camera_normal);btn_back = (Button) findViewById(R.id.imgvBtn_back);mContext = this;}/*** 初始化数据*/private void initData() {mSurfaceView.setFocusable(true);mSurfaceHolder = mSurfaceView.getHolder();mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);mSurfaceHolder.setKeepScreenOn(true);mSurfaceHolder.setFormat(PixelFormat.TRANSPARENT);mSurfaceHolder.addCallback(this);SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); //获取当前时间,作为图片的命名,再转换为常用时间格式currentTimeMillis = System.currentTimeMillis();curDate = formatter.format(currentTimeMillis);tv_date.setText(curDate);SimpleDateFormat format = new SimpleDateFormat("HH:mm", Locale.getDefault()); //获取24小时制的时间curTime = format.format(currentTimeMillis);tv_time.setText(curTime);Intent intent = getIntent(); //我写的这个类,是要用startActivityForResult来启动的,传入的参数可以根据自己需求来定,我这里传过来的信息有//地址CUR_ADDRESS,用户名USER_NAME,用户操作USER_OPERATION,然后把信息设置到空间里面去,同时还要保存intent。//而时间和日期,则是在本类中自己获取,同样设置入控件里面去if (intent != null) {waterIntent = intent;curAddress = intent.getStringExtra(StaticParam.CUR_ADDRESS);userName = intent.getStringExtra(StaticParam.USER_NAME);userOperation = intent.getStringExtra(StaticParam.USER_OPERATION);tv_operation.setText(userOperation);tv_address.setText(curAddress);tv_username.setText(userName);}else {toast("intent equals null,please try again!");}mCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;}/*** 初始化监听器*/private void initListener() {//这个方法是点击拍照的方法imgvBtn_takePic.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mCamera.takePicture(null, null, new PicCallBacKImpl(WaterCameraActivity.this));}});//设置闪光灯的模式,有禁止,自动和打开闪光灯三种模式imgvBtn_switchFlash.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {CameraUtil.setFlashMode(mCamera, imgvBtn_switchFlash);}});//这个是切换前后摄像头的操作,因为时间关系没有做imgvBtn_switchCamera.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {}});//取消按钮,finish本页面btn_back.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {WaterCameraActivity.this.finish();}});mSurfaceView.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {mCamera.autoFocus(autoFocusCallback); //设置相机为自动对焦模式,就不用认为去点击了return false;}});}/*** 我们在此周期方法里面打开摄像头*/@Overrideprotected void onStart() {if (this.checkCameraHardware(this) && (mCamera == null)) {openCamera();//打开后置摄像头}super.onStart();}/*** 拍照回调类*/class PicCallBacKImpl implements Camera.PictureCallback {private Activity mActivity;public PicCallBacKImpl(Activity activity) {this.mActivity = activity;}@Overridepublic void onPictureTaken(byte[] data, Camera camera) {Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);bitmap = ImageUtil.matrixImageView(bitmap, 90);String path = ImageUtil.saveBitmap(null, String.valueOf(currentTimeMillis), bitmap);if (path != null && path.length() > 0) {waterIntent.setClass(mActivity, ViewPhoto.class);waterIntent.putExtra(StaticParam.PIC_PATH, path);waterIntent.putExtra(StaticParam.CUR_DATE, curDate);waterIntent.putExtra(StaticParam.CUR_TIME, curTime);waterIntent.putExtra(StaticParam.CUR_TIME_MILLIS, currentTimeMillis);mActivity.startActivityForResult(waterIntent, REQUEST_CODE);} else {toast("can't save the picture");camera.stopPreview();camera.release();camera = null;}}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if(RESULT_OK == resultCode){switch (requestCode){case REQUEST_CODE: //处理返回结果setResult(RESULT_OK, data); //将结果直接给设置为,启动水印相机的返回结果break;default:break;}WaterCameraActivity.this.finish();//结束本页面,就会将结果返回到调用本页的那个activity了}super.onActivityResult(requestCode, resultCode, data);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {try {mCamera = Camera.open(mCameraId);Camera.getCameraInfo(mCameraId, cameraInfo);} catch (Exception e) {e.printStackTrace();}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {startPreview(mCamera, mSurfaceHolder);}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {if (mCamera != null) {mCamera.stopPreview();mCamera.release();mCamera = null;}}/*** 检查设备是否有摄像头** @param context context* @return boolean*/private boolean checkCameraHardware(Context context) {if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {return true;}return false;}/*** 打开后置摄像头*/private void openCamera() {Camera.CameraInfo cameraInfo = new Camera.CameraInfo();Camera.getCameraInfo(mCameraId, cameraInfo);this.cameraInfo = cameraInfo;if (mCameraId == Camera.CameraInfo.CAMERA_FACING_BACK) { //后置摄像头 CAMERA_FACING_FRONTmCamera = Camera.open();mCamera.startPreview();//开始预览相机}}/*** 开始预览相机** @param camera camera* @param surfaceHolder surfaceHolder*/private void startPreview(Camera camera, SurfaceHolder surfaceHolder) {camera.setDisplayOrientation(CameraUtil.getPreviewDegree(WaterCameraActivity.this));try {camera.setPreviewDisplay(surfaceHolder);} catch (IOException e) {e.printStackTrace();} finally {}camera.startPreview();//调用此方法,然后真正的预览相机}/*** 停止相机预览*/private void stopPreview() {if (mCamera != null) {mCamera.release();mCamera.release();mCamera = null;}}@Overrideprotected void onDestroy() {if (mCamera != null) {mCamera.stopPreview();mCamera.release();mCamera = null;}super.onDestroy();}}
下面是察看图片的类
ViewPhoto类的布局,布局入下图所示
<span style="font-size:12px;"><?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><RelativeLayoutandroid:id="@+id/rl_layout"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="0dp"android:padding="0dp"><ImageViewandroid:id="@+id/imgv_photo"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#000000" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="12dp"android:layout_marginTop="65dp"android:orientation="vertical"><TextViewandroid:id="@+id/tv_time"android:layout_width="wrap_content"android:layout_height="wrap_content"android:shadowColor="#000"android:shadowDx="3"android:shadowDy="3"android:shadowRadius="2"android:text="08:27"android:textColor="#fff"android:textSize="25sp" /><TextViewandroid:id="@+id/tv_date"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/tv_time"android:shadowColor="#000"android:shadowDx="3"android:shadowDy="3"android:shadowRadius="2"android:text="/07/24"android:textColor="#fff"android:textSize="15sp" /></RelativeLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="70dp"android:layout_marginRight="1dp"android:gravity="right"android:orientation="vertical"><TextViewandroid:id="@+id/tv_operation"style="@style/textView_water"android:drawableLeft="@drawable/operation"android:text="点击操作" /><TextViewandroid:id="@+id/tv_userName"style="@style/textView_water"android:drawableLeft="@drawable/user_icon"android:text="钓鱼的小木匠" /><TextViewandroid:id="@+id/tv_address"style="@style/textView_water"android:drawableLeft="@drawable/address"android:text="广东省惠州市惠城区鹅岭南路6号TCL工业大厦" /></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="10dp"android:background="#000"android:gravity="center_vertical"><TextViewandroid:id="@+id/tv_cancel"style="@style/textView_common"android:layout_marginLeft="20dp"android:text="重 拍" /><TextViewandroid:id="@+id/tv_ok"style="@style/textView_common"android:layout_alignParentRight="true"android:layout_marginRight="20dp"android:text="使用图片" /><CheckBoxandroid:id="@+id/cb_savePic"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:checked="true"android:text="保存"android:textColor="#4fe19f" /></RelativeLayout></RelativeLayout></span>
ViewPhoto类代码
<span style="font-size:12px;">/*** 查看拍照的类* <p/>* Created by tanksu on 16/6/29.*/public class ViewPhoto extends BaseActivity {private ImageView imgv_photo;private TextView tv_cancel, tv_ok;private int width, height;private RelativeLayout rl_layout;private String picPath = "", curDate = "", curTime = "", curAddress = "", userName = "", userOperation = "";private TextView tv_time, tv_date, tv_userName, tv_address, tv_operation;private CheckBox cb_savePic;private long currentTimeMillis;private String signal;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏setContentView(R.layout.viewphoto_layout);initViews();initData();initListener();}/*** 初始化控件*/private void initViews() {imgv_photo = (ImageView) findViewById(R.id.imgv_photo);tv_cancel = (TextView) findViewById(R.id.tv_cancel);tv_ok = (TextView) findViewById(R.id.tv_ok);rl_layout = (RelativeLayout) findViewById(R.id.rl_layout);tv_time = (TextView) findViewById(R.id.tv_time);tv_date = (TextView) findViewById(R.id.tv_date);tv_userName = (TextView) findViewById(R.id.tv_userName);tv_address = (TextView) findViewById(R.id.tv_address);cb_savePic = (CheckBox) findViewById(R.id.cb_savePic);tv_operation = (TextView) findViewById(R.id.tv_operation);}/*** 初始化数据*/private void initData() {WindowManager windowManager = getWindowManager();Display display = windowManager.getDefaultDisplay();width = display.getWidth();height = display.getHeight();Intent intent = getIntent();if (intent != null) {//这里的目标是,将所有传过来的的信息都去取出来,设置到每个相应的空间里面去//有人会问我为什么要这样做,其实我在拍照的时候,还没有真正的拿到一张具有水印的照片//我这里采用的是截屏的方式,所以呢,就要重新吧信息展现出来//其实还有很多的方法可以做水印相机,例如用位图来“画”信息等,但是有简单的方法,为什么不用呢,非要去弄一些很复杂的方法?!picPath = intent.getStringExtra(StaticParam.PIC_PATH);curDate = intent.getStringExtra(StaticParam.CUR_DATE);curTime = intent.getStringExtra(StaticParam.CUR_TIME);userName = intent.getStringExtra(StaticParam.USER_NAME);curAddress = intent.getStringExtra(StaticParam.CUR_ADDRESS);userOperation = intent.getStringExtra(StaticParam.USER_OPERATION);signal = intent.getStringExtra(StaticParam.TS_HUB_OP_SIGNAL);currentTimeMillis = intent.getLongExtra(StaticParam.CUR_TIME_MILLIS, System.currentTimeMillis());tv_time.setText(curTime);tv_date.setText(curDate);tv_userName.setText(userName);tv_address.setText(curAddress);tv_operation.setText(userOperation);BitmapFactory.Options options = new BitmapFactory.Options();options.outWidth = width;options.outHeight = height;Bitmap bitmap = ImageUtil.getPressedBitmap(picPath, width, height);//方法在下面,根据路径,获取第一步拍照存本地的图片/***** 根据图片路径,得到压缩过的位图** @param path* @param width* @param height* @return returnBitmappublic static Bitmap getPressedBitmap(String path, int width, int height) {BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;Bitmap bitmap = BitmapFactory.decodeFile(path, options);options.inSampleSize = getBitmapSampleSize(options, width, height);//getBitmapSampleSize(options, width, height)options.inJustDecodeBounds = false;Bitmap returnBitmap = BitmapFactory.decodeFile(path, options);return returnBitmap;}* 根据要去的宽高,压缩图片** @param options options* @param reqWidth reqWidth* @param reqHeight reqHeight* @return inSimpleSizepublic static int getBitmapSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {int imgWidth = options.outWidth;int imgHeight = options.outHeight;int inSimpleSize = 1;if (imgWidth > imgHeight || imgWidth < imgHeight) {final int heightRatio = imgWidth / reqWidth;final int widthRatio = imgHeight / reqHeight;inSimpleSize = widthRatio < heightRatio ? widthRatio : heightRatio;}return inSimpleSize;}*/imgv_photo.setImageBitmap(bitmap);} else {toast("intent equals null,please try again!");}}/*** 初始化监听器*/private void initListener() {//点击使用图片按钮,就可以在启动水印相机的onactivityresult回调里面,获取到图片的路径,然后获取图片即可使用了tv_ok.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {final Bitmap bitmap = getScreenPhoto(rl_layout);ImageUtil.saveBitmap(picPath, String.valueOf(currentTimeMillis), bitmap);//根据路径保存图片/*** 根据路径和名字保存图片** @param path path* @param imgName imgName* @param bitmap bitmap* @return createPathpublic static String saveBitmap(String path, String imgName, Bitmap bitmap) {String savePath = null;if (path == null) { //if path is nullFile fileSDCardDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);String imgPath = fileSDCardDir.getAbsolutePath() + "/s/waterCamera/";File fileDir = new File(imgPath);if (!fileDir.exists()) {fileDir.mkdirs();}String photoName = imgName + ".JPG";imgPath = imgPath + photoName;File fileIphoto = new File(imgPath);if (!fileIphoto.exists()) {try {fileIphoto.createNewFile();} catch (IOException e) {e.printStackTrace();}}savePath = fileIphoto.getPath();saveBitmap(bitmap, fileIphoto);return savePath;} else { //if path isn't null, override the photoFile oldFile = new File(path);if (oldFile.exists()) {oldFile.delete();}File newFile = new File(path);if (!newFile.exists()) {try {newFile.createNewFile();} catch (IOException e) {e.printStackTrace();}}saveBitmap(bitmap, newFile);savePath = newFile.getPath();return savePath;}}*/Intent intent = new Intent(ViewPhoto.this, TsDrActivity.class);intent.putExtra(StaticParam.PIC_PATH, picPath);//这里最主要的,就是将储存在本地的图片的路径作为结果返回intent.putExtra(StaticParam.IS_SAVE_PIC, cb_savePic.isChecked());//这里就是是否用户要保存这张图片的选项intent.putExtra(StaticParam.TS_HUB_OP_SIGNAL, signal);setResult(RESULT_OK, intent); //如果是OK,就设置为OK结果ViewPhoto.this.finish();}});tv_cancel.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {new Thread(new Runnable() {@Overridepublic void run() {ImageUtil.deleteImageFromSDCard(picPath);//重新拍照,就将本地的图片给删除掉,然后重新拍照}}).start();ViewPhoto.this.finish();}});}/*** 截屏,这里就是截屏的地方了,我这里是截屏RelativeLayout,* 只要你将需要的信息放到这个RelativeLayout里面去就可以截取下来了** @param waterPhoto waterPhoto* @return Bitmap*/public Bitmap getScreenPhoto(RelativeLayout waterPhoto) {View view = waterPhoto;view.setDrawingCacheEnabled(true);view.buildDrawingCache();Bitmap bitmap = view.getDrawingCache();int width = view.getWidth();int height = view.getHeight();Bitmap bitmap1 = Bitmap.createBitmap(bitmap, 0, 0, width, height);view.destroyDrawingCache();bitmap = null;return bitmap1;}</span>
使用
<span style="font-size:12px;">//例如:启动水印相机的代码Intent intent = new Intent(TsHubActivity.this, WaterCameraActivity.class);intent.putExtra(StaticParam.CUR_ADDRESS, curAddress);intent.putExtra(StaticParam.USER_NAME, stationName);Button btn_recv = (Button) findViewById(R.id.batchRecv);intent.putExtra(StaticParam.USER_OPERATION, btn_recv.getText().toString());startActivityForResult(intent, JustOneOrder);</span>
回调
<span style="font-size:12px;">//拍照回调方法@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {//以下是需要拍照的图片参数final String imgPath = data.getStringExtra(StaticParam.PIC_PATH);//图片路径Bitmap bitmap = BitmapFactory.decodeFile(imgPath);//获取到图片了}</span>
上面这两个类,直接复制来就可以用了,可以根据你的需求进行修改,不难,很简单。关于前后摄像头切换的,因为时间紧任务重,就没有时间去做了。
如有任何问题,请及时与我联系,谢谢。