APICloud开发记录手册

APICloud开发记录【持续】

1、开发要求

Web Storm 2018.1

2、创建项目

2.1 WebStorm插件操作

(1) 除了IOS一块,其余均建议阅读并操作
在这里插入图片描述

(2) 将webStorm-APICloud加入到项目中
在这里插入图片描述

(3) 安装好需要的插件
在这里插入图片描述
在这里插入图片描述

2.2 网页创建

具体创建应用操作步骤:https://docs.apicloud.com/APICloud/creating-first-app

2.3 下载代码

(1) 采用SVN下载代码,然后导入到Web Storm
在这里插入图片描述
(2) 采用Subversion

2.4 App创建以及测试

(1) 新建一个底部导航应用
在这里插入图片描述
(2) 启动Wifi真机测试

  • 开启服务 在这里插入图片描述
  • 手机输入ip以及端口,点击连接;然后在Web Storm中右键项目,点击【Wifi真机同步】
    在这里插入图片描述

3、Api的方法

具体API:https://docs.apicloud.com/Client-API/

API.js文档:https://docs.apicloud.com/Front-end-Framework/framework-dev-guide#37

3.1 监听返回键

api.addEventListener({
            name: 'keyback'
        }, function (ret, err) {
            api.confirm({
                title: '提示',
                msg: "确认退出应用?",
                buttons: ['确定', '取消']
            }, function (ret, err) {
                var index = ret.buttonIndex;
                if (index == 1) {
                    api.closeWin();
                }
                return;
            });
        });

3.2 拨打电话

api.call({
            type: 'tel', // 直接拨打,无任何提示
            number: '10086' // 电话号码
        });

参数说明:https://docs.apicloud.com/Client-API/api#7

3.3 跨页面执行js脚本

execScript:在指定 window 或者 frame 中执行脚本,对于 frameGroup 里面的 frame 也有效,若 name 和 frameName 都未指定,则在当前 window 中执行脚本,具体执行逻辑见补充说明。

execScript({params})

4、config.xml文件说明

<?xml version="1.0" encoding="UTF-8"?><widget id="A6080528176396" version="0.0.1">
    <name>demo1_nav</name>  <!--app的名称-->
    <description>
        Example For APICloud.
    </description>
    <author email="[email protected]" href="http://www.apicloud.com">
        Developer
    </author>
    <content src="grid.html"/>  <!--默认app进入的主页地址-->
	<preference name="appBackground" value="rgba(0,0,0,0)"/>
	<preference name="windowBackground" value="rgba(0,0,0,0)"/>
	<preference name="frameBackgroundColor" value="rgba(0,0,0,0)"/>
	<preference name="autoLaunch" value="true"/>
	<preference name="autoUpdate" value="true"/>
	<preference name="smartUpdate" value="false"/>
	<preference name="debug" value="false"/>
	<preference name="statusBarAppearance" value="true"/>
	<permission name="location"/>
	<permission name="internet"/>
	<access origin="*"/>
</widget>

5、 WeiUI集成

5.1 将样式以及JS加入到项目中

  • 下载zip,将build中的weui.css样式文件加入到项目中的css文件夹中

https://github.com/lihongxun945/jquery-weui/releases

5.2 weiUI官网

  • 在WeiUi官网查看对应组件的样式,并移植到页面中

6、上拉刷新

如果页面条目过多,需要进行分页显示,用户上滑数据加载下一页数据,具体实现如下:

6.1 父页面[只有header]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo-header</title>
    <!--标准mui.css-->
    <link rel="stylesheet" href="../../css/mui.min.css">
    <!--App自定义的css-->
    <link rel="stylesheet" type="text/css" href="../../css/app.css"/>
    <link rel="stylesheet" type="text/css" href="../../css/my.css"/>
</head>
<body>
<header class="mui-bar mui-bar-nav" id="topbar">
    <a class="  mui-icon mui-icon-left-nav mui-pull-left" href="#" onclick="goBeforePage()"></a>
    <h1 class="mui-title" id="title">示例</h1>
</header>

<div class="mui-content">
    <ul class="mui-table-view mui-table-view-chevron" id="showResult">


    </ul>
