OpenApplus小程序容器

作者:分分快三计划

github 地址 https://github.com/iocool/antminDatePicker

示例代码如下:

添加Activty入口

在AndroidManifest.xml中添加

<activity android:name="com.openapplus.activity.OATinyProgramActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>

        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="com.benmu.weex.example.categoty.page"/>

        <data android:scheme="http"/>
        <data android:scheme="https"/>
    </intent-filter>
</activity>

一些其他的说明

  1. 组件的封装过程中,由于采用的是支付宝的 picker-view 所以在界面上没有花过多的时间,主要可能还是日期时间数组的生成需要处理一下,借助了 moment.js 库,对于时间处理上还是很方便的,以下是对处理日期数组 handleDateArr.js 的代码说明.
// 依赖于 moment.js
const Moment = require('./moment.min')

/**
 * 生成日期时间数组
 * @param dayLength // 要生成的天数时长,不传的话,默认生成 1 天
 * @param timeSection // 时间区间,默认 10 , 可下单区间早上9点到下午6点,可下单时间在当前小时后2小时
 */
function getDaysArr(dayLength, timeSection){
  let _daysArr = [[],[]]
  let _dayLength = dayLength || 1
  const _timeSection = timeSection || 10
  const _nowHour = Moment().format('HH')  // 当前时间 小时
  const _expressHour = parseInt(_nowHour)   2 // 可下单时间,当前时间  2
  const _earlyHour = 9  // 最早时间
  const _endHour = 19 // 截止时间

  for(let i = 0; i < _dayLength; i  ){

    // 当天时间处理
    if( i === 0){

      if(_expressHour <= _earlyHour ){

        // 早于早上 9点时
        _daysArr[1].push(getHoursArr(_earlyHour, _timeSection))

        // 处理日期
        _daysArr[0].push(Moment().add(i, 'days').format('YYYY-MM-DD'))

      } else if( _expressHour > _earlyHour && _expressHour < _endHour){

        // 晚于早上 9 点, 早于下午 18 点之前
        _daysArr[1].push(getHoursArr(_expressHour, (_endHour - _expressHour)))
        // 处理日期
        _daysArr[0].push(Moment().add(i, 'days').format('YYYY-MM-DD'))
      } else if ( _expressHour >= _endHour && _expressHour < 24){

        // 超过晚上 19 点之后,日期天数增加一天
        _dayLength  

      }

    } else {
      // 其他日期时间处理

      // 早于早上 9点时
      _daysArr[1].push(getHoursArr(_earlyHour, _timeSection))
      // 处理日期
      _daysArr[0].push(Moment().add(i, 'days').format('YYYY-MM-DD'))
    }

  }

  /**
   * 获取小时时间数组
   * @param nowHour // 当前小时
   * @param hoursLength // 小时区间长度
   */
  function getHoursArr(nowHour, hoursLength) {
    let _hoursArr = []
    for(let j = 0 ; j < hoursLength; j  ){
      _hoursArr.push(`${nowHour   j}:00:00`)
    }
    return _hoursArr
  }

  return _daysArr
}

module.exports = {
  getDaysArr
}
  1. dateTimePicker.js 文件中使用 handleDateArr.js 的方法
...

const { getDaysArr } = require('./js/handleDateArr');   // 引入处理函数

Component({
  data: {
    ...
  },
  methods: {

    // 获取日期数据
    doGetDaysArr() {
      this.setData({
        dateTimeData: getDaysArr(2)     // 传入参数,需返回的日期天数,2天
      });
    }
  }
});
...

以上就是该组件的基本说明,代码相对比较简单,觉得可以给目前在做支付宝小程序并有相关需要的童鞋参考一下.

4. 使用匿名内部类
一般来说,事件处理器没有什么复用价值,可复用的代码都被抽象成了业务逻辑方法了,所以应该使用匿名内部类,这是最好的方法。
示例代码在上面内部类部分已经给出。直接new 监听器接口,或者new 事件适配器。
5. 直接绑定到标签
另一种简单的方法是直接在布局文件中指定事件处理方法。

startWithAppKey:

