拍照问题
司项目里面需要拍照的地方很多,因为每次选取一张单张上传,所以并没有使用很多已经写好的第三方,反而选取了android原生的拍照和相册选择。
最先遇见的问题就是适配,找网上的帖子很多都有原生的拍照,但是在三星、华为、小米上面并不能完全适配,特别是华为和三星。花了我一段时间
终于找到一个靠谱点的方法,记录下来。
先贴代码吧。
public class MainActivity extends AppCompatActivity {
private Button button;
private static final int TAKE_PHOTO=1234;
private static final int LOOK_PHOTO=4321;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = ((Button) findViewById(R.id.button));
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//弹出选择提示框
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("选择图片");
builder.setPositiveButton("相册", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
startActivityForResult(intent,LOOK_PHOTO);
}
});
builder.setNegativeButton("拍照", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Intent intent = new Intent(MainActivity.this, UseCameraActivity.class);
startActivityForResult(intent,TAKE_PHOTO);
}
});
builder.show();
}
});
}
//接收返回数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//判断是否是选择图片或者拍照图片的成功返回
if(resultCode==RESULT_OK&&(requestCode==TAKE_PHOTO||requestCode==LOOK_PHOTO)){
Uri uri=null;
String filePath=null;
if(requestCode==TAKE_PHOTO){
filePath=data.getStringExtra(UseCameraActivity.IMAGE_PATH);
}else{
uri=data.getData();
filePath = getRealFilePath(this, uri);
}
Toast.makeText(this,filePath,Toast.LENGTH_SHORT).show();
}else{
//进行失败处理
}
}
//选择相册后获得图片的真实路径
public static String getRealFilePath(final Context context, final Uri uri) {
if (null == uri)
return null;
final String scheme = uri.getScheme();
String data = null;
if (scheme == null)
data = uri.getPath();
else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
data = uri.getPath();
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null,
null);
if (null != cursor) {
if (cursor.moveToFirst()) {
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
if (index > -1) {
data = cursor.getString(index);
}
}
cursor.close();
}
}
return data;
}
}
//这个主要的拍照处理的activity,由于这边出现了一种情况:有两个Activity,一个为A,一个为B,由A跳B,再由B跳向拍照,拍完照返回时发现B消失了,查了查原因可能是由于手机内存过于小,当跳转到拍照时,app相当于位于后台,在拍照的过程中,手机自动杀死了Activity导致返回时候Activity为空,app出错,这里进行的处理就是在Activity被杀死时候通过saveinstance保存拍照地址进行处理。
public class UseCameraActivity extends AppCompatActivity {
public final static String IMAGEFILEPATH = "ImageFilePath";
public final static String IMAGE_PATH = "image_path";
private String mImageFilePath;
private final static String TAG ="UseCameraActivity";
static Activity mContext;
private static Context applicationContext;
public static final int TAKE_PHOTO=1111;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//判断savedInstanceState是否保存的有数据
if (savedInstanceState != null) {
//有数据,获取数据并返回
mImageFilePath = savedInstanceState.getString(IMAGEFILEPATH);
File file = new File(mImageFilePath);
if (file.exists()) {
Intent intent = new Intent();
intent.putExtra(IMAGE_PATH, IMAGEFILEPATH);
setResult(RESULT_OK, intent);
Log.e(TAG,"拍摄成功");
finish();
}else{
Log.e(TAG,"拍摄失败");
}
}
//没有数据,前往拍照页面
mContext=this;
applicationContext=getApplicationContext();
if(savedInstanceState==null){
takePhoto();
}
}
//这里获取系统时间给图片命名
public void takePhoto(){
long currentTimeMillis = System.currentTimeMillis();
mImageFilePath = getCameraPath() + currentTimeMillis+".jpg";
File file = new File(mImageFilePath);
showCamera(file);
}
private void showCamera(File file){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent,TAKE_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==TAKE_PHOTO&&resultCode==RESULT_OK){
Intent intent = new Intent();
intent.putExtra(IMAGE_PATH,IMAGEFILEPATH);
setResult(RESULT_OK,intent);
finish();
}else{
finish();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
//Activity被杀死时候保存数据
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(IMAGEFILEPATH,mImageFilePath+"");
}
//下面这三个方法是为了创建file,华为的手机不会默认创建3级file,只能一层一层慢慢创建了,
public static String getCameraPath() {
String filePath = getImageRootPath() + "/camera/";
File file = new File(filePath);
if (!file.isDirectory()) {
file.mkdirs();
}
file = null;
return filePath;
}
public static String getImageRootPath() {
String filePath = getAppRootPath() + "/image";
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
file = null;
return filePath;
}
public static String getAppRootPath() {
String filePath = "/a";
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
filePath = Environment.getExternalStorageDirectory() + filePath;
} else {
filePath = applicationContext.getCacheDir() + filePath;
}
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
file = null;
File nomedia = new File(filePath + "/.nomedia");
if (!nomedia.exists())
try {
nomedia.createNewFile();
} catch (IOException e) {
}
return filePath;
}
}