</div>
<script src="../../js/mui.js"></script>
<script type="text/javascript" src="../../script/api.js"></script>
<script type="text/javascript" src="../../js/request.js"></script>
<script type="text/javascript" src="../../js/dot.min.js"></script>
<script type="text/javascript" src="../../js/toastUtils.js"></script>
<script type="text/javascript" src="../../js/error.js"></script>
<script type="text/javascript">
 
    apiready = function () {
        var header = $api.byId('topbar');
        //适配iOS7+,Android4.4+状态栏沉浸式效果,详见config文档statusBarAppearance字段
        // $api.fixStatusBar(header);
        //动态计算header的高度,因iOS7+和Android4.4+上支持沉浸式效果,
        //因此header的实际高度可能为css样式中声明的44px加上设备状态栏高度
        //其中,IOS状态栏高度为20px,Android为25px
        var headerH = $api.offset(header).h;
        //frame的高度为当前window高度减去header和footer的高度
        var frameH = api.winHeight - headerH;
        api.openFrame({
            name: 'detection-search-result-list',
            url: './detection-search-result-list.html',
            rect: {
                x: 0,
                y: headerH,
                w: api.winWidth,
                h: frameH
            },
            pageParam: {
                itemsId: api.pageParam.itemsName,
                itemsId: api.pageParam.itemsId
            },
            bounces: true,
            bgColor: 'rgba(0,0,0,0)',
            vScrollBarEnabled: true,
            hScrollBarEnabled: true
        });

        $api.dom('#title').innerHTML = api.pageParam.itemsName;
       
    };
   
    // 返回上一个页面
    function goBeforePage() {
        api.closeWin();
    }
</script>
</body>


</html>

6.2 子页面[list页面]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>检测-检测记录</title>
    <!--标准mui.css-->
    <link rel="stylesheet" href="../../css/mui.min.css">
    <!--App自定义的css-->
    <link rel="stylesheet" type="text/css" href="../../css/app.css"/>
    <link rel="stylesheet" type="text/css" href="../../css/my.css"/>
</head>
<body>
<div class="mui-content">
    <ul class="mui-table-view mui-table-view-chevron" id="showResult">
    </ul>
</div>
<script src="../../js/mui.js"></script>
<script type="text/javascript" src="../../script/api.js"></script>
<script type="text/javascript" src="../../js/request.js"></script>
<script type="text/javascript" src="../../js/dot.min.js"></script>
<script id="searchResultTemp" type="text/x-dot-template">
    {{ for(var x in it) { }}
    <li class="mui-table-view-cell mui-collapse">
        <a class="mui-navigate-right" href="#">{{=it[x].date}}</a>
        <ul class="mui-table-view mui-table-view-chevron">
            {{ for(var t in it[x].result) { }}
            <li class="mui-table-view-cell"><a href="#">
                {{? it[x].result[t].userName!==null }}
                {{=it[x].result[t].userName}}
                {{?? it[x].result[t].userName==null}}
                ----
                {{??}}
                {{?}}
                {{=it[x].result[t].detectionResult}}
                {{=it[x].result[t].detectionAnalysis}}
                {{? it[x].result[t].age!==null }}
                {{=it[x].result[t].age}}岁
                {{?? it[x].result[t].age==null}}
                ----
                {{??}}
                {{?}}
                {{? it[x].result[t].sex === "0" }}
                女
                {{?? it[x].result[t].sex === "1"}}
                男
                {{??}}
                {{?}}
            </a>
            </li>
            {{ } }}
        </ul>
    </li>
    {{ } }}