传入在平台申请的 appKey,启动 JSPatch SDK。同时会自动执行已下载到本地的 patch 脚本。建议在 -application:didFinishLaunchingWithOptions: 开头处调用。

针对以上需求,借助小程序的 picker-view 组件,进行了二次封装,以下是封装后的组件.

Configuration cfg = getResources().getConfiguration();

sync

与 OpenApplus 平台后台同步,询问是否有包更新,如果有更新会自动下载并执行。

!!注意 startWithAppKey: 并不会询问后台包更新,必须调用 sync 方法。

每调用一次 sync 就会请求一次后台,对于实时性要求不高的 APP,只需在 -application:didFinishLaunchingWithOptions: 处调用一次,这样用户会在启动时去同步 patch 信息。对于实时性要求高的 APP,可以在 -applicationDidBecomeActive: 处调用这个接口,这样会在每次用户唤醒 APP 时去同步一次后台,请求次数会增多,但有包更新时用户会及时收到。

使用说明

支付宝小程序的组件引用方法,及使用说明,可参照 支付宝 使用自定义组件 查看,也可参照本示例中 pages/index 下的使用方法.

pages/index/index.json 需配置 usingComponents, 填写组件路径

{
    "defaultTitle": "日期选择picker demo",
    "usingComponents": {
        "picker": "../../components/dateTimePicker/dateTimePicker"
    }
}

pages/index/index.js 引入基础文件,详细配置及使用说明,参照 js 文件内容

// 引入基础初始
import datePicker from '../../components/dateTimePicker/datePickerBase'

pages/index/index.axml 使用 picker 组件

<picker
        title="{{datePicker.title}}"
        class="{{datePicker.class}}"
        visible="{{datePicker.visible}}"
        onHidePicker="hidePicker"
        onConfirm="onConfirm"
        pickerValue="{{datePicker.defaultValue}}"
/>

其中

title           // 组件标题
class           // 组件样式,可以自定义
visible         // 组件显示/隐藏
onHidePicker    // 隐藏该组件的事件
onConfirm       // 点击组件弹窗确定后的事件,onConfirm(str),其中 str 为最终回调的参数,可取到 picker 的值
pickerValue     // 默认参数,用来初始的时候用,传入数据是 picker 的索引值,默认(0,0),即 默认选中两列 picker 的第一项
// 简单起见,省略了返回值和参数
onKeyDown() // 按键
onKeyLongPress() // 长按
onKeyShortcut() // 键盘快捷键
onKeyUp() // 松开按键
onTouchEvent() // 触摸屏
onTrackballEvent() // 轨迹球屏

获得 AppKey

在平台上注册帐号,可以任意添加新 App,每一个 App 都有一个唯一的 AppKey 作为标识,平台提供客户端的AppKey、Appsecret和服务端的AppKey、Appsecret以便接入

项目结构

.
├── README.md
├── app.acss
├── app.js
├── app.json
├── components                      // 组件目录
│   └── dateTimePicker              // 日期组件目录
│       ├── datePickerBase.js       // 基础 js 文件,需在使用文件中引入
│       ├── dateTimePicker.acss     // 组件默认样式,除非特殊需要,一般不用修改
│       ├── dateTimePicker.axml     // 组件默认结构
│       ├── dateTimePicker.js       // 组件 js 
│       ├── dateTimePicker.json     // 组件配置信息
│       └── js
│           ├── handleDateArr.js    // 日期数组处理的 js ,用以生成所需的日期数组
│           └── moment.min.js       // 时间生成使用 moment.js
│
└── pages                         // 示例目录
    └── index
        ├── index.acss
        ├── index.axml
        ├── index.js
        └── index.json
void handleMessage(Message msg) // 处理消息,用于被重写
final boolean hasMessage(int what) // 检查消息队列中有无指定what属性的消息
final boolean hasMessage(int what, Object obj) // 检查消息队列中object属性为指定对象的消息
Message obtainMessage() // 多个重载方法,获取消息
sendEmptyMessage(int what) // 发送空消息
final boolean sendMessage(Message msg) // 立即发送消息
final boolean sendEmptyMessageDelayed(int what, long delayMillis) // 指定多少毫秒后发送空消息
final boolean sendMessageDelayed(Message msg, long delayMillis) // 指定多少毫秒后发送消息

