设为首页 收藏本站
查看: 921|回复: 0

[经验分享] 华为机型cordova-plugin-image-picker读取图库闪退

[复制链接]

尚未签到

发表于 2017-7-10 11:44:27 | 显示全部楼层 |阅读模式
  在测试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");
}
}
}
  这样问题就解决了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-392322-1-1.html 上篇帖子: 任正非:华为不开放就要死亡 不能建立封闭系统 下篇帖子: 华为交换机MSTP+VRRP配置实例说明文档
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表