Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cordova配置(WebApp混合开发环境)&&Hbuilder打包配置 #48

Closed
Wscats opened this issue Jul 23, 2016 · 5 comments
Closed

Cordova配置(WebApp混合开发环境)&&Hbuilder打包配置 #48

Wscats opened this issue Jul 23, 2016 · 5 comments
Labels

Comments

@Wscats
Copy link
Owner

Wscats commented Jul 23, 2016

必备环境安装

1.配置JDK和Gradle环境

用的是1.8的版本,网上很多地方可以下载,这里不上链接了
在本地配置sdk变量,如图,点击桌面(计算机)->右键属性->高级系统设置->系统属性面板高级->点击环境变量->在下面框中的系统变量中新建
这里写图片描述

JAVA_HOME          D:\Program Files\Java\jdk1.8.0_112//这个路径根据你安装JDK的环境对应其地址
PATH                      %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;//PATH本来是有内容的,不要全部替换,用分号隔开,再往后继续添加
CLASSPATH            .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar//注意不要漏了前面的点

//新版本需要配置如下Gradle环境
GRADLE_HOME      D:\Android_Studio\gradle\gradle-2.14.1-all //指向gradle的已解压文件的根目录配置path:
PATH                      %GRADLE_HOME%\bin //继续往PATH后面添加环境变量

2.下载Android SDK

推荐国内的android-studio下载
然后配置Android SDK环境,ANDROID_HOME定位到你的SDK文件夹的根目录

ANDROID_HOME     D://android-sdk-windows     //对应你的SDK文件夹的目录

重启电脑

Cordova安装

1.下载Node.js

node官网

2.在mac终端运行下面命令,输入密码安装cordova

sudo npm install -g cordova

如果是Window系统,去掉sudo

npm install -g cordova

这里写图片描述
sudo是因为需要管理员权限,-g是全局安装
cordvoa官网命令行帮助

3.执行以下代码创建一个cordvoa应用

cordova create hello com.example.hello HelloWorld

第一个参数是文件目录,第二个参数是app id, 第三个参数是显示的title
这里写图片描述

IOS打包

4.定位到hello目录文件夹,为项目安装平台模块

cd hello
cordova platform add ios

这里写图片描述

5.打开xcodeproj项目的文件位置双击打开,如果已安装Xcode就能顺利的打开项目了

hello/platform/ios/
这里写图片描述

6.可以用编写html项目的IDE打开www下的index.html查看效果,在浏览器打开即可

这里写图片描述

7.在Xcode打开iOS 模拟器如果看到以下效果说明环境已经搭建成功

这里写图片描述

ANDROID打包

续前面三步

4.定位到hello目录文件夹,为项目安装平台模块

cd hello
cordova platform add android

5.生成APK文件

cordova build android

image
遇到这个问题就是gradle下载失败了,可以尝试拿图中的链接手动下载然后把它放到对应的系统文件下,如下,注意版本一定要对应上

C:\Users\Administrator\.gradle\wrapper\dists\gradle-2.14.1-all\4cj8p00t3e5ni9e8iofg8ghvk7

image
gradle-2.14.1-all.zip下载地址
或者android-studio下载
成功就会显示如下
image
apk的目录如下:

项目路径\test\platforms\android\build\outputs\apk

6.更改应用桌面图标

在cordova生成项目的跟目录创建res文件夹
image
然后更改config.xml文件

ldpi : 36x36 px
mdpi : 48x48 px
hdpi : 72x72 px
xhdpi : 96x96 px
xxhdpi : 144x144 px
xxxhdpi : 192x192 px

<platform name="android">
        <allow-intent href="market:*" />
        <icon src="res/android/36.png" density="ldpi" />
		<icon src="res/android/48.png" density="mdpi" />
		<icon src="res/android/72.png" density="hdpi" />
		<icon src="res/android/96.png" density="xhdpi" />
		<icon src="res/android/144.png" density="xxhdpi" />
		<icon src="res/android/192.png" density="xxxhdpi" />
    </platform>

7.调用相机

