Android 自定义Camrea拍照自动旋转图片及保存
前言:抱着最起码的要求尽力去做好每一件事 ! ——秋不白
本文适用:针对项目的相机多张拍摄,查看图库(自己写的,查看自己拍摄的照片,不包含系统图库和其他文件夹的图片),其实也是自己项目中不断总结,为什么还要写个自定义相机呢,因为之前项目中写的不够好,拍照图片的旋转啊,现在离开公司了,总觉得还欠缺点什么,如有需要可以联系我,代码还没有上传github(后面我再放到gitbug),如需完整代码,可以联系我。
我定义了Photo和classPhoto两个java bean,快速开发就接入了LitePal,Glide,鸿洋大神的适配器,
图库效果截图:
功能:监听手机横着竖着,(比如竖着拍摄的照片,查看的时候希望是横着的,而不是竖着),动态修改相机参数,保存照片,以及加载图片。
申请权限,权限要自己加了
前提:
1 自定义SurfaceView(还有GLSurfaceView,TextureView,使用SurfaceView,最简单,毕竟是Google亲儿子,都封装好了)
2.Camera 工具类,(单利模式管理Camera对象,参数设置,释放资源等)(封成工具类,方便后面自己用GLSurfaceView,TextureView去实现相机,以及后面接入openGL,,或者opencv 做人脸识别,识别人脸拍照等等)
Camera工具类
package com.redrose.videodemo.camera;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import java.util.List;
/**
* Desc: 相机工具类
* author: RedRose
* Date: 2019/3/20
* Email: [email protected]
*/
public class CameraUtil {
private static CameraUtil mInstance;
/**
* 相机参数对象
*/
private Camera.Parameters mParameters;
/**
* 闪光灯自动
*/
public static final int FLASH_AUTO = 0;
/**
* 闪光灯关闭
*/
public static final int FLASH_OFF = 1;
/**
* 闪光灯开启
*/
public static final int FLASH_ON = 2;
private CameraUtil() {
}
private static final Object o = new Object();
public static CameraUtil getInstance() {
if (mInstance == null) {
synchronized (o) {
if (mInstance == null) {
mInstance = new CameraUtil();
}
}
}
return mInstance;
}
private Camera mCamera;
public Camera openCamera() {
// 0 表示开启后置相机
return openCamera(0);
}
public Camera openCamera(int id) {
if (mCamera == null) {
mCamera = Camera.open(id);
}
setProperty();
return mCamera;
}
/**
* 相机属性设置
*/
private void setProperty() {
//设置相机预览页面旋转90°,(默认是横屏)
mCamera.setDisplayOrientation(90);
mParameters = mCamera.getParameters();
//设置将保存的图片旋转90°(竖着拍摄的时候)
mParameters.setRotation(90);
mParameters.setPreviewSize(1920, 1080);
mParameters.setPictureSize(1920, 1080);
// mParameters.setPictureSize(4608, 3456);
mParameters.setPictureFormat(ImageFormat.JPEG);
mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// mParameters.set(ImageFormat.YUV_444_888);
mCamera.setParameters(mParameters);
}
/**
* 选装图片的角度
*/
public void setRotateDegree(int degree) {
// boolean result = degree == 0 || degree == 90
// mParameters.setRotation(90);
if (mCamera != null) {
mParameters = mCamera.getParameters();
mParameters.setRotation(degree);
mCamera.setParameters(mParameters);
}
}
/**
* 获取支持的预览分辨率
*/
public List<Camera.Size> getPreviewSizeList() {
if (mCamera == null) {
throw new NullPointerException("Camera can not be null");
}
return mCamera.getParameters().getSupportedPreviewSizes();
}
/**
* 获取保存图片支持的分辨率
*/
public List<Camera.Size> getPictureSizeList() {
if (mCamera == null) {
throw new NullPointerException("Camera can not be null");
}
return mCamera.getParameters().getSupportedPictureSizes();
}
/**
* 设置闪光灯模式
*/
public void setFlashMode(int mode) {
mParameters = mCamera.getParameters();
String flashMode = mParameters.getFlashMode();
switch (mode) {
case FLASH_AUTO:
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
break;
case FLASH_OFF:
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
break;
case FLASH_ON:
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
break;
default:
break;
}
mCamera.setParameters(mParameters);
}
/**
* 释放相机资源
*/
public void releaseCamera() {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.lock();
mCamera.release();
mCamera = null;
isRelease = true;
}
}
/**
* 是否旋转图片 true 选装
*/
private boolean isRelease = false;
public boolean getIsRelease() {
return isRelease;
}
/**
* 设置保存图片的分辨率
*/
public void setSaveSize(Camera.Size saveSize) {
mParameters.setPictureSize(saveSize.width, saveSize.height);
mCamera.setParameters(mParameters);
}
}
自定义SurfaceView
package com.redrose.videodemo.camera;
import android.content.Context;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.redrose.videodemo.utils.BitmapCallBack;
import com.redrose.videodemo.utils.LogUtils;
import com.redrose.videodemo.utils.ToastUtil;
import com.redrose.videodemo.utils.ToolUtils;
import java.io.IOException;
/**
* Desc:
* Author: RedRose
* Date: 2019/3/20
* Email: [email protected]
*/
public class Preview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback, Camera.PictureCallback {
private Camera mCamera;
private BitmapCallBack mBitmapCallback;
private static final String TAG = Preview.class.getSimpleName();
public Preview(Context context) {
this(context, null);
}
public Preview(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public Preview(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mCamera = CameraUtil.getInstance().openCamera();
SurfaceHolder holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
LogUtils.e(TAG, " --surfaceCreated--");
try {
//这里必须要这样处理,比如锁屏,回到桌面,再次回到相机的时候,surfaceCreated 会重新执行
//所以,要加个标识,判断是否被释放过资源
if (CameraUtil.getInstance().getIsRelease()) {
mCamera = CameraUtil.getInstance().openCamera();
}
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.setPreviewCallback(this);
mCamera.startPreview();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
LogUtils.e(TAG, " --surfaceChanged--");
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
LogUtils.e(TAG, " --surfaceDestroyed--");
//每次 执行surfaceDestroyed,都要销毁,释放camera
CameraUtil.getInstance().releaseCamera();
}
/**
* 预览回调
*/
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
}
/**
* 拍摄成功后回调
*/
@Override
public void onPictureTaken(byte[] data, Camera camera) {
if (mBitmapCallback != null) {
mBitmapCallback.backByte(data);
}
camera.startPreview();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
/**
* 触摸聚焦
*/
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
ToastUtil.show(getContext(), "聚焦成功");
camera.cancelAutoFocus();
}
}
});
return super.onTouchEvent(event);
}
public void takePhoto() {
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
//设置聚焦成功后再拍照,其实可以不用。看需求吧,可以直接调用takePicture()
//有些手机会聚焦失败,也就是success是false
if (success) {
ToastUtil.show(getContext(), "聚焦成功");
camera.cancelAutoFocus();
mCamera.takePicture(null, null, Preview.this);
}
}
});
}
/**
* 设置回调到Activity吧
*/
public void setBitmapCallback(BitmapCallBack callback) {
this.mBitmapCallback = callback;
}
}
public interface BitmapCallBack {
void backByte(byte[] data);
}
CamreaActivity
package com.redrose.videodemo.camera;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.redrose.videodemo.base.BaseActivity;
import org.litepal.crud.DataSupport;
import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;
import com.redrose.videodemo.R;
import com.redrose.videodemo.bean.Photo;
import com.redrose.videodemo.bean.Time;
import com.redrose.videodemo.utils.BitmapCallBack;
import com.redrose.videodemo.utils.GlideUtils;
import com.redrose.videodemo.utils.IntentUtils;
import com.redrose.videodemo.utils.LogUtils;
import com.redrose.videodemo.utils.MySensorHelper;
import com.redrose.videodemo.utils.SPUtils;
import com.redrose.videodemo.utils.ToastUtil;
import com.redrose.videodemo.utils.ToolUtils;
import com.zhy.adapter.recyclerview.CommonAdapter;
import com.zhy.adapter.recyclerview.base.ViewHolder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
/**
* Desc:
* Author: RedRose
* Date: 2019/3/20
* Email: [email protected]
*/
@ContentView(R.layout.activity_camera)
public class CameraActivity extends BaseActivity implements BitmapCallBack {
@ViewInject(R.id.pre_text)
private TextView mPreSize;
@ViewInject(R.id.save_text)
private TextView mSaveSize;
@ViewInject(R.id.flashlight)
private ImageView mFlashView;
@ViewInject(R.id.photo_list)
private ImageView mPreImageView;
@ViewInject(R.id.take_photo)
private View mTakePhoto;
@ViewInject(R.id.camera_preview)
private Preview mPreview;
private boolean showLocation = false;
private PopupWindow mPopWindow;
private List<Photo> mPhotoList;
private Time mTime;
/**
* 是否旋转图片
* true 表示当前Activity 处于横屏,false:当前处于竖屏
*/
private boolean mIsRotate = false;
/**
* 重力传感器监听
* 横着 竖着状态
*/
private MySensorHelper mMySensor;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initData();
}
private void initData() {
mMySensor = new MySensorHelper(this);
mMySensor.enable();
int mode = SPUtils.getInt("Flash_mode");
initFlashMode(mode);
mPreview.setBitmapCallback(this);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Calendar calendar = Calendar.getInstance();
String format = sdf.format(calendar.getTime());
mTime = new Time();
mTime.setClassId(Long.parseLong(format));
mTime.setDay(calendar.get(Calendar.DAY_OF_MONTH));
mTime.setYear(calendar.get(Calendar.YEAR));
mTime.setMonth(calendar.get(Calendar.MONTH) + 1);
mPhotoList = new ArrayList<>();
}
private void showPopWindow(View view) {
mPopWindow = new PopupWindow(view, ToolUtils.dp2px(mContext.getApplicationContext(),
200), ToolUtils.dp2px(mContext.getApplicationContext(), 200));
mPopWindow.setFocusable(true);
// popupWindow.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#3F51B5")));
mPopWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mPopWindow.setOutsideTouchable(true);
mPopWindow.update();
if (showLocation) {
mPopWindow.showAsDropDown(mSaveSize);
} else {
mPopWindow.showAsDropDown(mPreSize);
}
}
/**
* 显示支持保存的分辨率
*/
private void showSupportSize(List<Camera.Size> list) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.pop_size_layout, null);
RecyclerView recycleView = view.findViewById(R.id.recycle_size);
initRecycle(recycleView);
SizeAdapter mAdapter = new SizeAdapter(mContext, R.layout.size_item, list);
recycleView.setAdapter(mAdapter);
showPopWindow(view);
}
@Event(value = {R.id.pre_text, R.id.save_text, R.id.flashlight, R.id.take_photo, R.id.photo_list,
R.id.all_list})
private void onclickView(View view) {
int id = view.getId();
switch (id) {
/*暂时注释 动态设置预览分辨率*/
case R.id.pre_text:
/*预览分辨率,建议设置成屏幕分辨率,经测试,支持的最高就是屏幕分辨率 */
showLocation = false;
showSupportSize(CameraUtil.getInstance().getPreviewSizeList());
break;
//设置保存图片的分辨率
case R.id.save_text:
showLocation = true;
showSupportSize(CameraUtil.getInstance().getPictureSizeList());
break;
//切换闪光灯模式
case R.id.flashlight:
int mode = SPUtils.getInt("Flash_mode");
if (mode == CameraUtil.FLASH_AUTO) {
mode = CameraUtil.FLASH_OFF;
} else if (mode == CameraUtil.FLASH_OFF) {
mode = CameraUtil.FLASH_ON;
} else if (mode == CameraUtil.FLASH_ON) {
mode = CameraUtil.FLASH_AUTO;
}
SPUtils.put("Flash_mode", mode);
initFlashMode(mode);
break;
//拍照
case R.id.take_photo:
mPreview.takePhoto();
break;
//打开当前拍摄的照片图库
case R.id.photo_list:
int size = mPhotoList.size();
if (size == 0) {
ToastUtil.show(mContext, "还未拍摄照片,可以点击右侧查看所有照片");
return;
}
Bundle bundle = new Bundle();
bundle.putSerializable("photoList", (ArrayList<Photo>) mPhotoList);
IntentUtils.goToPreviewActivity(mContext, bundle);
break;
//打开图库
case R.id.all_list:
IntentUtils.goToImageActivity(mContext, null);
break;
default:
break;
}
}
private void initRecycle(RecyclerView recyclerView) {
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//设置布局管理器
recyclerView.setLayoutManager(layoutManager);
//设置为垂直布局,这也是默认的
layoutManager.setOrientation(OrientationHelper.VERTICAL);
//设置Adapter
// recyclerView.setAdapter(recycleAdapter);
//设置分隔线
// recyclerView.addItemDecoration(new DividerGridItemDecoration(this));
//设置增加或删除条目的动画
recyclerView.setItemAnimator(new DefaultItemAnimator());
}
@Override
public void backByte(byte[] data) {
GlideUtils.loadByte(mPreImageView, data);
ToolUtils.saveImageFile(data, mPhotoList, mIsRotate);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Calendar calendar = Calendar.getInstance();
String format = sdf.format(calendar.getTime());
List<Time> times = DataSupport.where("classId = ?", format).find(Time.class);
mTime.setPhotoList(mPhotoList);
if (times.size() == 0) {
mTime.save();
}
}
/**
* Desc: 相机页面,拍摄照片保存分辨率 显示适配器
* author: RedRose
* Date: 2019/4/1
* Email: [email protected]
*/
private class SizeAdapter extends CommonAdapter<Camera.Size> {
private SizeAdapter(Context context, int layoutId, List<Camera.Size> datas) {
super(context, layoutId, datas);
}
@Override
protected void convert(ViewHolder holder, Camera.Size size, int position) {
LogUtils.d("----redrose 装载数据测试 ----");
TextView textView = holder.getView(R.id.size_text);
String sizeString = String.format("%d * % d", size.width, size.height);
textView.setText(sizeString);
if (showLocation) {
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CameraUtil.getInstance().setSaveSize(size);
if (mPopWindow != null) {
mPopWindow.dismiss();
mPopWindow = null;
}
ToastUtil.show(mContext, size.width + "x" + size.height);
}
});
}
}
}
private void initFlashMode(int mode) {
if (mode == CameraUtil.FLASH_AUTO) {
mFlashView.setImageResource(R.mipmap.flash_auto);
} else if (mode == CameraUtil.FLASH_OFF) {
mFlashView.setImageResource(R.mipmap.flash_off);
} else if (mode == CameraUtil.FLASH_ON) {
mFlashView.setImageResource(R.mipmap.flash_on);
}
CameraUtil.getInstance().setFlashMode(mode);
}
@Override
protected void onDestroy() {
super.onDestroy();
mMySensor.disable();
LogUtils.e(TAG, " ---onDestroy---");
}
/**
* 是否旋转图片
*/
public void setIsRotate(boolean isRotate) {
if(mIsRotate == isRotate){
return;
}
this.mIsRotate = isRotate;
if (mIsRotate) {
CameraUtil.getInstance().setRotateDegree(0);
}else {
CameraUtil.getInstance().setRotateDegree(90);
}
}
public boolean getIsRotate(){
return mIsRotate;
}
}
重力监听传感器,判断手机是横着还是竖着
package com.redrose.videodemo.utils;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.util.Log;
import android.view.OrientationEventListener;
import com.redrose.videodemo.camera.CameraActivity;
import java.lang.ref.WeakReference;
/**
* Desc:
* 手机横着竖着监听
*
* @author: RedRose
* Date: 2019/4/2
* Email: [email protected]
*/
public class MySensorHelper {
private static final String TAG = MySensorHelper.class.getSimpleName();
private OrientationEventListener mLandOrientationListener;
private OrientationEventListener mPortOrientationListener;
private WeakReference<CameraActivity> mActivityWeakRef;
private boolean isPortLock = false;
private boolean isLandLock = false;
public MySensorHelper(final CameraActivity activity) {
this.mActivityWeakRef = new WeakReference(activity);
this.mLandOrientationListener = new OrientationEventListener(activity, 3) {
public void onOrientationChanged(int orientation) {
LogUtils.d(MySensorHelper.TAG, "mLandOrientationListener");
if (orientation < 100 && orientation > 80 || orientation < 280 && orientation > 260) {
LogUtils.e(MySensorHelper.TAG, "转到了横屏");
if (!MySensorHelper.this.isLandLock) {
CameraActivity mActivity = MySensorHelper.this.mActivityWeakRef.get();
if (mActivity != null) {
LogUtils.e(MySensorHelper.TAG, "转到了横屏##################");
/*mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
isLandLock=true;
isPortLock=false;*/
if (!mActivity.getIsRotate()) {
mActivity.setIsRotate(true);
}
}
}
}
}
};
this.mPortOrientationListener = new OrientationEventListener(activity, 3) {
public void onOrientationChanged(int orientation) {
LogUtils.d(MySensorHelper.TAG, "mPortOrientationListener");
if (orientation < 10 || orientation > 350 || orientation < 190 && orientation > 170) {
LogUtils.e(MySensorHelper.TAG, "转到了竖屏");
if (!MySensorHelper.this.isPortLock) {
CameraActivity mActivity = MySensorHelper.this.mActivityWeakRef.get();
if (mActivity != null) {
LogUtils.e(MySensorHelper.TAG, "转到了竖屏!!!!!!!!!!!!!!!!!!!!!!");
/*mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
isPortLock=true;
isLandLock=false*/
;
if (mActivity.getIsRotate()) {
mActivity.setIsRotate(false);
}
}
}
}
}
};
//this.disable();
}
//禁用切换屏幕的开关
public void disable() {
Log.e(TAG, "disable");
this.mPortOrientationListener.disable();
this.mLandOrientationListener.disable();
}
//开启横竖屏切换的开关
public void enable() {
this.mPortOrientationListener.enable();
this.mLandOrientationListener.enable();
}
//设置竖屏是否上锁,true锁定屏幕,fanle解锁
public void setPortLock(boolean lockFlag) {
this.isPortLock = lockFlag;
}
//设置横屏是否锁定,true锁定,false解锁
public void setLandLock(boolean isLandLock) {
this.isLandLock = isLandLock;
}
}
依赖的jar
implementation 'com.android.support:recyclerview-v7:26+'
implementation 'org.xutils:xutils:3.3.36'
implementation 'com.zhy:base-adapter:3.0.3'
implementation 'com.zhy:base-rvadapter:3.0.3'
CameraActivity 布局xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.redrose.videodemo.camera.Preview
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:visibility="gone"
android:id="@+id/pre_text"
style="@style/camera_button_style"
android:text="预览分辨率" />
<TextView
android:layout_marginEnd="10dp"
android:layout_alignParentEnd="true"
android:id="@+id/save_text"
style="@style/camera_button_style"
android:text="保存分辨率" />
<ImageView
android:layout_marginTop="20dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/flash_on"
android:id="@+id/flashlight"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<View
android:id="@+id/take_photo"
android:layout_marginBottom="20dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:background="@drawable/take_photo_selector"
android:layout_width="56dp"
android:layout_height="56dp"/>
<ImageView
android:layout_alignParentBottom="true"
android:layout_marginStart="10dp"
android:layout_marginBottom="10dp"
android:src="@mipmap/ic_launcher"
android:id="@+id/photo_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:src="@mipmap/ic_launcher"
android:id="@+id/all_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
共享参数工具类
/*
*
* Copyright 2016 YunDi
*
* The code is part of Yunnan, Shenzhen Branch of the internal architecture of YunDi source group
*
* DO NOT DIVULGE
*
*/
package com.redrose.videodemo.utils;
import android.content.Context;
import android.content.SharedPreferences;
import org.xutils.common.util.LogUtil;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
public class SPUtils {
public static final String TAG = SPUtils.class.getSimpleName();
public static final String KEY_USER_INFO = "user_info";
private static Context mContext;
public static void init(Context context) {
mContext = context;
}
/**
* 保存在手机里面的文件名
*/
public static final String FILE_NAME = "share_data";
/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*
* @param key
* @param object
*/
public static void put(String key, Object object) {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
editor.putInt(key, (Integer) object);
} else if (object instanceof Boolean) {
editor.putBoolean(key, (Boolean) object);
} else if (object instanceof Float) {
editor.putFloat(key, (Float) object);
} else if (object instanceof Long) {
editor.putLong(key, (Long) object);
} else {
editor.putString(key, object.toString());
}
editor.commit();
}
public static String getString(String key) {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.getString(key, null);
}
public static int getInt(String key) {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.getInt(key, 0);
}
public static long getLong(String key) {
return (long) get(key, 0);
}
public static float getFloat(String key) {
return (float) get(key, 0f);
}
public static boolean getBoolean(String key) {
return (boolean) get(key, false);
}
/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*
* @param key
* @param defaultObject
* @return
*/
public static Object get(String key, Object defaultObject) {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
if (defaultObject instanceof Integer) {
return sp.getInt(key, (Integer) defaultObject);
} else if (defaultObject instanceof Boolean) {
return sp.getBoolean(key, (Boolean) defaultObject);
} else if (defaultObject instanceof Float) {
return sp.getFloat(key, (Float) defaultObject);
} else if (defaultObject instanceof Long) {
return sp.getLong(key, (Long) defaultObject);
}
return null;
}
/**
* 移除某个key值已经对应的值
*
* @param key
*/
public static void remove(String key) {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
SharedPreferencesCompat.apply(editor);
}
/**
* 清除所有数据
*/
public static void clear() {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
SharedPreferencesCompat.apply(editor);
}
/**
* 查询某个key是否已经存在
*
* @param key
* @return
*/
public static boolean contains(String key) {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.contains(key);
}
/**
* 返回所有的键值对
*
* @return
*/
public static Map<String, ?> getAll() {
SharedPreferences sp = mContext.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.getAll();
}
/**
* 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
*/
private static class SharedPreferencesCompat {
private static final Method sApplyMethod = findApplyMethod();
/**
* 反射查找apply的方法
*
* @return
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private static Method findApplyMethod() {
try {
Class clz = SharedPreferences.Editor.class;
return clz.getMethod("apply");
} catch (NoSuchMethodException e) {
}
return null;
}
/**
* 如果找到则使用apply执行,否则使用commit
*
* @param editor
*/
public static void apply(SharedPreferences.Editor editor) {
try {
if (sApplyMethod != null) {
sApplyMethod.invoke(editor);
return;
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
editor.commit();
}
}
}
有的同学实现这个功能后,在打开系统图库的时候,看不见这张图片,是因为系统每次开机时会去检索图片等资源,把索引存到数据库,所以要通知刷新媒体库,要发广播通知系统刷新(如何发,百度一大把,我就不赘述了)。
先就这么多吧,最关键的就是自定义SurfaceView和CameraUtil 工具类。可以接着后面,继续写,实现更多的需求,我的目标是使用MediaCodeC录制编码小视频和解码,这部分还未完成。改天推到gitbub,就可以拉完整代码了