授权登录流程

  1. 该日期为快递上门时间.

  2. 用户只可选择的日期范围,当日往后 2 天(即 今天, 明天 )的日期,并且时间选择为早上 9 点至下午 18 点间的 10 个小时整点时间.

  3. 由于是快递上门,所以可选择的时间点为当前时间点 2 小时后(比如,现在时间是11点,用户可选择的最早时间为13点).

  4. 如果当前时间晚于下午 18 点,则用户应该可以看到 明天后天 2 天的时间点.

// 获取按钮,为按钮注册监听器,在onCreate方法中
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new MyClickListener());
// 定义监听器,内部类
class MyClickListener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        // 事件处理
    }
}

在工程中Info.plist文件中添加如下项

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
   <true/>
</dict>

示例

图片 1

onConfigurationChanged(Configuration newConfig)

my. datePicker(OBJECT)

打开日期选择列表。

OBJECT参数说明:

参数 类型 必填 说明
format String 返回的日期格式,yyyy-MM-dd(默认)HH:mm yyyy-MM-dd HH:mm yyyy-MM yyyy
currentDate String 初始选择的日期时间,默认当前时间
startDate String 最小日期时间
endDate String 最大日期时间
success function 调用成功的回调函数
fail function 调用失败的回调函数
complete function 调用结束的回调函数(调用成功、失败都会执行)

success返回参数说明:

参数 类型 必填 说明
date String 选择的日期

示例代码:

my.datePicker({
  format: 'yyyy-MM-dd',
  currentDate: '2012-12-12',
  startDate: '2012-12-10',
  endDate: '2012-12-15',
  success: (res) => {
    my.alert({
    content: res.date,
  });
  },
});

最近在做支付宝小程序(以下简称小程序)开发,发现小程序的日期选择组件很不好用,比如安卓和IOS设备上,样式明显不同,因为小程序调用该组件是调用系统原生组件,所以会有一定的差异,另外,小程序提供的日期组件并不满足我当前的业务需求:

常用的几个接口:

二、小程序接入

// SendSms类onCreate方法中
btn.setOnLongClickListener(new SendSmsListener(this, address, content));
// SendSmsListener类中
private Activity act;
private EditText address, content;
public SendSmsListener(Activity act, EditText address, EditText context) {
    this.act = act;
    this.address = address;
    this.content = content;
}
@Override
public boolean onLongClick(View source) {
    // 事件处理代码
    return true;
}

启动小程序容器

Intent intent = new Intent(SplashActivity.this, OATinyProgramActivity.class);
intent.putExtra("tiny","openapplus://jsApp/xxxxx");
startActivity(intent);
finish();

第三章 Android的事件处理
Android提供两种事件处理方式,基于回调和基于监听器。前者常用于传统图形界面编程中,而后者在AWT/Swing开发中常用。
3.1 事件处理概述
对于基于回调的事件处理而言,主要是重写Android组件特定的回调方法,或者重写Activity的回调方法,一般用于处理通用性的事件。
对于监听的事件处理而言,主要是为Android界面组件绑定特定的事件监听器。
3.2 基于监听的事件处理
事件响应的动作通常以方法的形式组织,但Java是面向对象的编程语言,必须用类把这些方法组织起来,所以事件监听器的核心就是这些方法——事件处理器(Event Handler)。普通Java方法是由程序员调用,而事件处理器方法由系统调用。
事件监听器是特殊的Java对象,注册在事件源上,当用户触发事件时,就会调用事件处理器来响应。
委派式的事件处理:每个组件可以针对不同的事件注册不同的事件监听器,而每个事件监听器可以监听一个或者多个事件源。
1. 使用内部类

在Podfile文件加入

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
#忽略引入库的警告
inhibit_all_warnings!

target 'openapplus-ios-demo' do
    pod 'OpenApplus', :podspec => './podspec/OpenApplus.podspec'
end
// onCreate方法中
btn.setOnClickListener(this);
// 实现事件处理方法
@Override
public void onClick(View v) {
    // 事件处理
}

Android集成