cordova plugin add cordova-plugin-camera

安装成功就会在plugin出现两个文件夹cordova-plugin-cameracordova-plugin-compat
image

@Wscats Wscats added the notes label Jul 23, 2016
@Wscats Wscats changed the title Cordova配置 Cordova配置&&Ionic配置 Jul 24, 2016
@Wscats Wscats changed the title Cordova配置&&Ionic配置 Cordova配置&&Ionic配置(混合开发环境) Jul 24, 2016
@Wscats Wscats changed the title Cordova配置&&Ionic配置(混合开发环境) Cordova配置&&Ionic配置(WebApp混合开发环境) Jul 24, 2016
@Wscats
Copy link
Owner Author

Wscats commented Aug 3, 2016

其他注意事项

这里写图片描述
如果遇到我上面的情况,那就是xcode冲命名或者路径不对,因为我用了xcode-beta版本,所以我重新设置了路径就能正常使用了

@Wscats Wscats changed the title Cordova配置&&Ionic配置(WebApp混合开发环境) Cordova配置(WebApp混合开发环境) Mar 22, 2017
@Wscats
Copy link
Owner Author

Wscats commented May 15, 2017

HBuilder 打包流程

1.运行HBuilder

百度搜索HBuilder,官网下载安装包,解压,运行HBuilder.exe。注册账号,并登陆
image

2.新建App

在左边右键,选择新建APP,或者点击中间的新建app
image

3.填入信息

在弹出的窗口,填应用名称,根据需求选择项目位置,以及模板内容,注意名字不要带有@等特殊字符,最后点击完成
image

4.真机调试

创建好之后,选择刚刚创建好的项目,在顶部选择运行,根据你的情况现在运行方式
image

5.真机演示

这是我刚刚选择的模板app展示,功能齐全,基本涵盖安卓常用的底层接口,如摄像头,地图,震动,下载等功能
这里写图片描述

6.打包成app

选择要打包的项目,在顶部选择运行,发布原生APK安装包
image

7.云端打包

在弹出的窗口,选择相应证书,如果参数配置未完成,点击顶部参数配置
image

8.图标配置

上传图标,如果不想逐个逐个图标替换,我们可以点击下方生成并替换
image

9.参数配置

这里的SDK配置选项要填上去才能打包,你可以暂时随机填一些乱串上去,最后就是保证所有提醒红叉的地方都要填满,微信登录,微信支付和微信消息及朋友圈的appid三者要统一,其他在测试时可随意

image

  • 1,配置相应的app入口位置,app名称,版本
  • 2,配置图标
  • 3,配置启动图片
  • 4,sdk配置(可选,如果需要同步登录,需配置相应的参数,获得相应的参数需到相应的开放平台申请)

10.打包成app---选择要打包的项目,在顶部选择运行,发型原生安装包

image

11.云端打包

在弹出的窗口,选择相应证书,如果参数配置未完成,点击顶部参数配置,如果配置完成,点击底部打包
image

12.稍等一会儿

image
image

13.如果刚刚不小心关闭了,或者后面某天想找到打包的App,在顶部选择运行,根据需要选择查看。发送到手机上,安装试试

image

@Wscats
Copy link
Owner Author

Wscats commented May 15, 2017

其他注意事项

真机调试过程中,如果出现如下错误提醒

安装失败,失败原因:Failure [INSTALL_CANCELED_BY_USER] 
请手动点亮手机屏幕,并重新运行真机调试,注:可能需要在手机上确认安装。

勾选了以下几个选项就可以调试了
image

调用plus

之前试过用Vue写的项目,用hbuilder打包APP,在页面第一次加载的时候无法获取cookie,storage等
后来发现原来是一定要plus加载完毕之后才能获取对应的信息,所以如果用了其他框架写的项目不要直接加载对应的JS,可以改成这样

function plusReady() {
    var script = document.createElement("script");
    script.src = "main-fa9faab1705d2e80a7c5.js";//项目的JS
    document.body.appendChild(script);
    console.log(plus.storage.getItem("token"))
}
document.addEventListener("plusready", plusReady, false);//等待plus准备就绪在加载

