uni-app 离线打包安卓APP常见问题汇总

uni-app 离线打包安卓APP常见问题汇总(手机)

uni-app 离线打包总会有各种各样的坑,以下是我的分享:

支付相关

原因为:requestPayment:fail[payment微信:-1]Genernal errors
新建一个同包名的相似应用名称,微信审核成功后,去商户后台关联appid,然后微信开发平台同意授权,后台返回跟之前一样的参数,完美

四、权限问题

官方指导

三、应用管理界面,找不到选择离线打包Key管理

因为应用宝隐私保护审核变严了,之前的uniapp自动会获取mac地址等,用于数据分析,所以要换3.1.10+打包了,要appid了,技术更新得太快了,没很入坑的建议,早点下车。。。找个离线打包Key管理,都疑惑了我大半天。。可能是我太辣鸡了,居然要双击应用名称才出来,选中是没得用的。
uni-app 离线打包安卓APP常见问题汇总_第1张图片

一、播放视频功能

勾选模块

uni-app 离线打包安卓APP常见问题汇总_第2张图片

原生的放包至libs

文件:media-release.aar
uni-app 离线打包安卓APP常见问题汇总_第3张图片

二、应用设置里都显示,相机授权了,调相机也没反应

调相机功能,基座能正常运行,打包,配了权限了,且基座运行时还询问了相机权限,我还授权了,去设置里面看这个app也显示授权了,可是调相机,没有任何反应,试的都要哭了,后面发现是有个包名没有改过来,以下是处理办法:

AndroidManifest.xmlapplication节点下添加修改provider节点,${apk.applicationId}请填写自己的包名,代码和图片如下:

        <provider
            android:name="io.dcloud.common.util.DCloud_FileProvider"
            android:authorities="${apk.applicationId}.dc.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/dcloud_file_provider" />
        </provider>

uni-app 离线打包安卓APP常见问题汇总_第4张图片

赠品

离线打包的权限

需要在AndroidManifest.xmlapplication节点添加权限,代码和图片如下:

      <uses-feature android:name="android.hardware.camera" />
   <uses-feature android:name="android.hardware.camera.autofocus" />
   <!-- 摄像头权限 -->
   <uses-permission android:name="android.permission.CAMERA" />
   <!-- 开启闪光灯权限 -->
   <uses-permission android:name="android.permission.FLASHLIGHT"/>

uni-app 离线打包安卓APP常见问题汇总_第5张图片

调用相机代码

async appCamera() {
       let that = this;
       var cmr = plus.camera.getCamera(1);
       var res = cmr.supportedImageResolutions[0];
       var fmt = cmr.supportedImageFormats[0];
       let funTips = '相机';
       //是不是isAndroidOs,请在APP.vue全局赋值
       //判断是否授权,没授权跳转设置
       var iscan = await permission_app.req_Permit_any(that.isAndroidOs, permission_app.permisionID_anrd.camera,
         permission_app.permisionID_ios.camera, funTips);
       if (iscan) {
         
         cmr.captureImage((path) => {
             
             that.chooseSuccessMethod([path])
           },
           (error) => {
             //alert("Capture image failed: " + error.message);
             console.log('失败!请重新选择');
​
​
           }, {
             resolution: res,
             format: fmt
           }
         );
       }},
     async chooseSuccessMethod(filePath) {
       let that = this;
       
       let path = filePath[0] ;
       
       return path;
      
     },

引入权限封装的js

	//#ifdef APP-PLUS
 	 import permission_app from "@/permission_app.js";
  // #endif

permission_app.js:此js封装了大部分App权限判断函数,适用安卓和iOS

  /**
 * 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启
 */

var isIos
// #ifdef APP-PLUS
isIos = (plus.os.name == "iOS")
// #endif

