4399支付SDK供flash游戏使用ANE的使用

简介:

 这两天对Flash游戏如何去接入android平台的SDK做了下研究,做了4399的支付SDK接入的工作,这里与大家分享下。


一、ANE的介绍

(网络描述也是一大堆,这里描述摘自http://blog.csdn.net/myquark/article/details/7904030)


Adobe AIR Native Extension,Adobe AIR的本地扩展,简称ANE。什么叫本地扩展?因为Adobe AIR是跨平台的一个运行时,可以在Windows,Mac,Android,iOS等系统上跑,正是因为其跨平台,所以它本身的功能就有局限性,不可能面面俱到;换句话来说,比如我们想在flash程序中调用一下系统的消息通知功能,但是AIR并没有这个功能,那么怎么办?这就要根据本地平台写段代码,让AIR委托本地平台去执行这段代码,这样就达到了拓展AIR程序的功能。换个角度来看问题,就好像系统有个dll文件,AIR可以去直接调用这个dll文件(这只是一个比方而已,让大家更容易理解,实际上AIR不能直接调用dll文件)。我们可以开发一个Android手机振动程序,然后打包成ANE,这样运行在AIR中的程序就可以调用写好的手机程序了。有了ANE机制,我们就可以开发很多Flash无法完成但是却可以使用的功能。


二、ANE开发步骤

 ANE的生成需要两个步骤,一个是生成本地的jar包,一个生成SWC库文件,最后进行编译合成。

  本文开发工具为fb 4.7 与eclipse为主


1、创建ane Android项目,生成本地jar包


准备工作

1)在eclipse中创建一个android的项目,假定命名为4399PaySDKANE_JAVA;

2) 将需要依赖的包(4399PaySdk.jar和FlashRuntimeExtensions.jar)添加到项目的libs目录下。

3)在项目属性中-java build path-Libraries下,添加以下

4399PaySdk.jar(4399的支付sdk包,在http://opensj.4399api.net/dev/downloadExchange可以下载到)

FlashRuntimeExtensions.jar(该包在E:\softinstall\ADOBE\Adobe Flash Builder 4.7\sdks\4.6.0\lib\android可找到)

4)在项目属性 - Java Build Path - Order and Export 下,将游戏 SDK 及其依赖的 JAR 包(4399PaySdk.jar)打上勾,确保能够被输出到生成的 JAR 包中;

 

准备工作有些多哈。接下来正式进入开发。


编码部分:


1、编写 FREContext 的派生类(YJPaymentApiContext.java)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package  com.sj4399.pay.ane;
import  java.util.HashMap;
import  java.util.Map;
import  com.adobe.fre.FREContext;
import  com.adobe.fre.FREFunction;
public  class  YJPaymentApiContext  extends  FREContext {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
     @Override
     public  void  dispose() {
     }
     @Override
     public  Map<String, FREFunction> getFunctions() {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
         return  null ;
     }
}

空的文件先不管。


2、编写 FREExtension 的派生类(如:YJPaymentApiExtension),在 createContext 方法中创建 YJPaymentApiContext的实例,并作为该方法的结果值返回。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package  com.sj4399.pay.ane;
import  com.adobe.fre.FREContext;
import  com.adobe.fre.FREExtension;
public  class  YJPaymentApiExtension  implements  FREExtension {
     @Override
     public  FREContext createContext(String arg0) {
         // TODO Auto-generated method stub
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
         return  new  YJPaymentApiContext();
     }
     @Override
     public  void  dispose() {
         // TODO Auto-generated method stub
     }
     @Override
     public  void  initialize() {
         // TODO Auto-generated method stub
     }
}


3、编写一系列 FREFunction 的派生类(如:YJFInit,YJFLogin……等),以实现每一个接口,每个接口方法用一个 FREFunction 派生类实现;


以YJFInit.java为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package  com.sj4399.pay.ane;
import  com.adobe.fre.FREContext;
import  com.adobe.fre.FREFunction;
import  com.adobe.fre.FREObject;
import  com.sj4399.pay.YjPaymentApi;
public  class  YJFInit  implements  FREFunction {
     private  static  final  String TAG =  "YJFInit" ;
     @Override
     public  FREObject call(FREContext context, FREObject[] args) {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
         YJPaymentApiContext yjac = (YJPaymentApiContext)context;
         YjPaymentApi.getInstance().init(yjac.getActivity());
         return  null ;
     }
}


我们通过

1
context.dispatchStatusEventAsync(callbackString,  "" );

进行回调给as3端。编写完其他接口类即可。


4、修改 YJPaymentApiContext的 getFunctions 方法,将实现的每一个 FREFunction 派生类添加到函数集合中,该函数集合作为该方法的结果值返回;此函数集合即承担接口调用职责

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package  com.sj4399.pay.ane;
import  java.util.HashMap;
import  java.util.Map;
import  com.adobe.fre.FREContext;
import  com.adobe.fre.FREFunction;
public  class  YJPaymentApiContext  extends  FREContext {
                                                                                                                                                                                                                                                                                                                                                                                                                                                    
     @Override
     public  void  dispose() {
     }
     @Override
     public  Map<String, FREFunction> getFunctions() {
         Map<String, FREFunction> mapFunc =  new  HashMap<String, FREFunction>();
         mapFunc.put( "getUser" new  YJFGetUser());
         mapFunc.put( "charge" new  YJFCharge());
         mapFunc.put( "destoryLogin" new  YJFLogout());
         mapFunc.put( "openLogin" new  YJFLogin());
         mapFunc.put( "init" new  YJFInit());
                                                                                                                                                                                                                                                                                                                                                                                                                                                           
         return  mapFunc;
     }
}


5、编写 ant 配置文件 build.xml,编译导出 JAR 包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<? xml  version = "1.0"  encoding = "UTF-8"  ?>
< project  name = "4399paysdk"  basedir = "."  default = "exportJar" >
                                                                                                                                                                                                                                                                                                                                                                                                                                   
     <!-- 设置全局变量 -->
     < property  name = "src.dir"  value = "src"  />
     < property  name = "classes.dir"  value = "bin/classes"  />
     < property  name = "dist.dir"  value = "dist"  />
     < property  name = "jar.file"  value = "4399PaySDKANEJava.jar"  />
     < property  name = "classes.encode"  value = "UTF-8"  />
     < property  name = "libs.dir"  value = "libs"  />
                                                                                                                                                                                                                                                                                                                                                                                                                                 
     < path  id = "classpath" >
         < fileset  dir = "${libs.dir}" >
             < include  name = "**/*.jar"  />
         </ fileset >
         < fileset  dir = "E:\softinstall\Java\jdk1.6.0_24\jre\lib" >
             < include  name = "**/*.jar"  />
         </ fileset >
         < fileset  dir = "E:\soft\android\adt-bundle-windows-x86\sdk\platforms\android-8" >
             < include  name = "android.jar"  />
         </ fileset >
         < fileset  dir = "E:\softinstall\ADOBE\Adobe Flash Builder 4.7\sdks\4.6.0\lib\android" >
             < include  name = "FlashRuntimeExtensions.jar"  />
         </ fileset >
     </ path >
                                                                                                                                                                                                                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                                                                                                                                                                                                                       
     < target  name = "init" >
         <!-- Create the time stamp -->
         < tstamp  />
     </ target >
                                                                                                                                                                                                                                                                                                                                                                                                                                 
     <!-- 编译源文件 -->
     < target  name = "buildFiles"  depends = "init" >
         < echo  message = "start building ....."  />
         < delete  dir = "${classes.dir}"  />
         < mkdir  dir = "${classes.dir}"  />
         < javac  deprecation = "on"  debug = "on"  encoding = "${classes.encode}"  srcdir = "${src.dir}"  destdir = "${classes.dir}"  classpathref = "classpath"  source = "1.6"  target = "1.6"  includeAntRuntime = "false"  />
         < copy  todir = "${classes.dir}" >
             <!-- copy config files -->
             < fileset  dir = "${src.dir}"  includes = "**/*.properties,**/*.xml,**/*.bsh,**/*.logic, **/*.hbm"  />
         </ copy >
     </ target >
                                                                                                                                                                                                                                                                                                                                                                                                                                 
     <!-- 导出jar文件 -->
     < target  name = "exportJar"  depends = "buildFiles" >
         < delete  dir = "${dist.dir}"  />
         <!-- Create the distribution directory -->
         < mkdir  dir = "${dist.dir}"  />
                                                                                                                                                                                                                                                                                                                                                                                                                                       
         < jar  destfile = "${dist.dir}/${jar.file}"  basedir = "${classes.dir}"
             < zipfileset  excludes = "META-INF/*.SF"  src = "${libs.dir}/4399PaySdk.jar" />
                                                                                                                                                                                                                                                                                                                                                                                                                                           
         </ jar >        
                                                                                                                                                                                                                                                                                                                                                                                                                                       
         < copy  todir = "${basedir}/../ane"  file = "${dist.dir}/${jar.file}"  />
     </ target >
</ project >

这样就完成了本地jar包的生成工作了。


2、创建flex库项目,生成swc库


准备工作:


1)创建项目

wKioL1Mfym6wAzwSAAIC2wb9fL0946.jpg

2)属性设置

wKiom1Mfyw-wm420AAKqRUbLYTw291.jpg


编码部分:


这边使用单例模式,创建actionscript代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package  com.sj4399.pay.ane
{
     import  flash.events.EventDispatcher;
     import  flash.events.IEventDispatcher;
     import  flash.events.StatusEvent;
     import  flash.external.ExtensionContext;
                                                                                                                                                                                                                                                                                                                                       
     public  class  YjPaymentApi  extends  EventDispatcher
     {
         public  static  const  EXTENSION_ID: String  "com.sj4399.pay.ane.android" ;
                                                                                                                                                                                                                                                                                                                                           
         private  var  _context:ExtensionContext;
         private  static  var  _instance:YjPaymentApi;
                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                           
         public  static  function  getInstance():YjPaymentApi{
             if (_instance ==  null ){
                 _instance =  new  YjPaymentApi();
             }
             return  _instance  as  YjPaymentApi;
         }
                                                                                                                                                                                                                                                                                                                                           
         public  function  YjPaymentApi(target:IEventDispatcher= null )
         {
             _context = ExtensionContext.createExtensionContext(EXTENSION_ID, null );
             if (_context ==  null ){
                 trace ( "YjPaymentApi(.as) constructor: _context is null,please call 'init()' first!" );
             }
                                                                                                                                                                                                                                                                                                                                               
             _context.addEventListener(StatusEvent.STATUS,onStatus);
             super (target);
         }
                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                           
         /**
          * SDK初始化
          */
         public  function  init(){
             _context.call( "init" , null );
         }
         /**
          * 登录
          */
         public  function  openLogin(){
             _context.call( "openLogin" , null );
         }
         /**
          * 注销
          */
         public  function  destoryLogin(){
             _context.call( "destoryLogin" , null );
         }
         /**
          * 充值
          * amount 充值金额
          * server 分服标识
          * mark 拓展标记
          */
         public  function  charge(amount: int ,server: int = 0 ,mark: String = null ){
             _context.call( "charge" ,amount,server,mark);
         }
                                                                                                                                                                                                                                                                                                                                           
         /**
          * 获取用户信息*/
         public  function  getUser(): String {
              return  String (_context.call( "getUser" ));
         }
                                                                                                                                                                                                                                                                                                                                           
         private  function  onStatus(e:StatusEvent): void {
             //trace("received status event:"+e.toString());
             var  eventObject: Object  = JSON.parse(e.code);
             var  evt:PayCallbackEvent =  new  PayCallbackEvent(Constants.EVENT_TYPE_4399PAYSDK_CALLBACK,
                 eventObject.callbackType, eventObject.code, eventObject.data);
             this .dispatchEvent(evt);
         }
                                                                                                                                                                                                                                                                                                                                           
     }
}


2、编写PayCallbackEvent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package  com.sj4399.pay.ane
{
     import  flash.events.Event;
     /**
      * 支付SDK回调事件
      */
     public  class  PayCallbackEvent  extends  Event
     {
                                                                                                                                                                                                                                                                                                                       
         private  var  _eventType:  String ;
         private  var  _callbackType:  String ;
         private  var  _code:  int ;
         private  var  _data:  Object ;
                                                                                                                                                                                                                                                                                                                       
         public  function  PayCallbackEvent(eventType: String , callbackType:  String , code:  int , data:  Object , bubbles: Boolean = false , cancelable: Boolean = false )
         {
             this ._eventType = eventType;
             this ._callbackType = callbackType;
             this ._code = code;
             this ._data = data;
             super (eventType, bubbles, cancelable);
         }
                                                                                                                                                                                                                                                                                                                       
         /**
          * 获取回调事件类型,Constants 中定义了回调事件类型常量(CALLBACKTYE_*),游戏应根据此回调事件类型对事件进行不同的处理。
          * @return
          *
          */
         public  function  get  callbackType():  String  {
             return  _callbackType;
         }
                                                                                                                                                                                                                                                                                                                       
         /**
          * 获取回调事件状态码,表示SDK返回的执行结果和状态,StatusCode 中定义了回调事件状态码常量。不同回调事件类型的事件有自己对应的状态列表,游戏应根据此状态码进行不同的处理。
          * @return
          *
          */
         public  function  get  code():  int  {
             return  _code;
         }
                                                                                                                                                                                                                                                                                                                       
         /**
          * 获取SDK返回的执行结果数据,不同回调事件类型的事件具有不同的数据结构,游戏应根据回调事件类型来获取相应的数据。
          * @return
          *
          */
         public  function  get  data():  Object  {
             return  _data;
         }}
}


3、定义常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package  com.sj4399.pay.ane
{
     public  class  Constants
     {
         public  static  const  EVENT_TYPE_4399PAYSDK_CALLBACK =  "4399_pay_sdk_callback" ;
                                                                                                                                                                                                                                                                          
         public  static  const  CB_LOGIN: String  "login" ;
         public  static  const  CB_LOGOUT: String  "logout" ;
         public  static  const  CB_CHARGE: String  "charge" ;
                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                          
         public  static  const  STATUS_LOGIN_COMPLETE: int  = - 1 ; //登录完成
         public  static  const  STATUS_LOGIN_CANCEL: int  = - 2 //取消登录
         public  static  const  STATUS_LOGOUT_COMPLETE: int  = - 3 //取消登录
         public  static  const  STATUS_CHARGE_COMPLETE: int  = - 4 //充值完成
         public  static  const  STATUS_CHARGE_CANCEL: int  = - 5 //取消充值
                                                                                                                                                                                                                                                                          
     }
}

编译在bin目录下可以看到swc库文件。


3、生成ANE

  拷贝生成的本地jar文件 与swc文件到要创建ANE的目录下

wKioL1MfzI_ji7T2AADbEQgvUJM369.jpg

这里我们可以看到有个extension.xml,这个就是用于as3代码里面的的拓展标识,用于as3调用jar包中的函数,里面内容是

1
2
3
4
5
6
7
8
9
10
11
12
13
< extension  xmlns = "http://ns.adobe.com/air/extension/2.5" >
     < id >com.sj4399.pay.ane.android</ id >
     < versionNumber >1</ versionNumber >
     < platforms >
         < platform  name = "Android-ARM" >
             < applicationDeployment >
                 < nativeLibrary >4399PaySDKANEJava.jar</ nativeLibrary >
                 < initializer >com.sj4399.pay.ane.YJPaymentApiExtension</ initializer >
                 < finalizer >com.sj4399.pay.ane.YJPaymentApiExtension</ finalizer >
             </ applicationDeployment >
         </ platform >
     </ platforms >