H5+支付接口

这里的官方文档的支付插件配置的请求DEMO是错误的,注意是用 POST 请求,而非 GET 请求

var channel = null;
// 1. 获取支付通道
function plusReady() {
    // 获取支付通道
    plus.payment.getChannels(function (channels) {
        channel = channels[0];
    }, function (e) {
        alert("获取支付通道失败:" + e.message);
    });
}
document.addEventListener('plusready', plusReady, false);

var ALIPAYSERVER = 'http://demo.dcloud.net.cn/helloh5/payment/alipay.php';
var WXPAYSERVER = 'http://demo.dcloud.net.cn/helloh5/payment/wxpay.php';
// 2. 发起支付请求
function pay(id) {
    // 从服务器请求支付订单
    var PAYSERVER = '';
    if (id == 'alipay') {
        PAYSERVER = ALIPAYSERVER;
    } else if (id == 'wxpay') {
        PAYSERVER = WXPAYSERVER;
    } else {
        plus.nativeUI.alert("不支持此支付通道!", null, "捐赠");
        return;
    }
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        switch (xhr.readyState) {
            case 4:
                if (xhr.status == 200) {
                    plus.payment.request(channel, xhr.responseText, function (result) {
                        plus.nativeUI.alert("支付成功!", function () {
                            back();
                        });
                    }, function (error) {
                        plus.nativeUI.alert("支付失败:" + error.code);
                    });
                } else {
                    alert("获取订单信息失败!");
                }
                break;
            default:
                break;
        }
    }
    xhr.open('POST', PAYSERVER);
    //如果是POST请求方式,设置请求首部信息
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhr.send("total=0.01");
}

@Wscats Wscats changed the title Cordova配置(WebApp混合开发环境) Cordova配置(WebApp混合开发环境)&&Hbuilder打包配置 May 15, 2017
@Wscats
Copy link
Owner Author

Wscats commented Dec 15, 2018

调用定位

调用定位可选用这个方法plus.geolocation.getCurrentPosition

location() {
    var that = this;
    if (window.plus) {
        plus.geolocation.getCurrentPosition(
            function (p) {
                that.latitude = p.coords.latitude;
                that.longitude = p.coords.longitude;
            },
            function (e) {
                alert("Geolocation error: " + e.message);
            }
        );
    }
}

当然我们可以把经纬度直接发到后台记录,实现实时跟踪定位

sendLocation() {
    var that = this;
    axios
        .get("http://10.3.136.180:9999/sendPostion", {
            params: {
                latitude: that.latitude,
                longitude: that.longitude
            }
        })
        .then(data => {
            console.log(data);
        })
        .catch(() => {});
}

录音

调用 plus.audio.getRecorder()获取音频对象,可以在成功的回调里面获取录音的地址

mounted() {
    this.r = plus.audio.getRecorder();
},
startRecord() {
    if (this.r == null) {
        alert("Device not ready!");
        return;
    }
    this.r.record({
            filename: "_doc/audio/"
        },
        e => {
            console.log(e);
            this.path = e;
            alert("Audio record success!");
        },
        e => {
            alert("Audio record failed: " + e.message);
        }
    );
}

播放

可以在上面把获取到的录音地址放进来用plus.audio.createPlayer(this.path)打开,然后播放音频信息,当然也可以播放其他格式的音频信息

startPlay() {
    console.log(this.path);
    if (plus.audio == undefined) {
        alert("Device not ready!");
    }
    this.p = plus.audio.createPlayer(this.path);
    this.p.play(
        function () {
            alert("Audio play success!");
        },
        function (e) {
            alert("Audio play error: " + e.message);
        }
    );
}

暂停播放

stopRecord() {
    this.r.stop();
}

上传文件

前端上传逻辑可以直接使用H5的input配合FormData格式