// 判断推送权限是否开启
function judgeIosPermissionPush() {
	var result = false;
	var UIApplication = plus.ios.import("UIApplication");
	var app = UIApplication.sharedApplication();
	var enabledTypes = 0;
	if (app.currentUserNotificationSettings) {
		var settings = app.currentUserNotificationSettings();
		enabledTypes = settings.plusGetAttribute("types");
		console.log("enabledTypes1:" + enabledTypes);
		if (enabledTypes == 0) {
			console.log("推送权限没有开启");
		} else {
			result = true;
			console.log("已经开启推送功能!")
		}
		plus.ios.deleteObject(settings);
	} else {
		enabledTypes = app.enabledRemoteNotificationTypes();
		if (enabledTypes == 0) {
			console.log("推送权限没有开启!");
		} else {
			result = true;
			console.log("已经开启推送功能!")
		}
		console.log("enabledTypes2:" + enabledTypes);
	}
	plus.ios.deleteObject(app);
	plus.ios.deleteObject(UIApplication);
	return result;
}

// 判断定位权限是否开启
function judgeIosPermissionLocation() {
	var result = false;
	var cllocationManger = plus.ios.import("CLLocationManager");
	var status = cllocationManger.authorizationStatus();
	result = (status != 2)
	console.log("定位权限开启:" + result);
	// 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation
	/* var enable = cllocationManger.locationServicesEnabled();
	var status = cllocationManger.authorizationStatus();
	console.log("enable:" + enable);
	console.log("status:" + status);
	if (enable && status != 2) {
		result = true;
		console.log("手机定位服务已开启且已授予定位权限");
	} else {
		console.log("手机系统的定位没有打开或未给予定位权限");
	} */
	plus.ios.deleteObject(cllocationManger);
	return result;
}

// 判断麦克风权限是否开启
function judgeIosPermissionRecord() {
	var result = false;
	var avaudiosession = plus.ios.import("AVAudioSession");
	var avaudio = avaudiosession.sharedInstance();
	var permissionStatus = avaudio.recordPermission();
	console.log("permissionStatus:" + permissionStatus);
	if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
		console.log("麦克风权限没有开启");
	} else {
		result = true;
		console.log("麦克风权限已经开启");
	}
	plus.ios.deleteObject(avaudiosession);
	return result;
}

// 判断相机权限是否开启
function judgeIosPermissionCamera() {
	var result = false;
	var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
	var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
	console.log("authStatus:" + authStatus);
	if (authStatus == 3) {
		result = true;
		console.log("相机权限已经开启");
	} else {
		console.log("相机权限没有开启");
	}
	plus.ios.deleteObject(AVCaptureDevice);
	return result;
}

// 判断相册权限是否开启
function judgeIosPermissionPhotoLibrary() {
	var result = false;
	var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
	var authStatus = PHPhotoLibrary.authorizationStatus();
	console.log("authStatus:" + authStatus);
	if (authStatus == 3) {
		result = true;
		console.log("相册权限已经开启");
	} else {
		console.log("相册权限没有开启");
	}
	plus.ios.deleteObject(PHPhotoLibrary);
	return result;
}

// 判断通讯录权限是否开启
function judgeIosPermissionContact() {
	var result = false;
	var CNContactStore = plus.ios.import("CNContactStore");
	var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
	if (cnAuthStatus == 3) {
		result = true;
		console.log("通讯录权限已经开启");
	} else {
		console.log("通讯录权限没有开启");
	}
	plus.ios.deleteObject(CNContactStore);
	return result;
}

// 判断日历权限是否开启
function judgeIosPermissionCalendar() {
	var result = false;
	var EKEventStore = plus.ios.import("EKEventStore");
	var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
	if (ekAuthStatus == 3) {
		result = true;
		console.log("日历权限已经开启");
	} else {
		console.log("日历权限没有开启");
	}
	plus.ios.deleteObject(EKEventStore);
	return result;
}

// 判断备忘录权限是否开启
function judgeIosPermissionMemo() {
	var result = false;
	var EKEventStore = plus.ios.import("EKEventStore");
	var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
	if (ekAuthStatus == 3) {
		result = true;
		console.log("备忘录权限已经开启");
	} else {
		console.log("备忘录权限没有开启");
	}
	plus.ios.deleteObject(EKEventStore);
	return result;
}

// Android权限查询
function requestAndroidPermission(permissionID) {
	return new Promise((resolve, reject) => {
		plus.android.requestPermissions(
			[permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
			function(resultObj) {
				var result = 0;
				for (var i = 0; i < resultObj.granted.length; i++) {
					var grantedPermission = resultObj.granted[i];
					console.log('已获取的权限:' + grantedPermission);
					result = 1
				}
				for (var i = 0; i < resultObj.deniedPresent.length; i++) {
					var deniedPresentPermission = resultObj.deniedPresent[i];
					console.log('拒绝本次申请的权限:' + deniedPresentPermission);
					result = 0
				}
				for (var i = 0; i < resultObj.deniedAlways.length; i++) {
					var deniedAlwaysPermission = resultObj.deniedAlways[i];
					console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
					result = -1
				}
				resolve(result);
				// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
				// if (result != 1) {
				// gotoAppPermissionSetting()
				// }
			},
			function(error) {
				console.log('申请权限错误:' + error.code + " = " + error.message);
				resolve({
					code: error.code,
					message: error.message
				});
			}
		);
	});
}

// 使用一个方法,根据参数判断权限
function judgeIosPermission(permissionID) {
	if (permissionID == "location") {
		return judgeIosPermissionLocation()
	} else if (permissionID == "camera") {
		return judgeIosPermissionCamera()
	} else if (permissionID == "photoLibrary") {
		return judgeIosPermissionPhotoLibrary()
	} else if (permissionID == "record") {
		return judgeIosPermissionRecord()
	} else if (permissionID == "push") {
		return judgeIosPermissionPush()
	} else if (permissionID == "contact") {
		return judgeIosPermissionContact()
	} else if (permissionID == "calendar") {
		return judgeIosPermissionCalendar()
	} else if (permissionID == "memo") {
		return judgeIosPermissionMemo()
	}
	return false;
}

// 跳转到**应用**的权限页面
function gotoAppPermissionSetting() {
	if (isIos) {
		var UIApplication = plus.ios.import("UIApplication");
		var application2 = UIApplication.sharedApplication();
		var NSURL2 = plus.ios.import("NSURL");
		// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");		
		var setting2 = NSURL2.URLWithString("app-settings:");
		application2.openURL(setting2);

		plus.ios.deleteObject(setting2);
		plus.ios.deleteObject(NSURL2);
		plus.ios.deleteObject(application2);
	} else {
		// console.log(plus.device.vendor);
		var Intent = plus.android.importClass("android.content.Intent");
		var Settings = plus.android.importClass("android.provider.Settings");
		var Uri = plus.android.importClass("android.net.Uri");
		var mainActivity = plus.android.runtimeMainActivity();
		var intent = new Intent();
		intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
		var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
		intent.setData(uri);
		mainActivity.startActivity(intent);
	}
}

// 检查系统的设备服务是否开启
// var checkSystemEnableLocation = async function () {
function checkSystemEnableLocation() {
	if (isIos) {
		var result = false;
		var cllocationManger = plus.ios.import("CLLocationManager");
		var result = cllocationManger.locationServicesEnabled();
		console.log("系统定位开启:" + result);
		plus.ios.deleteObject(cllocationManger);
		return result;
	} else {
		var context = plus.android.importClass("android.content.Context");
		var locationManager = plus.android.importClass("android.location.LocationManager");
		var main = plus.android.runtimeMainActivity();
		var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
		var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER);
		console.log("系统定位开启:" + result);
		return result
	}
}
const go_locatin = () => {
	uni.showModal({
		title: '提示',
		content: '请打开定位服务',
		confirmText: '去设置',
		success: ({
			confirm,
			cancel
		}) => {

			if (confirm) {
				// android平台
				if (uni.getSystemInfoSync().platform == 'android') {
					var Intent = plus.android.importClass('android.content.Intent');
					var Settings = plus.android.importClass('android.provider.Settings');
					var intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
					var main = plus.android.runtimeMainActivity();
					main.startActivity(intent); // 打开系统设置GPS服务页面
				}

				// ios平台
				if (uni.getSystemInfoSync().platform == 'ios') {
					var UIApplication = plus.ios.import("UIApplication");
					var application2 = UIApplication.sharedApplication();
					var NSURL2 = plus.ios.import("NSURL");
					var setting2 = NSURL2.URLWithString("App-Prefs:root=Privacy&path=LOCATION");
					application2.openURL(setting2);
					plus.ios.deleteObject(setting2);
					plus.ios.deleteObject(NSURL2);
					plus.ios.deleteObject(application2);
				}
			}

			// 用户取消前往开启定位服务
			if (cancel) {
				// do sth...
			}
		}
	});
}

const go_any = (settingTips) => {
	uni.showModal({
		title: '提示',
		content: '请允许"' + settingTips + '"服务',
		confirmText: '去设置',
		success: ({
			confirm,
			cancel
		}) => {

			if (confirm) {
				// android平台
				if (uni.getSystemInfoSync().platform == 'android') {
					var Intent = plus.android.importClass('android.content.Intent');
					var Settings = plus.android.importClass('android.provider.Settings');
					var intent = new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
					var main = plus.android.runtimeMainActivity();
					main.startActivity(intent); // 打开服务页面
				}

				// ios平台
				if (uni.getSystemInfoSync().platform == 'ios') {
					var UIApplication = plus.ios.import("UIApplication");
					var application2 = UIApplication.sharedApplication();
					var NSURL2 = plus.ios.import("NSURL");
					//
					var setting2 = NSURL2.URLWithString("App-Prefs:root=Photos");
					application2.openURL(setting2);
					plus.ios.deleteObject(setting2);
					plus.ios.deleteObject(NSURL2);
					plus.ios.deleteObject(application2);
				}
			}

			// 用户取消前往开启定位服务
			if (cancel) {
				// do sth...
			}
		}
	});
}

const go_AppSetting = (settingTips) => {
	uni.showModal({
		title: '提示',
		content: '请允许' + settingTips + '服务',
		confirmText: '去设置',
		success: ({
			confirm,
			cancel
		}) => {

			if (confirm) {
				gotoAppPermissionSetting();
			}

			// 用户取消前往开启定位服务
			if (cancel) {
				// do sth...
			}
		}
	});
}

const permisionID_ios = {
	location: 'location', //位置权限
	camera: 'camera', //摄像头权限camera
	call_phone: '', //拨打电话权限,ios勿需授权
	read_img: 'photoLibrary', //相册权限photoLibrary
}

const permisionID_anrd = {
	location: 'android.permission.ACCESS_FINE_LOCATION', //位置权限
	camera: 'android.permission.CAMERA', //摄像头权限
	call_phone: 'android.permission.CALL_PHONE', //拨打电话权限
	read_img: 'android.permission.READ_EXTERNAL_STORAGE',
}

function req_Permit_any(isAndroid, p_ID_anrd, p_ID_ios, settingTips) {
	return new Promise((resolve, reject) => {
		if (isAndroid) {
			plus.android.requestPermissions(
				[p_ID_anrd], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
				function(resultObj) {
					let iscan = false;
					//var result = 0;
					for (var i = 0; i < resultObj.granted.length; i++) {
						var grantedPermission = resultObj.granted[i];
						console.log('已获取的权限:' + grantedPermission);
						//result = 1
						iscan = true;
					}
					for (var i = 0; i < resultObj.deniedPresent.length; i++) {
						var deniedPresentPermission = resultObj.deniedPresent[i];
						console.log('拒绝本次申请的权限:' + deniedPresentPermission);
						//result = 0
					}
					for (var i = 0; i < resultObj.deniedAlways.length; i++) {
						var deniedAlwaysPermission = resultObj.deniedAlways[i];
						console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
						//result = -1
					}
					//resolve(result);
					// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
					if (!iscan) {
						go_AppSetting(settingTips)
					}
					resolve(iscan);

				},
				function(error) {
					console.log('申请权限错误:' + error.code + " = " + error.message);
					resolve({
						code: error.code,
						message: error.message
					});
				}
			);

		} else {
			let iscan = false;
			if (p_ID_ios.length > 0) {
				let isOnce = true;
				//苹果手机第一次判断了就不自动谈弹出系统框,设置里面不会有
				try {
					let auth_name = p_ID_ios + '_auth_ios';
					const auth = uni.getStorageSync(auth_name);
					if (auth) {
						isOnce = false;
					} else {
						isOnce = true;
					}
					if (!isOnce) {
						iscan = judgeIosPermission(p_ID_ios);
						if (!iscan) {
							go_AppSetting(settingTips)
						} else {
							iscan = true;
						}
					} else {
						iscan = true;
						uni.setStorage({
							key: auth_name,
							data: 'authed',
							success: function() {
								console.log('success');
							}
						});
					}
				} catch (e) {
					// error

				}


			} else {
				iscan = true;
			}

			resolve(iscan);
		}
	});
}

function req_Permit_locatin(isAndroid) {
	return new Promise((resolve, reject) => {
		//检查系统定位服务是否开启
		if (checkSystemEnableLocation()) {
			let p_ID_anrd = permisionID_anrd.location;
			let p_ID_ios = permisionID_ios.location;
			let settingTips = '定位';
			if (isAndroid) {
				plus.android.requestPermissions(
					[p_ID_anrd], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
					function(resultObj) {
						let iscan = false;
						//var result = 0;
						for (var i = 0; i < resultObj.granted.length; i++) {
							var grantedPermission = resultObj.granted[i];
							console.log('已获取的权限:' + grantedPermission);
							//result = 1
							iscan = true;
						}
						for (var i = 0; i < resultObj.deniedPresent.length; i++) {
							var deniedPresentPermission = resultObj.deniedPresent[i];
							console.log('拒绝本次申请的权限:' + deniedPresentPermission);
							//result = 0
						}
						for (var i = 0; i < resultObj.deniedAlways.length; i++) {
							var deniedAlwaysPermission = resultObj.deniedAlways[i];
							console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
							//result = -1
						}
						//resolve(result);
						// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
						if (!iscan) {
							//go_locatin()
							go_AppSetting(settingTips)
						}
						resolve(iscan);

					},
					function(error) {
						console.log('申请权限错误:' + error.code + " = " + error.message);
						resolve({
							code: error.code,
							message: error.message
						});
					}
				);

			} else {
				let iscan = false;
				iscan = judgeIosPermission(p_ID_ios);
				if (!iscan) {
					//go_locatin()
					go_AppSetting(settingTips)
				}
				resolve(iscan);
			}

		} else {
			uni.showModal({
				title: '提示',
				content: '请打开"系统"定位服务',
				showCancel: false,
				success: function(res) {
					if (res.confirm) {
						//console.log('用户点击确定');
					}
				}
			});

			let iscan = false;
			resolve(iscan);
		}
	});
}


module.exports = {
	judgeIosPermission: judgeIosPermission,
	requestAndroidPermission: requestAndroidPermission,
	checkSystemEnableLocation: checkSystemEnableLocation,
	gotoAppPermissionSetting: gotoAppPermissionSetting,
	permisionID_anrd,
	permisionID_ios,
	go_locatin,
	go_any,
	go_AppSetting,
	req_Permit_any,
	req_Permit_locatin,
}

有疑问

微信小程序联系客服,及时沟通
地图轨迹预览效果

扫描公众号,了解更多实例分享:
实例分享

参考

离线打包相机配置
权限js封装
安卓相机

你可能感兴趣的:(uniapp,Android,Studio)