View.OnClickListener // 单击事件
View.OnCreateContextMenuListener // 创建上下文菜单
View.OnFocusChangeListener // 焦点改变
View.OnKeyListener // 按键
View.OnLongClickListener // 长按
View.OnTouchListener // 触摸屏

添加相关权限

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<!-- 这个权限用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 这个权限用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

<uses-permission android:name="android.permission.ACCESS_GPS"/>

<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>

<uses-permission android:name="getui.permission.GetuiService.com.bmdoctor.jyt"/>

<!--amap额外权限-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>

使用内部类的好处是:可以在当前类中复用该监听器类;内部类也可以自由访问外部类的界面组件。
2. 使用外部类
如果某个事件监听器需要被多个GUI界面共享,且主要是完成某种业务逻辑的实现,则可以定义为外部类。
但并不推荐将业务逻辑写在事件监听器中,包含业务逻辑的事件监听器将导致程序的显示逻辑与业务逻辑耦合。如果确实有多个监听器需要实现相同的业务逻辑方法,可以考虑使用业务逻辑组件来定义业务逻辑功能,再让事件监听器来调用其方法。

发布指南

3. Activity本身作为事件监听器
缺点如下:
Activity主要是完成界面初始化工作,如果还需包含事件处理方法,会引起程序结构的混乱;
Activity界面类不该实现监听器接口。

应用指南

3.3 基于回调的事件处理
回调机制中事件源和事件监听器是统一的,组件自己负责处理该事件,可以提高程序的内聚性。
继承组件类,并重写该类的事件处理方法。常用的有:

Android Studio集成

下载SDK功能组件,解压.zip文件得到相应组件包(openapplus-release.aar),在Android Studio的项目工程libs目录中拷入相关组件jar包。

右键Android Studio的项目工程—>选择Open Module Settings —>在 Project Structure弹出框中 —>选择 Dependencies选项卡 —>点击左下“+”—>选择组件包类型—>引入相应的组件包。

final Handler myHandler = new Handler()
{
    @Override
    public void handleMessage(Message msg) {
        if (msg.what == 0x1233) {
            // do something
        }
    }
};
new Timer().schedule(new TimerTask()
{
    @Override
    public void run() {
        myHandler.sendEmptyMessage(0x1233);
    }
}, 0, 1200);

my. showToast(OBJECT)

confirm 确认框。

OBJECT参数说明:

参数 类型 必填 说明
content String alert框的标题
type function alert框的内容
success function 调用成功的回调函数
fail function 调用失败的回调函数
complete function 调用结束的回调函数(调用成功、失败都会执行)

示例代码:

  my.showToast({
  type: 'success',
  content: '操作成功',
  duration: 3000,
  success: () => {
    my.alert({
      title: 'toast 消失了',
    });
  },
});

当新线程发送消息时,handleMessage方法被自动回调。
UI线程中,系统已经初始化了一个Looper对象,所以直接创建Handler即可,而在子线程中,需要程序员创建一个Looper对象,并调用其prepare()方法。
使用Handler的步骤如下:
调用prepare()方法为当前线程创建Looper对象,之后它的构造器会创建与之配套的MessageQueue
创建Handler子类的实例,重写handleMessage方法;
调用loop()方法启动Looper
如果在UI线程中执行耗时操作,将导致ANR异常(20s),这会导致程序无法响应输入事件和Broadcast
3.6 异步任务
一种轻量级的解决方案,不需要借助线程和Handler即可实现。
AsyncTask<Params, Progress, Result>是抽象类,其中参数:
Params:启动任务执行的输入参数类型;
Progress:后台任务完成的进度值类型;
Result:返回结果的类型。
实现步骤:
第一步,创建AsyncTask的子类,并为三个泛型参数指定类型,如不需要指定,用Void
第二步,根据需要,实现如下方法:
doInBackground():后台将要执行的任务,该方法可以调用publishProgress()方法更新进度;
onPrograssUpdate():调用PublishProgress()方法后将触发该方法;
onPreExecute():一些初始化工作,如显示进度条等;
onPostExecute():当doInBackground()完成后,将其返回值传给此方法。
第三步,调用execute()开始执行耗时任务。
第二步中的方法由系统调用,程序员只需重写。
阅读学习材料:《疯狂Android讲义》(第二版)
本章源代码地址:Github

