您的位置:首页 > 移动开发 > Android开发

Android解决小米手机相机和相册的问题(适配小米手机相机和相册)

2016-09-09 20:41 417 查看
这两天做一个功能,需要拍照和相册选择图片并上传,功能本来不难,但是MIUI就不行了,拍照和相册取图用一般的方法都有问题,网上查了好多都是转载的,且解决办法有问题,当然也可能是我使用有问题,总之最后还是从网上东拼西凑做的,现在做个总结,也方便自己日后的使用。

测试机:小米5

相机:以storage为存储路径以当前时间作为File的文件名,拍照后根据路径获取图片的File就可以为所欲为了。

// 存储路径
private static final String PATH = Environment
.getExternalStorageDirectory() + "/DCIM";

// 图片名
public String name;
public void takephoto(View v){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 调用系统相机
new DateFormat();
name = DateFormat.format("yyyyMMdd_hhmmss",
Calendar.getInstance(Locale.CHINA))
+ ".jpg";//以当前时间作为文件名
Uri imageUri = Uri.fromFile(new File(PATH, name));

intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

startActivityForResult(intent, RESULT_FROM_CAMERA);
}

然后在onActivityResult()中对图片进行处理,这里就单纯的放到imageview里了,内存小的手机发生OOM表找我。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_FROM_CAMERA && resultCode == RESULT_OK){
String filePath = PATH + "/" + name;
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
imageview.setImageBitmap(bitmap);
}
}
这样就结束了,拍照还是蛮简单的。

从相册选择:

调用相册的方法都一样,不多说了

<span style="white-space:pre">	</span>Intent i = new Intent(Intent.ACTION_PICK, null);
i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(i, RESULT_FROM_ALBUM);
关键是在onActivityResult中,需要单独对小米机型做处理

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_FROM_ALBUM && resultCode == RESULT_OK){
if (SystemUtils.isMIUI()){
setPhotoForMiuiSystem(data);
}else {
setPhotoForNormalSystem(data);
}
}
}
这里需要判断当前的手机系统是不是MIUI系统:这里我直接贴上工具类

public class SystemUtils {
private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";

public static boolean isMIUI() {
try {
final BuildProperties prop = BuildProperties.newInstance();
return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null;
} catch (final IOException e) {
return false;
}
}

public static class BuildProperties {

private final Properties properties;

private BuildProperties() throws IOException {
properties = new Properties();
properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
}

public boolean containsKey(final Object key) {
return properties.containsKey(key);
}

public boolean containsValue(final Object value) {
return properties.containsValue(value);
}

public Set<Map.Entry<Object, Object>> entrySet() {
return properties.entrySet();
}

public String getProperty(final String name) {
return properties.getProperty(name);
}

public String getProperty(final String name, final String defaultValue) {
return properties.getProperty(name, defaultValue);
}

public boolean isEmpty() {
return properties.isEmpty();
}

public Enumeration<Object> keys() {
return properties.keys();
}

public Set<Object> keySet() {
return properties.keySet();
}

public int size() {
return properties.size();
}

public Collection<Object> values() {
return properties.values();
}

public static BuildProperties newInstance() throws IOException {
return new BuildProperties();
}

}
}

以及针对MIUI系统的相册选择:

/**
* MIUI系统的相册选择
* @param data
*/
private void setPhotoForMiuiSystem(Intent data) {
Uri localUri = data.getData();
String scheme = localUri.getScheme();
String imagePath = "";
if("content".equals(scheme)){
String[] filePathColumns = {MediaStore.Images.Media.DATA};
Cursor c = getContentResolver().query(localUri, filePathColumns, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePathColumns[0]);
imagePath = c.getString(columnIndex);
c.close();
}else if("file".equals(scheme)){//小米4选择云相册中的图片是根据此方法获得路径
imagePath = localUri.getPath();
}
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
imageview.setImageBitmap(bitmap);
}
针对其他非小米手机的图片选择:

/**
* 其他系统的相册选择
* @param data
*/
private void setPhotoForNormalSystem(Intent data) {
String filePath = getRealPathFromURI(data.getData());
<pre name="code" class="java" style="font-size: 13.3333px;"><span style="white-space:pre">	</span>Bitmap bitmap = BitmapFactory.decodeFile(<span style="font-size: 13.3333px; font-family: Arial, Helvetica, sans-serif;">filePath</span><span style="font-size: 13.3333px; font-family: Arial, Helvetica, sans-serif;">);</span>
imageview.setImageBitmap(bitmap); }


/**
* 解析Intent.getdata()得到的uri为String型的filePath
* @param contentUri
* @return
*/
public String getRealPathFromURI(Uri contentUri){
String[] proj = { MediaStore.Audio.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}


这样就大功告成了,不过我在写博客的时候出现了FileNotFoundException,提示我:EACCES (Permission denied);可是我明明已经在manifest里申请了读写权限,后来经各种Google发现在api 23+的时候不仅需要在manifest中申请权限,在代码中也要添加。
public class PermissionsUtils {
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};

/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission
.WRITE_EXTERNAL_STORAGE);

if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
使用起来就很方便了:

if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
PermissionsUtils.verifyStoragePermissions(this);
}


其实这只是适配小米而且,安卓机型那么多,谁知道还会出现什么问题,所以最好还是自己写个相册,我也在写希望能坚持写完吧。

Demo的地址:
http://download.csdn.net/detail/lizhiying61f/9634016
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