uploadImg() {
    var fileNode = document.getElementById("file");
    var xmlhttp = new XMLHttpRequest();
    //设置回调,当请求的状态发生变化时,就会被调用
    xmlhttp.onreadystatechange = function () {
        //上传成功,返回的文件名,设置到父节点的背景中
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            console.log(xmlhttp.responseText);
        }
    };
    //构造form数据
    var data = new FormData();
    console.log(fileNode.files);
    data.append("avatar", fileNode.files[0]);
    console.log(data);
    //设置请求,true:表示异步
    xmlhttp.open("post", "http://10.3.136.180:9999/requireImg", true);
    //不要缓存
    //xmlhttp.setRequestHeader("If-Modified-Since", "0");
    //提交请求
    xmlhttp.send(data);
    //清除掉,否则下一次选择同样的文件就进入不到onchange函数中了
    fileNode.value = null;
}
<input @change="uploadImg" type="file" id="file" name="avatar">

后端逻辑,配合 express 和 multer 模块可以获取到传过来的文件

var express = require("express");
var multer = require('multer')
var upload = multer({
    dest: 'uploads/'
})
var app = express();
app.post("/requireImg", upload.single('avatar'), (req, res) => {
    res.append("Access-Control-Allow-Origin", "*")
    res.send({
        state: "success"
    })
})
app.listen(9999)

@Wscats
Copy link
Owner Author

Wscats commented Feb 27, 2019

uni

uni-app是一个使用Vue.js开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS、Android、H5、小程序等多个平台。

目录结构

一个uni-app工程,默认包含如下目录及文件:

┌─components            uni-app组件目录
  └─comp-a.vue         可复用的a组件
├─hybrid                存放本地网页的目录,详见
├─platforms             存放各平台专用页面的目录,详见
├─pages                 业务页面文件存放的目录
  ├─index
    └─index.vue       index页面
  └─list
     └─list.vue        list页面
├─static                存放应用引用静态资源(如图片、视频等)的地方,注意:静态资源只能存放于此
├─main.js               Vue初始化入口文件
├─App.vue               应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json         配置应用名称、appid、logo、版本等打包信息
└─pages.json            配置页面路由、导航条、选项卡等页面类信息

全局样式库

可以在App.vue组件里面引入uni.css定义好的样式,配合已经写好的组件和模板快速开发

<style>
	/* uni.css - 通用组件、模板样式库,可以当作一套ui库应用 */
	@import "./common/uni.css";
</style>

应用生命周期

函数名 说明
onLaunch 当uni-app 初始化完成时触发(全局只触发一次)
onShow 当 uni-app 启动,或从后台进入前台显示
onHide 当 uni-app 从前台进入后台 浏览器页面切换时候会触发,Mac显示屏切换会触发
onUniNViewMessage 对 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯

注意

  • 应用生命周期仅可在App.vue中监听,在其它页面监听无效。
  • 在应用生命周期函数内进行页面跳转时需要注意,不要和pages.json内配置的首页打开时机冲突

页面生命周期

  • onPullDownRefresh生命周期配合enablePullDownRefresh使用

在 js 中定义onPullDownRefresh处理函数(和onLoad等生命周期函数同级),监听该页面用户下拉刷新事件。需要在pages.json里,找到的当前页面的 pages 节点,并在 style 选项中开启enablePullDownRefresh。当处理完数据刷新后,uni.stopPullDownRefresh可以停止当前页面的下拉刷新。

onPullDownRefresh() {
	setTimeout(() => {
		uni.stopPullDownRefresh()
	}, 1000)
}

触底触发的生命周期

onReachBottom() {
	console.log('到底了')
}

pages.json

配置路由和底部的tabbar,和小程序是差不多的,注意当我们在page文件夹新建页面的时候,pages.json文件的pages内容会自动添加