my. hideLoading()

隐藏加载提示。

示例代码:

my.hideLoading();
// xml文件中
android:onClick="clickHandler"
// Activity类中
public void clckHandler(View source) {
    // 事件处理
}

收银台

事件传播
基于回调的事件处理方法都有一个布尔返回值,该返回值标识该方法能否处理该事件,如果不能则返回false,事件将继续传播。
先监听,后回调,最后到Activity
当组件上发生某个按键事件时,首先触发的是该按键绑定的事件监听器(Listener),接着触发该组件提供的事件回调方法(自定义组件中重写的),然后还会传播到该组件所在的Activity
Adnroid事件处理机制保证基于监听的事件监听器被优先触发,基于监听的事件模型中事件源与监听器分工明确,易于维护。
回调模型更适合于处理那些逻辑比较固定的场景,不需要监听,组件自行处理。
3.4 响应系统设置的事件
Configuration可以用于获取用户特定的配置项,以及系统的动态设备配置。可用如下代码:

my. getAuthCode(OBJECT)

调用接口获取登录凭证(jsAppToken)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key)。用户数据的加解密通讯需要依赖会话密钥完成。

OBJECT参数说明:

参数 类型 必填 说明
jsAppKey String 小程序应用AppKey
success function 调用成功的回调函数
fail function 调用失败的回调函数
complete function 调用结束的回调函数(调用成功、失败都会执行)

CALLBACK返回参数说明:

参数 类型 必填 说明
authCode String 授权码,用户允许登录后,回调内容会带上 authCode(有效期五分钟),开发者需要将 authCode 发送到开发者服务器后台,使用code 换取 session_key api,将 authCode 换成 openid 和 session_key
expired Timestamp 过期时间

示例代码:

my.getAuthCode({
  jsAppKey: 'jsAppKey',
  success: (res) => {
    my.alert({
    content: res.authCode,
  });
  },
});

代码示例:

my. navigateToMiniProgram(OBJECT)

开放小程序容器操作API,打开同一App下关联的另一个小程序。

OBJECT参数说明:

参数 类型 必填 说明
appId String 要打开的小程序 jsAppKey
path String 打开的页面路径,如果为空则打开首页
extraData String 需要传递给目标小程序的数据,目标小程序可在 App.onLaunch(e),App.onShow(e) 中获取到这份数据。参数e格式为:{path: "", query: query},其中query 为extraData,仅支持一层字典
url String 和appId二者选择一个,打开小程序的URL,格式为:openapplus://jsApp/e03f37ba425a47e6aafd8170eee6be52/param1=value1&param2=value2, 如果参数中提供了instancId,会尝试打开已有页面
success function 调用成功的回调函数
fail function 调用失败的回调函数
complete function 调用结束的回调函数(调用成功、失败都会执行)

示例代码:

  my.navigateToMiniProgram({
  appId: '',
  path: 'pages/index/index',
  extraData: {
    foo: 'bar'
  },
  envVersion: 'develop',
  success(res) {
    // 打开成功
  }
})

动态更改屏幕方向,可以用setRequestedOrientation(int)方法。
为了能监听系统设置的改变,在AndroidMenifest文件中配置Activityandroid:configChanges属性,各属性值之间用竖线隔开。
如果targetSdkVersion设置超过12,则属性值应当为orientation|screenSize,因为转屏时屏幕大小也变了。
3.5 Handler消息传递机制
只允许主线程(UI线程)修改UI组件,其他线程借助Handler消息传递机制来实现对界面组件的修改。
通过回调的方式:开发者重写Handler中处理消息的方法,新线程发送消息到MessageQueue,而Handler不断从中获取并处理消息。Handler类中处理消息的方法被回调。

iOS集成

可以获取屏幕方向,触摸方式,导航设备等。
监听系统设置的改变可用如下基于回调的方法:

my.confirm(OBJECT)

confirm 确认框。

OBJECT参数说明:

参数 类型 必填 说明
title String alert框的标题
content function alert框的内容
confirmButtonText function 确认按钮文字,默认‘确定’
cancelButtonText function 确认按钮文字,默认‘取消’
success function 调用成功的回调函数
fail function 调用失败的回调函数
complete function 调用结束的回调函数(调用成功、失败都会执行)
// 自定义View
public class MyButton extends Button {
    // 构造方法略
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        super.onKeyDown(keyCode, event);
        // 事件处理
        return true;
    }
}
// xml文件中,各种属性略
<org.crazyit.event.MyButton />

第五步:通过session调用接口

能调用的接口有以下:

接口 接口URL 接口说明
/auth/jsapp/getUser http://www.openapplus.com/auth/jsapp/getUser 获取用户个人信息
// 用了匿名内部类
planeView.setOnKeyListener(new OnKeyListener() {
    @override
    public boolean onKey(View source, int keyCode, KeyEvent event){
        switch(event.getKeyCode()){
            // 获取由哪个键触发的事件,并处理
        }
        return true;
    }
});

小程序 API

OpenApplus小程序容器。编程步骤:
获取界面组件(事件源);
实现监听器类(编程重点),实现XxxListener接口;
setXxxListener方法将事件监听器对象注册给事件源。
在触发事件后,事件会作为参数传递给事件监听器。但在上面的代码中,并没有出现事件的踪迹,原因是,当事件足够简单,事件中封装的信息比较有限,就无须封装事件对象了。但对于键盘事件,触摸屏事件等,就需要详细的信息。Android将其封装成XxxEvent对象。

第二步:配置App的授权接口

    [OpenApplus startWithAppKey:@"AppKey" andSecret:@"AppSecret"];
    NSString *uid = @"111";
    [OAConfiguration setUserIdentify:uid];
    [OpenApplus setupCallback:^(OACallbackType type, id data, OpenApplusNotify notify, NSError *error) {
        switch (type) {
            case OACallbackTypeAuthUser: {
                // http://www.openapplus.com/auth/auth,请求该接口获取token和超时时间
                OAContainerAuthObject *containerAuthObject = [[OAContainerAuthObject alloc] init];
                containerAuthObject.token = @"";
                containerAuthObject.expired = @"";
                notify(containerAuthObject, nil);
                // 使用App服务端的AppKey和AppSecret,以下注释代码因为使用简易方式,没有经过服务端的验证,并且将AppServerKey,AppServerSecret暴露在客户端,属于不安全的简易方式,仅供测试或者没有服务器的app的使用,再次申请,该方式不安全。
                // OARequestWrapper *requestWrapper = [OpenApplus requestWithAppKey:@"AppServerKey" andSecret:@"AppServerSecret"];
                // OAAuthDtoWrapper *dto = [[OAAuthDtoWrapper alloc] init];
                // dto.code  = [data performSelector:@selector(code)];
                // dto.deviceid  = [OpenUDID value];
                // dto.uid = uid;
                // [requestWrapper sendObject:dto thenNotify:notify];
            }
  }]

运行

在项目工程的自定义application中的onCreate方法中添加以下两个方法:
注意:一定要在主进程进行该项操作

OpenApplus.registerApp(this, SampleContants.APPID, SampleContants.APP_SECRET);
OpenApplus.sync();
OpenApplus.setCallback(new OpenApplusCallback() {
            @Override
            public void invoke(OACallbackType type, JSONObject data, OpenApplusNotify notify) {
                if (type == OACallbackType.OACallbackTypeAuthUser){
                    // 该接口仅供测试使用,请使用服务端发送给授权请求
                    OARequestWrapper requestWrapper = OpenApplus.makeRequestWrapper(SampleContants.SERVER_APPID, SampleContants.SERVER_APP_SECRET);
                    OAAuthDtoWrapper dto = new OAAuthDtoWrapper();
                    dto.setUid("1");
                    try {
                        dto.setCode(data.getString("code"));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    String deviceID = Settings.Secure.getString(WXEnvironment.sApplication.getApplicationContext().getContentResolver(),
                            Settings.Secure.ANDROID_ID);
                    dto.setDeviceid(deviceID);
                    requestWrapper.sendObject(dto, notify);
                }
            }
});

注意:

参数1:上下文,必须的参数,不能为空

参数2:OpenApplus app key,必须参数。

参数3:OpenApplus app secret,必须参数。

SDK API

my. hideToast()

隐藏弱提示。

示例代码:

my.hideToast()

wx.navigateBackMiniProgram(OBJECT)

返回到上一个小程序,只有在当前小程序是被其他小程序打开时可以调用成功

OBJECT参数说明:

参数 类型 必填 说明
extraData String 需要返回给上一个小程序的数据,上一个小程序可在 App.onShow(e) 中获取到这份数据。参数e格式为:{path: "", query: query},其中query 为extraData,仅支持一层字典
success function 调用成功的回调函数
fail function 调用失败的回调函数
complete function 调用结束的回调函数(调用成功、失败都会执行)

第三步:通过jsToken获取获取后台session

http://www.openapplus.com/auth/jsapp/code2session

请求方式:

POST, ContentType:x-www-form-urlencode

参数说明:

参数 类型 必填 说明
jsAppKey String 该应用的jsAppKey
token String 前端获取的jsToken
timestamp String 当前时间戳
signature String 使用签名规则生成的签名sha1(toquery(sort(params))) , 参数中密钥为:appSecret=jsAppSecret

返回说明:

参数 类型 必填 说明
code String 状态编码
data String 响应数据
message String 错误信息

OpenApplus小程序容器。data参数说明:

参数 类型 必填 说明
session String 授权会话
expired String 为session的过期时间

后台使用

第一步:获取服务端的AppKey、AppSecret、AppKey、JsAppsecret

在进行OpenApp OAuth2授权登录接入之前,在开放平台注册【http://www.openapplus.com/】开发者帐号,并拥有一个已审核通过的网站应用, 获取应用的AppKey、AppSecret,并获得相应的服务端的JsAppKey、JsAppsecret,申请OpenApp 登录且通过审核后,可开始接入流程。

第三步:用户认证

用户认证接口

http://www.openapplus.com/auth/auth

请求方式:

POST, ContentType:x-www-form-urlencode

参数说明:

参数 类型 必填 说明
appKey String 应用appServerKey
code String 授权code
deviceid String 设备deviceid
uid String 用户标识
timestamp String 当前时间戳
signature String 使用签名规则生成的签名sha1(toquery(sort(params))) , 参数中密钥为:appSecret=appSecret

返回说明:

参数 类型 必填 说明
code String 状态编码
data String 返回数据
message String 错误信息

data参数说明:

参数 类型 必填 说明
token String 授权token
expired String 为session的过期时间

概述

OpenApp 一个小程序容器,配置简单、功能完善、界面流畅、开箱即用!使用OpenApp 可以快速扩展你的APP,使其拥有与微信一样的功能扩展可能,让App的所有的功能都通过小程序来实现,动态更新,更快的响应用户需求。其拥有的管理具备版本管理功能,让功能发布更加随心。

代码混淆

如果您的应用使用了混淆, 请添加

-keep class com.openapplus.** {*;}

my. hideKeyboard()

隐藏键盘。

示例代码:

my. hideKeyboard();

客户端

集成SDK

第一步:获取小程序的JsAppKey、JsAppsecret

在进行OpenApp OAuth2授权登录接入之前,在开放平台注册【http://www.openapplus.com/】开发者帐号,并拥有一个已审核通过的小程序项目,并获得相应的服务端的JsAppKey、JsAppsecret,将其授权到应用后,可开始接入流程。

Cocoapods 安装

推荐使用 CocoaPods 的方式安装使用。

CocoaPods 是一个广泛适用于Objective-C依赖管理工具,能够自动配置项目,简化你配置Openapp 的过程,使用以下命令行安装

$ gem install cocoapods

运行

在 AppDelegate.m 里按顺序调用三个方法:

1、调用 startWithAppKey: ,参数为第一步获得的 AppKey。

2、调用 sync 方法检查包更新。

在AppDelegate.m或ViewController.m中调用 navigateToMiniProgram: 加载小程序项目,参数为在平台中创建的项目的名称。

  #import <"openapplus/openapplus.h">
  @implementation AppDelegate
  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:testViewController];
      self.window.rootViewController = navigationController;
      [self.window makeKeyAndVisible];

      [OpenApplus startWithAppKey:@"test"];
      [OpenApplus sync];
      [OpenApplus setNavigationController:navigationController];
      // JS_APPID 为小程序的APP_ID
      [OpenApplus navigateToMiniProgram:@"openapplus://jsApp/#JS_APPID#" completion:^{

      }];

      ...
  }
  @end