</script>
<script type="text/javascript" src="../../js/toastUtils.js"></script>
<script type="text/javascript" src="../../js/error.js"></script>
<script type="text/javascript">

    var pageIndex = 0;
    var pageSize = 15;
    var userId = "";
    var itemsId = "";
    apiready = function () {
        api.addEventListener({name: 'scrolltobottom'}, function (ret, err) {
            toDoRequest();
        });

        userId = $api.getStorage(CURRENT_USER)["id"];
        itemsId = api.pageParam.itemsId;
        toDoRequest();
    };

    // 刷新 初始化加载
    function toDoRequest() {
        showProgress('加载中', '加载数据中.....');
        API.detection.getDetectionByItems(userId, itemsId, pageIndex, pageSize, function (ret, err) {
            api.refreshHeaderLoadDone(); //复位下拉刷新
            api.hideProgress();
            if (!globalException(err)) {
                return;
            }
            pageIndex++;
            if(ret["data"]==null||ret["data"].length==0){
                showToast('无更多数据加载',1000);
                return ;
            }
            var evaluation = doT.template($api.dom('#searchResultTemp').innerHTML);
            $api.dom('#showResult').innerHTML += evaluation(ret["data"]);
        });
    }
</script>
</body>
</html>

7、异步请求

$api.get('http://192.168.2.66:8081/app/index', function (ret) {
            alert($api.jsonToStr(ret));
        }, 'json');
api.ajax({
            url: 'http://192.168.2.66:8081/app/index',
            method: 'get',
        },function(e){
            alert($api.jsonToStr(e));
        });

8、dot.js[模板引擎]

当使用web方式显示数据列表时,使用js模板可以有效提高开发效率。使用方式如下:

8.1 下载地址

https://github.com/olado/doT

8.2 在页面引用dot.min.js

<script type="text/javascript" src="../../script/api.js"></script>
<script type="text/javascript" src="../../js/dot.min.js"></script>

8.3 定义页面模板

<ul class="mui-table-view mui-grid-view mui-grid-12">
        <div id="itemsDataDiv"></div>
        <script id="itemsDataTemp" type="text/x-dot-template">
            {{ for(var x in it) { }}
            <li class="mui-table-view-cell mui-media mui-col-xs-3 mui-col-sm-3">
                <a href="#" onclick="goToItems(3)" tapmode>
                    <img src="../../image/cbd.jpg" class="indeximg"/>
                    <div class="mui-media-body">{{=it[x].itemsName}}</div>
                </a>
            </li>
            {{ } }}
        </script>
    </ul>

8.4 js驱动模板

apiready = function () {
        doFindAllItems();
    };

    // 查询所有的检测项目
    function doFindAllItems(){
        //TODO:
        var data = [
            {itemsName:"A",itemsIcon:"../../image/cbd.jpg",},
            {itemsName:"B",itemsIcon:"../../image/cbd.jpg",},
            {itemsName:"C",itemsIcon:"../../image/cbd.jpg",},
            {itemsName:"D",itemsIcon:"../../image/cbd.jpg",},
        ];
        // 
        var evaluation = doT.template($api.dom('#itemsDataTemp').innerHTML);
        $api.dom('#itemsDataDiv').innerHTML = evaluation(data);
    }

8.5 参考链接

9、Git管理

9.1 创建项目

  1. 在APICloud中创建新的项目
  2. 在git中创建repository,命名为demoApp
  3. 编写项目,即widget
    在这里插入图片描述

9.2 提交项目

1 在与widget同级的情况下,运行git bash,然后输入

$ git init

在这里插入图片描述

2 与远程库(demoApp)关联

git remote add origin https://github.com/xx/demoApp.git

3 推送代码到远程库

$ git add .
  $ git commit -m "commit message"
  $ git push -u origin master

9.3 与APICloud关联

在这里插入图片描述

9.4 云编译

当做完以上操作后,之后进行云编译,然后下载App.

9.5 官方说明git管理

10、各个项目模板参考

11、Android Stduio 设置代理访问

在本机安装shadowsockets 然后设置本机ip端口为1081 ,最后file->setting->System Settings-> Http Proxy

配置完毕后,进行测试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

12、自定义模块开发

开发之前,下载【模块开发SDK】,地址:https://docs.apicloud.com/Download/download

12.1 自定义模块开发[Eclipse]

​ 在用Android Studio打包模块并测试,发现so文件并不能加载,具体原因因为调试环境限制,暂时不明确(AS可以开发不需要so文件的模块,调用无问题)。故采用Eclipse开发模块。具体步骤如下:

1、下载SDK模块开发项目,并导入到Eclipse工作空间

在这里插入图片描述

2、创建 apiDigital 模块,并加入代码

在这里插入图片描述

3、加入需要的依赖,并build path

在这里插入图片描述

在这里插入图片描述

4、加入需要的libXXX.so库

在这里插入图片描述

5、映射

package com.apicloud.apiDigital;

import com.uzmap.pkg.uzcore.UZWebView;
import com.uzmap.pkg.uzcore.uzmodule.UZModule;
import com.uzmap.pkg.uzcore.uzmodule.UZModuleContext;
import com.xmgh.digitalreader.proxy.DigitalReaderProxy;

/**
* 该类映射至Javascript中apiDigital对象<br>
* <br>
* <strong>Js Example:</strong><br>
* var module = api.require('apiDigital');<br>
* module.xxx();
*
* @author fangping
*/
public class APIDigitalModule extends UZModule {// 需要继承UZModule

   private static DigitalReaderProxy digitalReaderProxy = null;

   public APIDigitalModule(UZWebView webView) {
   	super(webView);

   }
 
   /**
    * <strong>函数</strong><br>
    * <br>
    * 该函数映射至Javascript中moduleDemo对象的showAlert函数<br>
    * <br>
    * <strong>JS Example:</strong><br>
    * moduleDemo.showValue(argument);
    *
    * @param moduleContext
    *            (Required)
    */
	public void jsmethod_showValue(final UZModuleContext moduleContext)
			throws JSONException {
		JSONObject ret = new JSONObject();
		ret.put("msg", "Hello");
	    moduleContext.success(ret, false);
	}
}

6、导出jar,只导出该模块的代码即可

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

然后点击【Finish】即可。

7、资源修改

在这里插入图片描述

8、页面调用

在这里插入图片描述
在这里插入图片描述

9、打包的项目结构,新建一个与模块名一致的文件夹

在这里插入图片描述

文件夹说明:

res_apiDigital(可选目录):

1)、该目录命名规范必须为“res_”开头,后面跟模块名。例如“res_apiDigital”。

2)、res_apiDigital目录中内容审核: res_apiDigital的根路径下最多仅允许包含res子目录和AndroidManifest.xml文件,如图:
在这里插入图片描述

这两个文件对应项目中的:
在这里插入图片描述

sources: source目录为必须目录。

1)、该目录为模块的代码导出的JAR文件及其依赖的JAR所在目录,可存放多个JAR文件。

2)、该目录下均存放的.jar后缀名的文件,如apiDigital.jar、digitalreaderproxylibrary.jar.jar、tencent.jar。

4)、该目录下不允许存放名为android-support-v4.jar的文件。

5)、该目录下不允许存放名类似为apiEngine v1.1.0.jar的文件。

截图如下:
在这里插入图片描述

target:该目录为可选目录。
在这里插入图片描述

实际复制模块项目中的:
在这里插入图片描述

1)、该目录为模块用到的so库其依赖的so库所在目录,可存放多个so文件。

2)、该目录允许包含子目录,如armeabi-v7a、arm64、x86、mips等,这些子目录均为可选。

10、新建module.json,添加内容如下

{
   name:'apiDigital',
   class:'com.apicloud.apiDigital.APIDigitalModule'
}

11、压缩打包成zip即可

在这里插入图片描述

在这里插入图片描述

12、加入自定义模块,并添加到项目中.页面调用模块,不再累述

在这里插入图片描述

在这里插入图片描述

13、注意

  • res中需要去掉以下配置,以防冲突导致app编译失败

    <resources>
        <string name="app_name">apiDigital</string>
    </resources>
  • AndroidManifest.xml只加入对应的权限以及其他Activity,多余的去掉

  • 加入so库,不需要加入libsec.so

14、参考

12.2 自定义模块开发[AS]

12.3 模块开发之上传文件

代码:

package com.apicloud.apiDigital;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;

import org.json.JSONException;
import org.json.JSONObject;

import com.uzmap.pkg.uzcore.uzmodule.UZModuleContext;