{
    "pages" : [
        //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
        {
            "path" : "pages/index/index",
            "style" : {
                "navigationBarTitleText" : "uni-app"
            }
        },
        {
            "path" : "pages/home/home",
            "style" : {
                "navigationBarTitleText" : "设置页"
            }
        },
        {
            "path" : "pages/detail/detail",
            "style" : {}
        }
    ],
    "globalStyle" : {
        "navigationBarTextStyle" : "black",
        "navigationBarTitleText" : "uni-app",
        "navigationBarBackgroundColor" : "#F8F8F8",
        "backgroundColor" : "#F8F8F8"
    },
    "tabBar" : {
        "color" : "#7A7E83",
        "selectedColor" : "#007AFF",
        "borderStyle" : "black",
        "backgroundColor" : "#ffffff",
        "list" : [
            {
                "pagePath" : "pages/index/index",
                "iconPath" : "static/component.png",
                "selectedIconPath" : "static/componentHL.png",
                "text" : "组件"
            },
            {
                "pagePath" : "pages/home/home",
                "iconPath" : "static/component.png",
                "selectedIconPath" : "static/componentHL.png",
                "text" : "组件"
            }
        ]
    }
}

路由跳转

声明式导航:用绝对路径或者相对当前组件的相对路径,这里的路由跳转用了绝对路径

<navigator url="/pages/detail/detail" hover-class="navigator-hover"></navigator>
<navigator url="navigate/navigate?title=navigate" hover-class="navigator-hover"></navigator>

编程式导航

// 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面。
uni.navigateTo({
    url: 'test?id=1&name=uniapp'
});
// 关闭当前页面,跳转到应用内的某个页面。
uni.redirectTo({
    url: 'test?id=1'
});
// 关闭所有页面,打开到应用内的某个页面。
uni.reLaunch({
    url: 'test?id=1'
});
// 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
uni.switchTab({
    url: '/pages/index/index'
});
// 关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层
// 此处是A页面
uni.navigateTo({
    url: 'B?id=1'
});
// 此处是B页面
uni.navigateTo({
    url: 'C?id=1'
});
// 在C页面内 navigateBack,将返回A页面
uni.navigateBack({
    delta: 2
});

组件

可以使用uni-app帮我封装好的组件,但有几个比较注意的是,组件的名字不要用一些微信小程序或者一些常用的名字,我们可以在前面加个后缀,防止无效

<template>
	<view>
		<xswiper />
		<xaudio />
		<xmediaList />
		<xmap />
	</view>
</template>
import xaudio from '../../components/audio/audio.vue'
import xmap from '../../components/map/map.vue'
import xswiper from '../../components/swiper/swiper.vue'
import xmediaList from '../../components/media-list/media-list.vue'

发起请求

可以使用uni.request发起请求

const requestUrl = "https://cnodejs.org/api/v1/topics"
const duration = 2000
export default {
	data() {
		return {
			loading: false,
			res: ""
		}
	},
	methods: {
		makeRequest: function() {
			this.loading = true
			uni.request({
				url: requestUrl,
				data: {
					noncestr: Date.now()
				},
				success: (res) => {
					uni.showToast({
						title: '请求成功',
						icon: 'success',
						mask: true,
						duration: duration
					})
					this.res = '请求结果 : ' + JSON.stringify(res);
					console.log('request success', res)
				},
				fail: (err) => {
					console.log('request fail', err);
					uni.showModal({
						content: err.errMsg,
						showCancel: false
					})
				},
				complete: () => {
					this.loading = false
				}
			})
		}
	}
}

调用微信小程序接口

这里注意要把小程序的单向数据绑定和指令改为vue的写法,也可以使用uni.createCameraContext()兼容性会更好

<template>
	<view>
		<text>text</text>
		<camera device-position="back" flash="off" binderror="error" style="width: 100%; height: 300px;"></camera>
		<button type="primary" @click="takePhoto">拍照</button>
		<view>预览</view>
		<image mode="widthFix" :src="src"></image>
	</view>
</template>
<script>
	export default {
		data() {
			return {
				src:""
			};
		},
		methods: {
			takePhoto() {
				const ctx = wx.createCameraContext()
				ctx.takePhoto({
					quality: 'high',
					success: (res) => {
						this.src = res.tempImagePath
					}
				})
			},
		}
	}
</script>

@Wscats Wscats closed this as completed Aug 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant