air应用接入移动mm弱联网平台
不得不说移动mm平台是比较友好的,遇到的所有问题都在群里有人回答,并且sdk接入十分方便,没有遇到什么大问题。
工作量大概是一天左右,分享一下接入过程。
所需环境:
AIR:3.9
ANDROIDAPI:19
移动mm版本:1.2.2
1.编写as文件
定义函数常量
private static const MM_FUNCTION_INIT:String = "mmsns_function_init";//与java端中Map里的key一致
private static const MM_FUNCTION_BILL:String = "mmsns_function_bill";//与java端中Map里的key一致
private static const MM_FUNCTION_DEBUG:String = "mmsns_function_debug";//与java端中Map里的key一致
private static const EXTENSION_ID:String = "com.mmsns.ane";//与extension.xml中的id标签一致
创建单例
private static var _instance:MMSNSExtension;
public function MMSNSExtension()
{if(extContext == null) {extContext = ExtensionContext.createExtensionContext(EXTENSION_ID, "");extContext.addEventListener(StatusEvent.STATUS, statusHandler);}
}
/*** 获取实例* @return DLExtension 单例*/
public static function getInstance():MMSNSExtension
{
if(_instance == null) {
_instance = new MMSNSExtension();
}
return _instance;
}
抛事件函数
/*** 转抛事件* @param event 事件*/
private function statusHandler(event:StatusEvent):void
{dispatchEvent(event);
}
以上是99%的ane都需要复制粘贴的语句。。
然后是定义移动mm的函数,因为弱联网版本只有初始化跟支付两个功能点,所以直接写
/*** 初始化* @param APPID* @param APPKEY* @return * */
public function MMSNSInit(APPID:String,APPKEY:String):void{if(extContext ){extContext.call(MM_FUNCTION_INIT, APPID, APPKEY);}
} /*** 商品购买接口。* @param payCode* @param num* @param description* @return * */
public function MMSNSBilling(payCode:String, num:uint, description:String = ''):void{if(extContext ){extContext.call(MM_FUNCTION_BILL, payCode, num, description);}
}
以上,as版本真心没技术含量,请大家谅解。
然后是安卓端。。
安卓端我的api一律设为19,然后记得勾上"Mark this project as a library",上面两项都去掉勾
安卓端要先创建context跟extension两个文件,把入口代码站过去。
Context文件
package com.mmsns.ane;import java.util.HashMap;
import java.util.Map;import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.mmsns.func.MMSNSBill;
import com.mmsns.func.MMSNSBillInit;public class MMSNSContext extends FREContext {/*** 初始化*/public static final String MMSNS_FUNCTION_INIT = "mmsns_function_init";/*** 订购*/public static final String MMSNS_FUNCTION_BILL = "mmsns_function_bill";@Overridepublic void dispose() {// TODO Auto-generated method stub}@Overridepublic Map<String, FREFunction> getFunctions() {// TODO Auto-generated method stubMap<String, FREFunction> map = new HashMap<String, FREFunction>();//映射map.put(MMSNS_FUNCTION_INIT, new MMSNSBillInit());map.put(MMSNS_FUNCTION_BILL, new MMSNSBill());return map;}}
Extension文件
package com.mmsns.ane;import com.adobe.fre.FREContext;
import com.adobe.fre.FREExtension;public class MMSNSExtension implements FREExtension {@Overridepublic FREContext createContext(String arg0) {// TODO Auto-generated method stubreturn new MMSNSContext();}@Overridepublic void dispose() {// TODO Auto-generated method stub}@Overridepublic void initialize() {// TODO Auto-generated method stub}}
把入口定义好后,就是加入功能代码了,因为要完成移动mm的支付,需要完成Handler和OnSMSPurchaseListener这两个类来监测初始化跟支付的状态。
IAPHandler
package com.mmsns.func;import android.os.Handler;
import android.os.Message;import com.adobe.fre.FREContext;public class IAPHandler extends Handler {public static final int INIT_FINISH = 10000;public static final int BILL_FINISH = 10001;public static final int QUERY_FINISH = 10002;public static final int UNSUB_FINISH = 10003;public IAPHandler(FREContext context) {MMSNSShared.context = (FREContext) context;}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);}
}
IAPListener,处理各种完成的回调之类的,抛送信息到as端
package com.mmsns.func;import java.util.HashMap;import mm.sms.purchasesdk.OnSMSPurchaseListener;
import mm.sms.purchasesdk.PurchaseCode;
import mm.sms.purchasesdk.SMSPurchase;
import android.os.Message;
import android.util.Log;import com.adobe.fre.FREContext;public class IAPListener implements OnSMSPurchaseListener {private final String TAG = "IAPListener";private IAPHandler iapHandler;public IAPListener(FREContext context, IAPHandler iapHandler) {MMSNSShared.context = context;this.iapHandler = iapHandler;}@Overridepublic void onInitFinish(int code) {MMSNSShared.event(TAG, "Init finish, status code = " + code);Message message = iapHandler.obtainMessage(IAPHandler.INIT_FINISH);String result = "初始化结果:" + SMSPurchase.getReason(code);message.obj = result;message.sendToTarget();}@Overridepublic void onBillingFinish(int code, HashMap arg1) {MMSNSShared.event(TAG, "billing finish, status code = " + code);String result = "订购成功";Message message = iapHandler.obtainMessage(IAPHandler.BILL_FINISH);// 商品信息String paycode = null;// 商品的交易 ID,用户可以根据这个交易ID,查询商品是否已经交易String tradeID = null;if (code == PurchaseCode.ORDER_OK|| code == PurchaseCode.ORDER_OK_TIMEOUT) {/*** 商品购买成功或者已经购买。 此时会返回商品的paycode,orderID,以及剩余时间(租赁类型商品)*/if (arg1 != null) {paycode = (String) arg1.get(OnSMSPurchaseListener.PAYCODE);if (paycode != null && paycode.trim().length() != 0) {result = result + ",Paycode:" + paycode;}tradeID = (String) arg1.get(OnSMSPurchaseListener.TRADEID);if (tradeID != null && tradeID.trim().length() != 0) {result = result + ",tradeid:" + tradeID;}MMSNSShared.event("ORDER_SUCCESS", paycode);}} else {/*** 表示订购失败。*/result = "订购失败:" + SMSPurchase.getReason(code);MMSNSShared.event("ORDER_FAIL", SMSPurchase.getReason(code));Log.d(TAG, "ORDER_FAIL" + SMSPurchase.getReason(code));}MMSNSShared.event(TAG, result);}
}
好了,现在可以开始写功能函数了,但是我们需要一个共享的类来存储context和一些初始信息,方便我们随时调用。
于是来一个Shared类,专门存储信息
package com.mmsns.func;import mm.sms.purchasesdk.SMSPurchase;import android.util.Log;
import android.widget.Toast;import com.adobe.fre.FREContext;public class MMSNSShared {public static Boolean DEBUG = false;public static String APPID = "0000000000";public static String APPKEY = "0000000000";public static SMSPurchase purchase;public static IAPListener mListener;public static FREContext context;public static void event(String code,String level ){Log.d(code, "---------抛出event-------" + ":"+level );context.dispatchStatusEventAsync(code, level );if (DEBUG){Toast.makeText(context.getActivity(), code + ":" + level, Toast.LENGTH_LONG).show();}}
}
现在实现初始化mm模块
package com.mmsns.func;import mm.sms.purchasesdk.SMSPurchase;import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject;public class MMSNSBillInit implements FREFunction {private String TAG = "MMBillInit";@Overridepublic FREObject call(final FREContext context, FREObject[] arg1) {MMSNSShared.context = context;FREObject result = null; try{MMSNSShared.APPID = arg1[0].getAsString();MMSNSShared.APPKEY = arg1[1].getAsString();}catch(Exception e){return null;}IAPHandler iapHandler = new IAPHandler(MMSNSShared.context);/*** IAP组件初始化.包括下面3步。*//*** step1.实例化PurchaseListener。实例化传入的参数与您实现PurchaseListener接口的对象有关。* 例如,此Demo代码中使用IAPListener继承PurchaseListener,其构造函数需要Context实例。*/MMSNSShared.mListener = new IAPListener(MMSNSShared.context, iapHandler);/*** step2.获取Purchase实例。*/MMSNSShared.purchase = SMSPurchase.getInstance();/*** step3.向Purhase传入应用信息。APPID,APPKEY。 需要传入参数APPID,APPKEY。 APPID,见开发者文档* APPKEY,见开发者文档*/try {MMSNSShared.purchase.setAppInfo(MMSNSShared.APPID, MMSNSShared.APPKEY);} catch (Exception e1) {return null;}/*** step4. IAP组件初始化开始, 参数PurchaseListener,初始化函数需传入step1时实例化的* PurchaseListener。*/try {MMSNSShared.purchase.smsInit(context.getActivity(), MMSNSShared.mListener); } catch (Exception e) {return null;}//--------------------------------return result;}
}
然后是支付函数
package com.mmsns.func;import android.content.Context;import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject;public class MMSNSBill implements FREFunction {private String TAG = "MMSNSBill";@Overridepublic FREObject call(final FREContext context, FREObject[] arg1) {String payCode = null,description = null;int num = 0;FREObject result = null; //get paramstry{payCode = arg1[0].getAsString();num = arg1[1].getAsInt();description = arg1[2].getAsString();}catch(Exception e){MMSNSShared.event(TAG, "参数错误:" + e.getMessage() + "|" + payCode + "|" + num + description);return null;}/*** 商品购买接口。*/if(MMSNSShared.context != null){order(MMSNSShared.context.getActivity(), payCode, num, description);}else{}//--------------------------------return result;}public void order(Context context, String payCode, int num, String description) {try {MMSNSShared.purchase.smsOrder(context, payCode, MMSNSShared.mListener, description);} catch (Exception e) {MMSNSShared.event(TAG, "支付失败" + e.getMessage() + "," + e.toString());}}}
好了,程序上的东西都做好了,现在开始打包ane
我们需要as端bin文件夹下的swc文件,和and端bin文件夹下的jar文件
以及一个extension.xml的文件
<?xml version="1.0" encoding="UTF-8"?>
<extension xmlns="http://ns.adobe.com/air/extension/3.9"><id>com.mmsns.ane</id><versionNumber>1</versionNumber><platforms><platform name="Android-ARM"><applicationDeployment><nativeLibrary>mmsnsbillingane.jar</nativeLibrary><initializer>com.mmsns.ane.MMSNSExtension</initializer><finalizer>com.mmsns.ane.MMSNSExtension</finalizer></applicationDeployment></platform></platforms>
</extension>
先要合并生成的jar跟移动的jar文件
用winrar之类的打开自己的jar和移动mm的jar,把移动mm的除了assets和META-INF外都复制到自己的jar文件那
我是使用批处理完成这个复杂的操作。。感谢前人的努力写出这段神奇的批处理
rem 你做的主JAR包的路径
set SOURCEJAR=com.mmsns.ane.jar
set MainJar=mmsnsbillingane.jar
rem 第三方JAR包的路径
set ExternalJar=mmsmsbilling1.2.2.jar
rem 第三方JAR包顶级包名称
set packageName=com
set packageName2=mm
rem swc文件名
set SWC=MMANE-SNS.swc
echo =========== start make jar ==============
rem 创建临时目录
md temp
rem 拷贝临时文件
rem copy %SOURCEJAR% %MainJar%
copy .\android-project\bin\%SOURCEJAR% .\temp\%MainJar% >nul
copy .\SDK1.2.2\libs\%ExternalJar% .\temp\ >nul
cd temp
rem 解压第三方包
jar -xf %ExternalJar%
rem 合并主JAR包
jar -uf %MainJar% %packageName%
rem 合并其他顶级包
jar -uf %MainJar% %packageName2%
然后把生成的jar,swc解压出来的catalog.xml,library.swf,一起扔到android-ARM文件夹里,把swc,extension.xml,p12放到外面
移动mm提供的libsmsiap.so,需要放到android-ARM/libs/armeabi-v7a下面
用一行命令打包,其中p12用自己的p12文件
set FLEX_SDK=D:\AIR_3.9
java -jar "%FLEX_SDK%\lib\adt.jar" -package -storetype PKCS12 -keystore czq.p12 -storepass 123456 -target ane com.mmsns.ane extension.xml -swc *.swc -platform Android-ARM -C Android-ARM mmiap .
搞定。。
另外打包apk的时候,记得把移动mm的jar包里的assets\mmiap打包进你的apk。
我还做了个一件打包生成ane的自动化批处理文件,包含在源码里面。
本教程的所有代码以及打包函数都在这里。
https://github.com/platformanes/android-mm-sms
第一篇文章,请拍砖。感谢Rect的先期研究。接下来我会放出小米还有移动mm平台,以及我接过的一些ios平台的教程。有些rect的版本改动不大的我就不放出来了,请自己到https://github.com/platformanes去下载。
希望使用air的人能更专注于开发游戏上面,而不要在ane接入上耗费太多时间。
air应用接入移动mm弱联网平台相关推荐
- 海量之道之弱联网优化
前言 [弱联网优化]作为海量之道2.0系列课题的基础方法论之一,望文生义,想必定是卖弄移动网络信号不佳时如何优化的奇技淫巧.恭喜你,感觉靠谱,不过我们还想多聊一点其它话题. 移动互联网颠覆着我们的生活 ...
- 移动网络为什么“慢”? 腾讯工程师分享弱联网优化之道
一.移动网络的特点 我们看到移动网络和移动互联网时代用户的行为有如下三个典型特点: 1)移动状态网络信号不稳定,高时延.易抖动丢包.通道狭窄: 2)移动状态网络接入类型和接入点变化频繁: 3)移动状态 ...
- IOT(32)---各大物联网平台对比
各大物联网平台对比 本文主要针对目前比较流行的物联网平台,进行功能的简单总结与对比. 目前来说,有以下几种物联网平台比较流行,他们分别是: 百度IoT平台 阿里物联平台 QQ物联平台 微信硬件平台 京 ...
- 优酷弱网平台落地实践
作者:孙长浩(火炏) 弱网环境下的质量保障一直是公认的难题,实际生活中每个人都会遇到弱网环境,比如用户在景区地铁里,高铁上,电梯中,景区周边等场景使用APP大概率都会遇到弱网场景.优酷作为视频内容AP ...
- 手游弱联网手游如何防作弊
本文是看到<乐元素CTO凌聪:弱联网手游如何防作弊?>之后,我觉得这篇文章讲的东西都很实用,贴合我们实际,比你看那些理论的书籍强多了,而且也非常佩服乐元素能把这些东西拿出来讲,虽然在某些人 ...
- 国标GB28181协议国标设备是否可以同时接入多个国标GB28181平台进行视频直播、录像检索、回看
国标GB28181视频云服务EasyGBS是基于开放式.大融合.全兼容.标准化的设计架构理念,依据<安全防范视频监控联网系统信息传输.交换.控制技术要求>(GB/T 28181-2011/ ...
- 重磅!全场景覆盖、全方位智能感知的视联网平台来了
在云计算.人工智能.物联网等技术的助推下,视频无处不在.我们看到,在不同应用场景中,海量视频设备和视频数据通过互联互通的方式形成强大的视联网,在智慧城市.智慧交通.工业能源.智慧零售等诸多领域中发挥着 ...
- 正点原子STM32f103ZE精英开发板实现基于ESP8266 WIFI模块温湿度数据上传至乐联网平台
文章目录 一.准备工作 二.实现流程 1.AT指令 2.接入乐联网平台 3.代码实现 三.数据可视化分析 一.准备工作 1.准备一块正点原子STM32f103ZE精英开发板 2.在某宝上购买好正点原子 ...
- ESP8266WiFi模块接入乐为物联平台
目录 了解乐为物联 乐为物联的框架结构 ESP8266初试小结 模拟工具在线调试 PC端 串口调试 STM32硬件调试 参考资料 前段时间利用手边的ESP8266小WiFi模块尝试接入了Yeelink ...
- “智慧血联网平台”亮相军民融合技术装备博览会
该平台可实现血液全程跟踪溯源,为大众提供安全.透明.便捷的用血服务. 一个打造智慧化血液管理新模式的血联网平台最近亮相第三届中国军民融合技术装备博览会.该平台可实现血液全程跟踪溯源,为大众提供安全.透 ...
最新文章
- AD20使用中文菜单
- 【Luogu4512】多项式除法(FFT)
- golang beego 自定义配置
- Scala变量介绍及入门示例
- android 查看多个图片,一分钟实现Android多张图片选择
- 02-Wifi通讯架构介绍
- boost::ratio_multiply相关的测试程序
- ASP.NET+SQL创建存储过程
- CodeForces - 91B Queue(单调队列+二分)
- SAP UI5 workthrough 12 sap.m.shell
- 2016年个人技术总结(前端)
- api postmain 鉴权_WebAPI常见的鉴权方法,及其适用范围
- 关于memcpy和 strcpy的区别 以及memset
- Python代码制作“恐龙跳一跳“小游戏
- 《游戏大师Chris Crawford谈互动叙事》一第 6 章 数学之苦劳
- 管理员身份修改hosts文件
- win101909要不要更新_近年最稳的Win10更新?Win10 1909值得升级吗
- kkfile配置https预览文件
- 根据生日定时发送生日祝福邮件
- ZigBee 3.0实战教程-Silicon Labs EFR32+EmberZnet-2-01:芯科的硬件解决方案EFR32