Android Camera 三星BUG :
最近在Android项目中使用拍照功能 , 其它型号的手机运行成功了 唯独在三星的相机上遇到了bug .
BUG具体体现为 :
(1) 摄像头拍照后图片数据不一定能返回 ; onActivityResult的data为空
(2) 三星的camera强制切换到横屏 导致Activity重启生命周期 (但是部分机型 配置 android:configChanges 也不能阻止横竖屏切换);
我的解决方法为
如果 activity 的销毁如果无法避免 那么在activity销毁之前调用 onSaveInstanceState 保存图片的路径
当activity重新创建的时候 会将 onSaveInstanceState 保存的文件传递给onCreate()当中
在onCreate当中 检查照片的地址是否存在文件 以此来判定拍照是否成功
运气不错 终于通过了测试同学们的验证.....
我的代码如下:
配置 Androidmanifest.xml 中的配置 activity
<activity android:name=".UseCameraActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|navigation" android:launchMode="singleTop" android:screenOrientation="portrait" />
增加权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
功能是: 根据指定的路径 生成bitmap ; 显示图片
package com.example.camerabaozi; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import android.app.Activity; import android.content.ContentResolver; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import com.nostra13.universalimageloader.core.ImageLoader; /** * 启动界面 * * 照片生成的目录在 sd卡的/a/image/camera/.. .jpg * * @author baozi * */ public class MainActivity extends Activity { protected static final int REQCAMERA = 11; private static final String TAG = "MainActivity"; private View button1; private ImageView photo_iv; private ContentResolver mContentResolver; final int IMAGE_MAX_SIZE = 1024; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContentResolver = getContentResolver(); button1 = (Button) findViewById(R.id.button1); button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, UseCameraActivity.class); startActivityForResult(intent, REQCAMERA); } }); photo_iv = (ImageView) findViewById(R.id.imageView1); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQCAMERA: String path = data.getStringExtra(UseCameraActivity.IMAGE_PATH); Log.i("123", path); // 根据照片的位置获取图片 Bitmap bitmap = getBitmap(path); photo_iv.setImageBitmap(bitmap); // ImageLoader.getInstance().displayImage( // getImageUri(path).toString(), photo_iv); break; default: super.onActivityResult(requestCode, resultCode, data); break; } } private Uri getImageUri(String path) { return Uri.fromFile(new File(path)); } private Bitmap getBitmap(String path) { Uri uri = getImageUri(path); InputStream in = null; try { in = mContentResolver.openInputStream(uri); // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(in, null, o); in.close(); int scale = 1; if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) { scale = (int) Math.pow( 2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5))); } BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; in = mContentResolver.openInputStream(uri); Bitmap b = BitmapFactory.decodeStream(in, null, o2); in.close(); return b; } catch (FileNotFoundException e) { Log.e(TAG, "file " + path + " not found"); } catch (IOException e) { Log.e(TAG, "file " + path + " not found"); } return null; } } // ┏┓ ┏┓ // ┏┛┻━━━┛┻┓ // ┃ ┃ // ┃ ━ ┃ // ┃ ┳┛ ┗┳ ┃ // ┃ ┃ // ┃ ┻ ┃ // ┃ ┃ // ┗━┓ ┏━┛ // ┃ ┃ 神兽保佑 // ┃ ┃ 代码无BUG! // ┃ ┗━━━┓ // ┃ ┣┓ // ┃ ┏┛ // ┗┓┓┏━┳┓┏┛ // ┃┫┫ ┃┫┫ // ┗┻┛ ┗┻┛
本类的功能是调用 生成图片拍摄后的路径
照片生成的目录在 sd卡的/a/image/camera/.. .jpg
package com.example.camerabaozi; import java.io.File; import java.io.IOException; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; /** * 照片生成的目录在 sd卡的/a/image/camera/.. .jpg * * @author baozi * */ public class UseCameraActivity extends Activity { private String mImageFilePath; public static final String IMAGEFILEPATH = "ImageFilePath"; public final static String IMAGE_PATH = "image_path"; static Activity mContext; public final static int GET_IMAGE_REQ = 5000; private static Context applicationContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //判断 activity被销毁后 有没有数据被保存下来 if (savedInstanceState != null) { mImageFilePath = savedInstanceState.getString(IMAGEFILEPATH); Log.i("123---savedInstanceState", mImageFilePath); File mFile = new File(IMAGEFILEPATH); if (mFile.exists()) { Intent rsl = new Intent(); rsl.putExtra(IMAGE_PATH, mImageFilePath); setResult(Activity.RESULT_OK, rsl); Log.i("123---savedInstanceState", "图片拍摄成功"); finish(); } else { Log.i("123---savedInstanceState", "图片拍摄失败"); } } mContext = this; applicationContext = getApplicationContext(); if (savedInstanceState == null) { initialUI(); } } public void initialUI() { //根据时间生成 后缀为 .jpg 的图片 long ts = System.currentTimeMillis(); mImageFilePath = getCameraPath() + ts + ".jpg"; File out = new File(mImageFilePath); showCamera(out); } private void showCamera(File out) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out)); // set startActivityForResult(intent, GET_IMAGE_REQ); } @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { if (GET_IMAGE_REQ == requestCode && resultCode == Activity.RESULT_OK) { Intent rsl = new Intent(); rsl.putExtra(IMAGE_PATH, mImageFilePath); mContext.setResult(Activity.RESULT_OK, rsl); mContext.finish(); } else { mContext.finish(); } } @Override protected void onDestroy() { super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("ImageFilePath", mImageFilePath + ""); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); } 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; } } //┏┓ ┏┓ //┏┛┻━━━┛┻┓ //┃ ┃ //┃ ━ ┃ //┃ ┳┛ ┗┳ ┃ //┃ ┃ //┃ ┻ ┃ //┃ ┃ //┗━┓ ┏━┛ //┃ ┃ 神兽保佑 //┃ ┃ 代码无BUG! //┃ ┗━━━┓ //┃ ┣┓ //┃ ┏┛ //┗┓┓┏━┳┓┏┛ // ┃┫┫ ┃┫┫ // ┗┻┛ ┗┻┛
Demo 下载地址: http://download.csdn.net/detail/aaawqqq/7653475
祝福大家每日精进
谢谢