public class UploadUtil {
	private static final int TIME_OUT = 180 * 1000; // 超时时间
	private static final String CHARSET = "utf-8"; // 设置编码

	/**
	 * android上传文件到服务器
	 * 
	 * @param file
	 *            需要上传的文件
	 * @param RequestURL
	 *            请求的rul
	 * @param userId 
	 * @param itemsId 
	 * @param batchCode 
	 * @param moduleContext
	 * @return 返回响应的内容
	 */
	public static String uploadFile(File file, String RequestURL,
			String itemsId, String userId, String batchCode, UZModuleContext moduleContext) {
		String result = null;
		String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成
		String PREFIX = "--", LINE_END = "\r\n";
		String CONTENT_TYPE = "multipart/form-data"; // 内容类型
		DataOutputStream dos = null;
		InputStream is = null;
		try {
			URL url = new URL(RequestURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setReadTimeout(TIME_OUT);
			conn.setConnectTimeout(TIME_OUT);
			conn.setDoInput(true); // 允许输入流
			conn.setDoOutput(true); // 允许输出流
			conn.setUseCaches(false); // 不允许使用缓存
			conn.setRequestMethod("POST"); // 请求方式
			conn.setRequestProperty("Charset", CHARSET); // 设置编码
			conn.setRequestProperty("connection", "keep-alive");
			conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary="
					+ BOUNDARY);
			conn.connect();

			if (file != null) {
				/**
				 * 当文件不为空,把文件包装并且上传
				 */
				dos = new DataOutputStream(conn.getOutputStream());
				// 
				StringBuffer sb = new StringBuffer();
				sb.append(PREFIX);
				sb.append(BOUNDARY);
				sb.append(LINE_END);
				sb.append("Content-Disposition: form-data;name=\"itemsId\"");
				sb.append(LINE_END);
				sb.append(LINE_END);
				sb.append(itemsId);
				sb.append(LINE_END);
				dos.write(sb.toString().getBytes());
				// 用户
				sb = new StringBuffer();
				sb.append(PREFIX);
				sb.append(BOUNDARY);
				sb.append(LINE_END);
				sb.append("Content-Disposition: form-data;name=\"userId\"");
				sb.append(LINE_END);
				sb.append(LINE_END);
				sb.append(userId);
				sb.append(LINE_END);
				dos.write(sb.toString().getBytes());
				
				// 
				sb = new StringBuffer();
				sb.append(PREFIX);
				sb.append(BOUNDARY);
				sb.append(LINE_END);
				sb.append("Content-Disposition: form-data;name=\"batchCode\"");
				sb.append(LINE_END);
				sb.append(LINE_END);
				sb.append(batchCode);
				sb.append(LINE_END);
				dos.write(sb.toString().getBytes());
				sb = new StringBuffer();
				sb.append(PREFIX);
				sb.append(BOUNDARY);
				sb.append(LINE_END);
				/**
				 * 这里重点注意: name里面的值为服务器端需要key 只有这个key 才可以得到对应的文件
				 * filename是文件的名字,包含后缀名的 比如:abc.png
				 */
				sb.append("Content-Disposition: form-data; name=\"Fdata\"; filename=\""
						+ file.getName() + "\"" + LINE_END);
				sb.append("Content-Type: application/octet-stream; charset="
						+ CHARSET + LINE_END);
				sb.append(LINE_END);
				dos.write(sb.toString().getBytes());
				is = new FileInputStream(file);
				byte[] bytes = new byte[1024];
				int len = 0;
				while ((len = is.read(bytes)) != -1) {
					dos.write(bytes, 0, len);
				}
				is.close();
				dos.write(LINE_END.getBytes());
				byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END)
						.getBytes();
				dos.write(end_data);
				dos.flush();
				/**
				 * 获取响应码 200=成功 当响应成功,获取响应的流
				 */
				int res = conn.getResponseCode();
				if (res == 200) {
//					is = conn.getInputStream();
					BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
					StringBuffer sb1 = new StringBuffer();
					int ss;
					while ((ss = in.read()) != -1) {
						sb1.append((char) ss);
					}
					result = sb1.toString();
					JSONObject ret = new JSONObject();
					ret.put("msg", result);
					ret.put("identity", 1);
					file.delete();// 删除上传
					moduleContext.success(ret, true);
				}else{
					JSONObject ret = new JSONObject();
					ret.put("msg", "请求失败,请联系后台管理员");
					ret.put("identity", -1);
					moduleContext.success(ret, true);
				}
				
			}
		} catch (MalformedURLException e) {
			JSONObject ret = new JSONObject();
			try {
				ret.put("msg", e.getMessage());
				ret.put("identity", -1);
			} catch (JSONException e1) {
				e1.printStackTrace();
			}
			moduleContext.success(ret, true);
			e.printStackTrace();
		} catch (Exception e) {
			JSONObject ret = new JSONObject();
			try {
				ret.put("msg", e.getMessage());
				ret.put("identity", -1);
			} catch (JSONException e1) {
				e1.printStackTrace();
			}
			moduleContext.success(ret, true);
			e.printStackTrace();
		} finally {
			try {
				if (dos != null) {
					dos.close();
				}
				if (is != null) {
					is.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}
}

13、自定义拍照模板

1 效果如下:

在这里插入图片描述

2 步骤如下

自定义模板scanner.html页面

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="maximum-scale=1.0, minimum-scale=1.0, user-scalable=0, initial-scale=1.0, width=device-width" />
    <meta name="format-detection" content="telephone=no, email=no, date=no, address=no">
    <title>Hello APP</title>
    <link rel="stylesheet" type="text/css" href="../css/api.css" />
    <style>

        html,body {
            padding-top: 80px;
            background-color: transparent;
            padding-left: 0%;
        }
      /*.box{width: 18%;height: 80px;margin: 0 auto;background: #fff;}*/
      .box{width: 400px;height: 100px;margin: 0 auto; border: 2px dotted #f3f3f7; margin-left:-15%;
          /*旋转90度*/
          -webkit-transform: rotate(90deg); /* Safari and Chrome */
          -moz-transform: rotate(90deg);   /* Firefox */
          -moz-transform: rotate(90deg);   /* Firefox */
          -ms-transform: rotate(90deg);   /* IE 9 */
          -o-transform: rotate(90deg);   /* Opera */
          transform: rotate(90deg);}
        .linebox {
            width: 173px;
            float: left;
            margin-left: 25%;
            margin-top: 16px;
        }
      .line{display: block; width:5px;height:30px;float: left; margin:25PX 25PX;border: 2px dotted #f3f3f7; }
        .Rightbox {
            float: left;
            margin-left: 70px;
            margin-top: 32px;
        }
        .circle{display: block; width:40px;height:30px;border-radius:40%; border: 2px dotted #f3f3f7; } /**f3f3f7**/

    </style>
</head>

<body>

<!--<a class="button" tapmode="active" onclick="fnTakePhoto()">拍照 </a>-->
   <div class="box">
       <span class="linebox" id="lineBox">
        <span class="line"></span>
        <span class="line"></span>
       </span>
       <div class="Rightbox">
           <span class="circle"></span>
       </div>
   </div>
</body>
<script type="text/javascript" src="../../../script/api.js"></script>
 
</html>

页面调用js

// 切换手机拍照
    function doChangePhoto() {
        var header = $api.dom('header'); // 获取 header 标签元素
        var headerH = $api.fixStatusBar(header);
        var FNPhotograph = api.require('FNPhotograph');
        var curdate = new Date();
        var photoPath = 'fs://FNPhotograph/' + curdate.getTime() + '.jpg';
        exitFlag = false;
        FNPhotograph.open({
            path: photoPath,
            album: true,
            quality: 'high',
            qualityValue:100
        }, function (ret) {
            if (ret.eventType == 'show') {
                api.openFrame({
                    name: 'scanner',
                    url: './photo/scanner.html',
                    bounces: true,
                    rect: { // 推荐使用Margin布局,用于适配屏幕的动态变化
                        x: 30, // main页面距离win顶部的高度
                        y: 80, // main页面距离win底部的高度
                        // w: 'auto' // main页面的宽度 自适应屏幕宽度
                        w: 'auto',
                        h: '430px',
                    },
                    bounces: false,
                });
            } else if (ret.eventType == 'takePhoto') {
                console.log(JSON.stringify(ret));
                var imagePath = ret.imagePath;
                if (imagePath != null) {
                    api.openWin({
                        name: 'detection-takephoto-submit',
                        url: './photo/detection-takephoto-submit.html',
                        rect: {
                                  api.openFrame({
                    name: 'scanner',
                    url: './photo/scanner.html',
                    bounces: true,
                    rect: { // 推荐使用Margin布局,用于适配屏幕的动态变化
                        x: 30, // main页面距离win顶部的高度
                        y: 80, // main页面距离win底部的高度
                        // w: 'auto' // main页面的宽度 自适应屏幕宽度
                        w: 'auto',
                        h: '430px',
                    },
                    bounces: false,
                });
            } else if (ret.eventType == 'takePhoto') {
                console.log(JSON.stringify(ret));
                var imagePath = ret.imagePath;
                if (imagePath != null) {
                    api.openWin({
                        name: 'detection-takephoto-submit',
                        url: './photo/detection-takephoto-submit.html',
                        rect: {
                            w: api.winWidth,
                            h: api.winWidth
                        },
                        pageParam: {imagePath: imagePath}
                    });
                }

            } else if (ret.eventType == 'close') {
                // document.getElementById('abc').src = ret.imagePath;
                // api.closeFrame({
                //     name: 'scanner'
                goToBeforePage();
            }
        });
    }

14、调用模块说明

14.1 调用定位模块说明

15、App抓包

15.1 安装说明

首先下载安装Fiddler,运行后选择菜单Tools->Fiddler Options。

选中"Decrpt HTTPS traffic",Fiddler就可以截获HTTPS请求:
在这里插入图片描述

选中"Allow remote computers to connect",是允许别的机器把HTTP/HTTPS请求发送到Fiddler上来:
在这里插入图片描述

配置完成后重启Fiddler。

15.2 安装证书【安卓不装】

1.获取当前电脑的IP地址,例如我这里是:192.168.2.65

2.在iPhone中打开safari并访问地址http://192.168.2.65:8888,点"FiddlerRoot certificate"然后安装证书:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

15.3 手机设置代理

在iPhone上打开设置->无线局域网,点击当前WIFI后面的i图标查看当前连接信息,滚动到底部的HTTP代理,切换为“手动”:
在这里插入图片描述

15.4 使用过程报错

使用中弹出:

creation of the root certificate was not successful

解决如下:

cd  d:\Program Files\Fiddler

makecert.exe -r -ss my -n "CN=DO_NOT_TRUST_FiddlerRoot, O=DO_NOT_TRUST, OU=Created by http://www.fiddler2.com" -sky signature -eku 1.3.6.1.5.5.7.3.1 -h 1 -cy authority -a sha1 -m 120 -b 09/05/2012

再安装证书

16、app更新

16.1 版本更新

16.2 云更新

17、ios证书

​ 现在apicloud官方不提供测试版本的IOS证书, 所以这里使用一个工具去生成IOS证书。

1.创建免费的苹果开发者账号的过程

2.申请ios证书步骤说明,这一步主要弄证书以及描述文件即可

3.打包ios的步骤说明

4.apicloud官方说明一些问题

5.博客说明ios证书

地址:https://blog.csdn.net/xxw888/article/details/76083152

6.注意

苹果端安装ipa,采用第三方去安装。扫描二维码以及ipa安装,会报安装失败等错误。

18、集成极光推送

18.1 集成步骤

1.app加入极光模块

在这里插入图片描述

2.极光官网绑定app

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.修改config.xml,在配置文件中,加入以下配置

<feature name="ajpush">
		 <param name="channel" value="developer-danqiusheng" />
		 <param name="app_key" value="93458e2fe2c88736b455b743" />  <!--上面的AppKey-->
	 </feature>

4.推送

在这里插入图片描述
在这里插入图片描述

18.2 链接

  • 论坛极光示例说明:
相关文章
相关标签/搜索