</ extension >

 

signature.p12是air生成的密钥,相信air游戏开发者都清楚这个内容。


以解压的方式打开SWC,解压其中的library.swf到Android-ARM文件夹中。

wKiom1MfzgTQpYkWAAHftNFQRW4246.jpg


将jar包和第三方所需要的res资源文件拷贝到Android-ARM中,如图

wKiom1MfzlOiDSo2AACD6pc1nJU317.jpg


这里都做好了,接下来就是生成ANE了,我们编写一个批处理文件

1
2
3
4
5
6
7
@REM 打包 .ane
SET SWC_FILE=4399PaySDK_ANE_AS.swc
SET ANE_FILE=4399PaySDK.ane
SET JAR_FILE=4399PaySDKANEJava.jar
SET FLEX_ADT_CMD=java -jar  "E:\softinstall\ADOBE\Adobe Flash Builder 4.7\sdks\4.6.0\lib\adt.jar"
%FLEX_ADT_CMD% -package -tsa none -storetype pkcs12 -keystore signature.p12 -storepass 123456 -target ane %ANE_FILE% extension.xml -swc %SWC_FILE% -platform Android-ARM -C Android-ARM .
pause


好了,这样就可以生成我们的所需要的ANE了.至于如何调用相信大家都知道,这里就不多说了。



本文转自xuzw13 51CTO博客,原文链接:http://blog.51cto.com/xuzhiwei/1373830,如需转载请自行联系原作者

相关文章
|
2月前
|
Java 应用服务中间件 开发工具
如何使用支付宝沙箱环境支付并公网调用sdk创建支付单服务
如何使用支付宝沙箱环境支付并公网调用sdk创建支付单服务
|
3月前
|
Java API 开发工具
支付与银行业线上客户协议应用中的DocuSign集成方式选择——SDK和API
跨境支付公司和Docusign进行集成时,碰到问题时的解决方案。分别用SDK和API集成后的各自使用体验。
48 2
支付与银行业线上客户协议应用中的DocuSign集成方式选择——SDK和API
|
7月前
|
开发工具 Python
Django使用支付宝SDK完整网站应用支付。
Django使用支付宝SDK完整网站应用支付。
172 0
|
移动开发 Java 开发工具
Android客户端三步完成支付宝支付SDK接入
Android客户端三步完成支付宝支付SDK接入
1916 0
|
6月前
|
API 开发工具 C#
一套基于 .NET Core 开发的支付SDK集 - paylink
一套基于 .NET Core 开发的支付SDK集 - paylink
|
6月前
|
开发框架 移动开发 前端开发
基于.Net Core开发的支付SDK,简化支付功能开发
基于.Net Core开发的支付SDK,简化支付功能开发
81 0
|
开发工具 iOS开发
支付SDK适配iPhone X 公告
尊敬的蚂蚁金服开放平台合作伙伴:     苹果已于近期发布最新机型iPhone X,该机型的视觉和页面布局较以往机型有调整。 目前,iOS端的支付宝App支付SDK已适配包括iPhone X在内的iPhone机型,并上传至蚂 蚁金服开放平台,请各位合作伙伴更新该支付SDK,确保用户可以获得最佳的使用体验。
344 0
|
开发工具 iOS开发
ios授权登录sdk分享(不包含支付功能)
说明:   为了解决开发者在ios中使用支付宝授权接口产品上架问题,所以推出授权登录相关sdk(不包含支付功能) 如果商户有使用到支付宝登录授权功能接口,可以参考使用。   ios SDK:AFAuthSDK.
664 0
|
17天前
|
JavaScript Java Maven
云效产品使用常见问题之android sdk 构建出aar后,上传到私有maven仓库失败如何解决
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。