华为机型cordova-plugin-image-picker读取图库闪退
在测试cordova开发的安卓APP过程中,使用$cordovaImagePicker.getPictures(options)获取相册照片时,华为机型总是会闪退。
config.xml已经添加了权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
如果先调用相机$cordovaCamera.getPicture(options)弹出权限申请,赋予权限后再调用$cordovaImagePicker.getPictures(options)就不会闪退。
查看了一下调用相机插件cordova-plugin-camera源码org.apache.cordova.camera.CameraLauncher中的方法callTakePicture,可知其做了权限的检测,源码如下:
/**
* Take a picture with the camera.
* When an image is captured or the camera view is cancelled, the result is returned
* in CordovaActivity.onActivityResult, which forwards the result to this.onActivityResult.
*
* The image can either be returned as a base64 string or a URI that points to the file.
* To display base64 string in an img tag, set the source to:
* img.src="data:image/jpeg;base64,"+result;
* or to display URI in an img tag
* img.src=result;
*
* @param returnType Set the type of image to return.
* @param encodingType Compression quality hint (0-100: 0=low quality & high compression, 100=compress of max quality)
*/
public void callTakePicture(int returnType, int encodingType) {
boolean saveAlbumPermission = PermissionHelper.hasPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
boolean takePicturePermission = PermissionHelper.hasPermission(this, Manifest.permission.CAMERA); // CB-10120: The CAMERA permission does not need to be requested unless it is declared
// in AndroidManifest.xml. This plugin does not declare it, but others may and so we must
// check the package info to determine if the permission is present. if (!takePicturePermission) {
takePicturePermission = true;
try {
PackageManager packageManager = this.cordova.getActivity().getPackageManager();
String[] permissionsInPackage = packageManager.getPackageInfo(this.cordova.getActivity().getPackageName(), PackageManager.GET_PERMISSIONS).requestedPermissions;
if (permissionsInPackage != null) {
for (String permission : permissionsInPackage) {
if (permission.equals(Manifest.permission.CAMERA)) {
takePicturePermission = false;
break;
}
}
}
} catch (NameNotFoundException e) {
// We are requesting the info for our package, so this should
// never be caught
}
} if (takePicturePermission && saveAlbumPermission) {
takePicture(returnType, encodingType);
} else if (saveAlbumPermission && !takePicturePermission) {
PermissionHelper.requestPermission(this, TAKE_PIC_SEC, Manifest.permission.CAMERA);
} else if (!saveAlbumPermission && takePicturePermission) {
PermissionHelper.requestPermission(this, TAKE_PIC_SEC, Manifest.permission.READ_EXTERNAL_STORAGE);
} else {
PermissionHelper.requestPermissions(this, TAKE_PIC_SEC, permissions);
}
}
然后又查看了一下cordova-plugin-image-picker插件com.synconset.ImagePicker.java的源码发现方法execute没有做权限检测直接执行this.cordova.startActivityForResult((CordovaPlugin) this, intent, 0)方法,而这个方法最终调用的是android.app.Activity.java中的startActivityForResult(intent, requestCode)方法。
android.app.Activity.java中startActivityForResult方法的源码:
/**
* Same as calling {@link #startActivityForResult(Intent, int, Bundle)}
* with no options.
*
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
* onActivityResult() when the activity exits.
*
* @throws android.content.ActivityNotFoundException
*
* @see #startActivity
*/
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
可以看到这个方法加了@RequiresPermission,所以在没有权限的情况下直接调用可能会被拒绝。
所以需要在调用前申请权限。
解决:
这是com.synconset.ImagePicker.java插件源码:
/**
* An Image Picker Plugin for Cordova/PhoneGap.
*/
package com.synconset; import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin; import org.apache.cordova.PermissionHelper;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; import java.util.ArrayList; import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.util.Log; public class ImagePicker extends CordovaPlugin {
public static String TAG = "ImagePicker"; private CallbackContext callbackContext;
private JSONObject params; public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
this.callbackContext = callbackContext;
this.params = args.getJSONObject(0);
if (action.equals("getPictures")) {
Intent intent = new Intent(cordova.getActivity(), MultiImageChooserActivity.class);
int max = 20;
int desiredWidth = 0;
int desiredHeight = 0;
int quality = 100;
if (this.params.has("maximumImagesCount")) {
max = this.params.getInt("maximumImagesCount");
}
if (this.params.has("width")) {
desiredWidth = this.params.getInt("width");
}
if (this.params.has("height")) {
desiredHeight = this.params.getInt("height");
}
if (this.params.has("quality")) {
quality = this.params.getInt("quality");
}
intent.putExtra("MAX_IMAGES", max);
intent.putExtra("WIDTH", desiredWidth);
intent.putExtra("HEIGHT", desiredHeight);
intent.putExtra("QUALITY", quality); if (this.cordova != null) {
this.cordova.startActivityForResult((CordovaPlugin) this, intent, 0);
}
}
return true;
} public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && data != null) {
ArrayList<String> fileNames = data.getStringArrayListExtra("MULTIPLEFILENAMES");
JSONArray res = new JSONArray(fileNames);
this.callbackContext.success(res);
} else if (resultCode == Activity.RESULT_CANCELED && data != null) {
String error = data.getStringExtra("ERRORMESSAGE");
this.callbackContext.error(error);
} else if (resultCode == Activity.RESULT_CANCELED) {
JSONArray res = new JSONArray();
this.callbackContext.success(res);
} else {
this.callbackContext.error("No images selected");
}
}
}
这是我修改后添加了权限申请的代码:
/**
* An Image Picker Plugin for Cordova/PhoneGap.
*/
package com.synconset; import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin; import org.apache.cordova.PermissionHelper;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; import java.util.ArrayList; import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.util.Log; public class ImagePicker extends CordovaPlugin {
public static String TAG = "ImagePicker"; private CallbackContext callbackContext;
private JSONObject params; public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
this.callbackContext = callbackContext;
this.params = args.getJSONObject(0);
if (action.equals("getPictures")) {
Intent intent = new Intent(cordova.getActivity(), MultiImageChooserActivity.class);
int max = 20;
int desiredWidth = 0;
int desiredHeight = 0;
int quality = 100;
if (this.params.has("maximumImagesCount")) {
max = this.params.getInt("maximumImagesCount");
}
if (this.params.has("width")) {
desiredWidth = this.params.getInt("width");
}
if (this.params.has("height")) {
desiredHeight = this.params.getInt("height");
}
if (this.params.has("quality")) {
quality = this.params.getInt("quality");
}
intent.putExtra("MAX_IMAGES", max);
intent.putExtra("WIDTH", desiredWidth);
intent.putExtra("HEIGHT", desiredHeight);
intent.putExtra("QUALITY", quality);
//添加权限申请
boolean saveAlbumPermission = PermissionHelper.hasPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if(!saveAlbumPermission){
PermissionHelper.requestPermission(this, 0, Manifest.permission.READ_EXTERNAL_STORAGE);
}else{
if (this.cordova != null) {
this.cordova.startActivityForResult((CordovaPlugin) this, intent, 0);
}
}
}
return true;
} public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && data != null) {
ArrayList<String> fileNames = data.getStringArrayListExtra("MULTIPLEFILENAMES");
JSONArray res = new JSONArray(fileNames);
this.callbackContext.success(res);
} else if (resultCode == Activity.RESULT_CANCELED && data != null) {
String error = data.getStringExtra("ERRORMESSAGE");
this.callbackContext.error(error);
} else if (resultCode == Activity.RESULT_CANCELED) {
JSONArray res = new JSONArray();
this.callbackContext.success(res);
} else {
this.callbackContext.error("No images selected");
}
}
}
这样问题就解决了。
华为机型cordova-plugin-image-picker读取图库闪退的更多相关文章
- android开发针对小米、三星、华为8.0+系统个别型号打开应用闪退
最近开发中有个别客户反馈新换的三星.小米或者华为手机打开应用就闪退,而且是个别型号.针对这种情况特别查阅了一些资料,原因是8.0+系统的手机不允许后台创建服务,那么怎么修改呢,请看代码: 1.修改启动 ...
- cordova+vue打包ios调用相机闪退解决
cordova+vue项目打包android,打开相机正常使用,但是打包ios后,需要多几个配置,才能打开,否则当调用的时候会闪退,上配置图 需要在选中的文件里面添加 <key>NSCam ...
- [Cordova] Plugin开发入门
[Cordova] Plugin开发入门 Overview Cordova的设计概念,是在APP上透过Web控件来呈现Web页面,让Web开发人员可以操作熟悉的语言.工具来开发APP.使用Web页面来 ...
- [Cordova] Plugin里使用iOS Framework
[Cordova] Plugin里使用iOS Framework 前言 开发Cordova Plugin的时候,在Native Code里使用第三方Library,除了可以加速项目的时程.也避免了重复 ...
- [Cordova] Plugin开发架构
[Cordova] Plugin开发架构 问题情景 开发Cordova Plugin的时候,侦错Native Code是一件让人困扰的事情,因为Cordova所提供的错误讯息并没有那么的完整.常常需要 ...
- [Cordova] Plugin里使用Android Library
[Cordova] Plugin里使用Android Library 前言 开发Cordova Plugin的时候,在Native Code里使用第三方Library,除了可以加速项目的时程.也避免了 ...
- cordova plugin数据传递概要
cordova plugin数据传递概要: 1.调用pluginManager向所有插件发送消息: PluginManager.postMessage(String id, Object data); ...
- ionic cordova plugin simple demo
要用cordova plugin 的话还是需要设置一下的 1. 下载 ng-cordova.js download the zip file here 2. 在index.html 中引用 (cord ...
- 在meteor中如何使用ionic组件tabs,及如何添加使用cordova plugin inappbrower
更新框架: meteor update meteor框架的优点不言而喻,它大大减轻了App前后端开发的负担,今年5月又获得B轮2000万融资,代表了市场对它一个免费.开源开发框架的肯定.cordova ...
随机推荐
- ditto复制增强
1.下载 http://ditto-cp.sourceforge.net/ 2.用法 ctrl+` ctrl+数字 或者 ctrl +` 然后用鼠标选择 soeasy
- qt无法使用终端启动的解决方法
在Terminal中直接输入命令就能打开QtCreator, i.e. ~$ qtcreator 就可以打开Qt Creator了. 想完成这个功能的原因是,一般在Linux下打命令比较方便,而师兄给 ...
- 【转】Linux中常见问题(磁盘 定时任务)
[转]Linux中常见问题(磁盘 定时任务) 第1章 linux无法上网 1) 第一步,先ping域名. ping www.baidu.com 2)再ping一个公网ip , ping 223 ...
- 反向代理负载均衡之APACHE
反向代理负载均衡之APACHE 一.反向代理1.1 介绍反响代理 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将 ...
- Day6-------------ext4文件系统
1.cp /etc/passwd /sdb6 把/etc/passwd的内容写入 sdb6 写入过程:日志------------>刷到硬盘 2.ext4已经有点过时 xfs:可存海量数据 bt ...
- CSS和DIV
DIV主要就是结合CSS使用来对网页进行布局: CSS可以通过单独建立一个.css的文件来使用<link type="text/css" href="1.css& ...
- Hibernate 常用jar包 分析
antlr-2.7.6.jar的作用 ANTLR (ANother Tool for Language Recognition) 是一个PCCTS制定的语言工具,它为他创建认定者,程序编译者,翻译者提 ...
- dispatchers 设置
Oracle连接方式(dispatchers 设置) oracle 响应客户端请求有两种方式: 1 专有连接:用一个服务器进程响应一个客户端请求 2 共享连接:用一个分派器(dispatcher)响应 ...
- 线段树解LIS
先是nlogn的LIS解法 /* LIS nlogn解法 */ #include<iostream> #include<cstring> #include<cstdio& ...
- hdu3255扫描线:带权面积交转体积交
手贱把i打成j,调了半天 /* 面积并转体积并,长方体高度为作物价格 算体积并:在笛卡尔坐标系的y轴上建立线段树cnt记录区间被完全覆盖的次数,sum记录区间被覆盖的总长度 以平行于xoy的平面从下往 ...