上述例子是把 Openapplus 同步放在 -application:didFinishLaunchingWithOptions: 里,若希望包能及时推送,可以把 [OpenApplus sync] 放在 -applicationDidBecomeActive: 里,每次唤醒都能同步更新 OpenApplus 包,不需要等用户下次启动。

my. showLoading()

显示加载提示。

OBJECT参数说明:

参数 类型 必填 说明
content String alert框的标题
delay Integer 延迟显示,单位 ms,默认 0。如果在此时间之前调用了 my.hideLoading 则不会显示
success function 调用成功的回调函数
fail function 调用失败的回调函数
complete function 调用结束的回调函数(调用成功、失败都会执行)

示例代码:

my.showLoading({
  content: '加载中...',
  delay: 1000,
});

一、App接入

my.alert(OBJECT)

alert 警告框。

OBJECT参数说明:

参数 类型 必填 说明
title String alert框的标题
content function alert框的内容
buttonText function 按钮文字,默认确定
success function 调用成功的回调函数
fail function 调用失败的回调函数
complete function 调用结束的回调函数(调用成功、失败都会执行)

第二步:前端调用登录API

my.getAuthCode({
  jsAppKey: 'jsAppKey',
  success: (loginResponse) => {
    if (!loginResponse.error){
        let sessionData = {
            token: loginResponse.authCode,
            jsAppKey: that.config.jsAppKey
        }
        let qs = require('qs')
        my.httpRequest({
          url: 'http://httpbin.org/post',
          method: 'POST',
          data: sessionData,
          success: function(res) {
            if (parseInt(respData.data.code) === 1) {
                console.debug("获取jsToken成功!jsToken为:"   respData.data.jsToken);
            }
          },
          fail: function(res) {
            console.debug("获取authCode失败!");
          },
          complete: function(res) {

          }
        });
    } else {
        console.debug("获取jsToken失败!");
    }
  }
});

OpenApplus 安装

使用CocosPods集成Openapp 到Xcode,需要编写/podspec/OpenApplus.podspec文件

Pod::Spec.new do |s|
    s.name         = "OpenApplus"
    s.version      = "1.0.0"
    s.summary      = "OpenApplus framework"
    s.homepage     = "http://github.com/linwaiwai/openapplus"
    s.license      = { :type => 'OpenApplus License, Version 1.0.0', :text => <<-LICENSE
      Licensed under the OpenApplus License, Version 1.0.0 (the "License");
      you may not use this file except in compliance with the License.
      LICENSE
    }
    s.author   = "linwaiwai"
    s.platform     = :ios, "6.0.0"
    s.source       = { :git => "https://github.com/linwaiwai/openapplus.git", :branch => "master"}
    s.frameworks = "UIKit"
    s.requires_arc = true
    s.dependency 'SDWebImage', '3.7.5'
    s.dependency 'SSZipArchive', '1.6.2'
    s.dependency 'SVProgressHUD', '2.1.2'
    s.dependency 'Masonry', '1.0.2'
    s.dependency 'UMengUShare/Social/WeChat', '6.3.0'
    s.dependency 'MJRefresh', '3.1.12'
    s.dependency 'libextobjc', '~> 0.4.1'
    s.dependency 'AFNetworking'
    s.dependency 'OpenUDID'

    s.subspec 'OpenApplus' do |ss|
        ss.vendored_frameworks = '*.framework'
        ss.vendored_libraries = '*.a'
        ss.source_files = '*.h'
        ss.resource = '*.bundle'
    end
end

本文由分分快三计划发布,转载请注明来源

关键词: 分分快三计划 日记本 Android 学习编程