中国移动SDK计费开发手册(转载)

来源:互联网 发布:淘宝the mountain 编辑:程序博客网 时间:2024/05/16 09:07

 

 

 

 

中国移动动漫基地

 

 

 

 

 

 

开发指南

 

 

V 1.2

 

2013-11

 

 

 

本文档主要描述了中国移动动漫基地的短信计费基本机制,以及指导开发者如何在应用中使用应用内计费功能。文档中提供了开发者需要做哪些准备、如何获取所需资源及如何使用SDK等的指引,同时也提供了相关的范例供开发者学习使用。

 

目      录

 

1.1       开发应用... 2

1.1.1准备开发环境...2

1.1.2 下载和导入SDK. 3

2.4.3 使用SDK. 4

1.2       开发者开发应用注意事项... 5

2      应用内计费SDK使用手册. 5

2.1       SDK组成和接口说明... 5

2.1.1    SMSPaycodeAPI说明... 6

2.1.2    OnSMSPaycodeListener7

2.1.3    OnSMSPaycodeListener中返回数据说明... 7

2.2       业务流程及要点说明... 8

2.2.1         主要流程... 8

2.3       SDK调用时序... 9

2.3.1         订购... 9

2.4       示例代码... 9

3.4.1 应用混淆... 11

3      开发者集成弱联网计费版本教程. 13

3.1       AndroidManifest.xml修改... 13

3.2       实现OnSMSPaycodeListener. 14

3.3       调用计费接口... 15

 

1.1     开发应用

1.1.1准备开发环境

在使用应用内计费接口之前,请确认Eclipse、JDK、Android SDK已经安装,并正常使用。如果尚未安装,请参考以下资源,安装过程不再赘述。

Eclipse:

http://www.eclipse.org/downloads/

 

JDK:

http://www.oracle.com/technetwork/java/javase/downloads/index.html

 

Android SDK:

http://developer.android.com/SDK/index.html

 

1.1.2 下载和导入SDK

SDK以jar文件的形式提供给开发者在程序中使用,同时提供HTML格式的API文档供查阅相关类、方法、常量等说明。

 

以下内容将说明如何在Eclipse中,将jar文件加入到应用工程中去。

1.       将Cartoonsmsbilling1.0.0.jar文件拷贝到应用工程的libs目录下,如没有该目录,可新建;

2.       在ProjectExplorer中右击鼠标,从弹出的菜单中,选中“Properties”;

3.       在Properties窗口的左侧菜单项中,点击“Java Build Path”,并在右侧选中“Libraries”;

4.       点击“Add JARs…”按钮,在弹出窗口中,选中jar文件,如下图1所示。

 

图表 1 添加jar文件

最后,检查ReferencedLibraries中是否可以看到jar文件,如下图2所示。如果可以,则表示配置成功,否则,请检查上述步骤是否执行成功。

 

 

图表 2 检查

5.      *将libdmsmsiap.so复制到libs\armeabi目录下

 

2.4.3 使用SDK

*SDK使用注意事项

使用SDK可依照以下五个步骤。

1)     实现OnSMSPaycodeListener

OnSMSPaycodeListener是应用内计费的监听器,检查的结果通过onBillingFinish返回给调用者。

以上这些方法中的参数StatusCode的取值,均定义在PurchaseCode类的常量中,包括AUTH_XXX和COPYRIGHT_XXX等,每个常量具体表达的含义,请参考API文档, 也可使用SMSPurchase.getDescription(int)方法获取具体描述。

 

2)      增加权限声明

打开应用的AndroidManifest.xml文件,增加权限

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

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

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

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

以确保可以正常读取手机的IMSI/IMEI。

 

 

1.2     开发者开发应用注意事项

1)        为保证自身敏感数据(APPID、APPKEY、PAYCODE)的安全性,请尽量采用加密等手段保存,避免以常量字符串形式出现于源码。

2)        为保护自身数据和付费点,开发完成后,建议对APK做混淆处理。

3)        应用中不能同时发起两起或者以上的订购操作,比如不能同时启动两个查询订单的线程。

4)        可重复购买的计费点,在两次订购之间,目前有时间限制(目前定义30秒钟)

5)        应用升级,开发如果需要升级目前已投入商用的APP,需要重新上传后,用户通过动漫基地或者其他与移动有关渠道升级。如果采用自升级,可能会因为APP数据与移动服务器中数据不一致,导致APP中无法正常发起交易业务。

6)        中国移动部分省份已经开始销售147号段的SIM卡,该号段同样可以使用IAP进行计费。请应用开发者注意判断此号段的SIM卡,以免造成不必要的麻烦。

 

 

 

 

2     应用内计费SDK使用手册

2.1     SDK组成和接口说明

SDK公开的接口包括:

 

 

2.1.1  SMSPaycodeAPI说明

SMSPaycode对象是SDK提供给开发者发起订购的接口。

开发者在实例化该对象后,调用其中的函数可以处理相应的业务。

1)  构造实例

SMSPaycode对象的创建使用了单例模式,不需要重复创建:

SMSpurcode = SMSPaycode.getInstance();

 

2)  各参数设置:

SMSPaycode.setAppInfo(appid, appkey);  //设置计费应用ID和Key (必须)

 

 

3)  订购:

传统接口:

调用SMSPurchase对象中的smsorder函数,传入相应的参数:

l       payCode,计费点(见本文档2.3)

l       Listener,本参数是开发实现OnSMSPaycodeListener对象的实例,主要用于监听各个业务的结果。

// 订购一个商品

SMSPaycode.smsorder(context, paycode, listener);  

订购具体的结果在OnSMSPaycodeListener中的onBillingFinish()中获得。

        使用UserData接口:

l       payCode,计费点(见本文档2.3)

l       Listener,本参数是开发实现OnSMSPaycodeListener对象的实例,主要用于监听各个业务的结果。

l       Userdata,开发者透传数据。

Userdata用于开发者上传的任意数据,该数据需要限制在16个字节以内。

// 订购一个商品

SMSPaycode.smsorder(context, paycode, listener,userdata); 

 

     

2.1.2  OnSMSPaycodeListener

应用内计费各种操作(初始化,订购)监听器。开发者通过实现该接口中各个接口来监听各种业务操作的状态:

// 订购返回接口:

void onBillingFinish(final int returncode, final HashMap<String, Object> returnObject) 

   Returncode的定义在PurchaseCode类中,具体含义可以通过getDescription()获取。

2.1.3  OnSMSPaycodeListener中返回数据说明

   正如前面所描述的一样,初始化,订购接口的返回值在OnSMSPaycodeListener中得到。

   returnObject中定义的数据主要有几种:

// 计费点代码

public final static String PAYCODE = "Paycode";

//交易ID

public final static String PAYCODE = "TradeID";

 

   上面这些值包含在onBillingFinish中参数Hashmap中。各个接口返回的数据不一样。

    上面这些值所代表的意义如下:

     Paycode,表示此次交易的计费点

TradeID,表示此次交易的id

1)订购接口

         订购接口在订购成功后,会返回上面一个值。如果订购失败,则不返回上面任何值。

2.2     业务流程及要点说明

2.2.1  主要流程

初始化

订购

 

 


首次计费时,或者初始化,SDK会发送短信激活。之后,只要不失效,将不会再次触发。

 

 

2.3     SDK调用时序

2.3.1  订购

 

注意:

1.       本期SDK在触发订购之后,接管全部UI,所以应用在调用smsorder接口之后不需要做任何处理, 所有UI处理均已由SDK处理。

 

2.       onBillingFinish()方法在订购界面退出后,才会返回给应用。

 

2.4     示例代码

下面将通过demo中的代码具体说明如何使用本SDK。

APPID,APPKEY,PayCode设置。

       在demo程序中,APPID,APPKEY,PayCode默认赋值为00000000000。请根据在2.3节中操作,将生成的APPID,APPKEY,PayCode分别填入。

         // 计费应用信息(demo测试)

         private static final String APPID ="00000000000";

         private static final String APPKEY ="00000000000";

         // 计费点信息

         private static final String LEASE_PAYCODE ="00000000000";// 单次

 

OnSMSPaycodeListener接口实现

开发者使用SDK,需要自定义实现一个接口OnSMSPaycodeListener,该接口用来将初始化,订购的结果或者状态返回给APP。Demo中具体实现如下:

public class IAPListener implements OnSMSPaycodeListener {

    private final String TAG = "IAPListener";

    private Democontext;

    private IAPHandleriapHandler;

 

    public IAPListener(Context context, IAPHandler iapHandler) {

       this.context = (Demo) context;

       this.iapHandler = iapHandler;

    }

 

   

    public void onBillingFinish(int code, HashMap arg1) {

       Log.d(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,tradeID          */

           if (arg1 != null) {

paycode=(String)arg1.get(OnSMSPaycodeListener.PAYCODE);

              if (paycode != null && paycode.trim().length()!= 0) {

                  result = result + ",Paycode:" + paycode;

              }

      tradeID=(String)arg1.get(OnSMSPaycodeListener.TRADEID);

              if (tradeID != null && tradeID.trim().length()!= 0) {

                  result = result + ",tradeid:" + tradeID;

              }

           }

       } else {

           /**

            * 表示订购失败。

            */

           result = "订购结果:" + SMSPaycode.getReason(code);

       }

       context.dismissProgressDialog();

       System.out.println(result);

 

    }

SDK初始化

         本SDK初始化很简单,只需要实例化SDK中SMSPaycode类即可,再根据APP的实际情况设置相应的参数。Demo中的代码如下:

        @Override

    public void onCreate(Bundle savedInstanceState){

/**

        * IAP组件初始化.包括下面3步。

        */

       /**

        * step1.实例化OnSMSPaycodeListener。实例化传入的参数与您实现OnSMSPaycodeListener接口的对象有关。

        * 例如,此Demo代码中使用IAPListener继承OnSMSPaycodeListener,其构造函数需要Context实例。

        */

       mListener = new IAPListener(this, iapHandler);

       /**

        * step2.获取Purchase实例。

        */

       purchase= SMSPaycode.getInstance();

       /**

        * step3.Purhase传入应用信息。APPIDAPPKEY需要传入参数APPIDAPPKEY APPID,见开发者文档

        * APPKEY,见开发者文档

        */

       try {

           purchase.setAppInfo(APPID,APPKEY);

       } catch (Exception e1) {

           e1.printStackTrace();

       }

      

}

   SDK订购接口的调用

1)订购接口调用

 

       订购只能可重复购买这种类型的订购,此版本应用内计费SDK包含有1个订购接口

1.    订购接口

public void smsOrder(Contextcontext, String paycode,OnSMSPaycodeListener listener)

需要传入Activity实例,paycode,以及OnSMSPaycodeListener的实例

3.4.1 应用混淆

如果您的应用需要混淆,请参照下面的格式修改proguard.cfg。然后使用ProGuard工具对您的应用进行混淆。

-optimizationpasses 5

-dontusemixedcaseclassnames

-dontskipnonpubliclibraryclasses

-dontpreverify

-dontwarn

-dontnote

-verbose

-optimizations!code/simplification/arithmetic,!field/*,!class/merging/*

-libraryjarslibs/mmsmsbilling1.2.0.jar

 

-keep public class* extends android.app.Activity

-keep public class* extends android.app.Application

-keep public class* extends android.app.Service

-keep public class* extends android.content.BroadcastReceiver

-keep public class* extends android.content.ContentProvider

-keep public class* extends android.app.backup.BackupAgentHelper

-keep public class* extends android.preference.Preference

-keep public classcom.android.vending.licensing.ILicensingService

 

-keepclasseswithmembernames class * {

    native <methods>;

}

-keepclasseswithmembernames class * {

    public <init>(android.content.Context,android.util.AttributeSet);

}

 

-keepclasseswithmembernames class * {

    public <init>(android.content.Context,android.util.AttributeSet, int);

}

 

-keepclassmembers enum* {

    public static **[] values();

    public static ** valueOf(java.lang.String);

}

 

-keep class *implements android.os.Parcelable {

  public static finalandroid.os.Parcelable$Creator *;

}

-keep public class sms.purchasesdk.cartoon.OnSMSPaycodeListener{*;}

-keep public classsms.purchasesdk.cartoon.PurchaseCode {*;}

-keep public enumsms.purchasesdk.cartoon.OnSMSPaycodeListener$** {

    **[]$VALUES;

   public *;

}

具体修改如下,如果要混淆某个包,则在proguard.cfg中增加:

 –keep class 应用某个包名.**

注意:您在混淆时,请务必在cfg文件中添加红色的代码,否则可以会导致您的程序运行出错。蓝色部分的代码,如果您使用eclipse工具混淆则需要添加,如果是ant编写的混淆脚本则不需要添加。

如果您使用ant脚本编译,可以参照build.xml中的混淆脚本修改您的脚本

   <target name="optimize"depends="compile">  

        <echo>optimize classes are put to"${out.absolute.dir}"  .</echo>  

        <jarbasedir="${out.classes.absolute.dir}"destfile="${out.absolute.dir}/temp.jar"/>  

                   <javajar="${jar.proguard}\proguard.jar" fork="true"failonerror="true"> 

                            <jvmargvalue="-Dmaximum.inlined.code.length=32"/>

                            <argvalue="@${jar.proguard}\proguard.cfg"/> 

                            <argvalue="-injars ${out.absolute.dir}/temp.jar"/> 

                            <argvalue="-outjars ${out.absolute.dir}/optimized.jar"/> 

                            <argvalue="-libraryjars ${SDK.dir}/platforms/android-4/android.jar"/>                  

                            <argvalue="-libraryjars ./libs/mmsmsbilling1.2.0.jar"/> 

 

                   </java> 

        <deletefile="${out.absolute.dir}/temp.jar"/>  

        <deletedir="${out.classes.dir}" failonerror="false" />  

        <mkdirdir="${out.classes.dir}"/>  

        <unzipsrc="${out.absolute.dir}/optimized.jar"dest="${out.classes.absolute.dir}"/>  

        <deletefile="${out.absolute.dir}/optimized.jar"/>  

</target>  

Proguard的路径在local.properties中进行修改。Demo中有个文件夹proguard中存放的是proguard.jar文件和proguard.cfg

3       开发者集成弱联网计费版本教程

弱联网计费sdk版本使用到了android中的部分权限。因此,在集成弱联网计费sdk需要做如下一些工作

3.1    AndroidManifest.xml修改

3.1.1              添加receiver
<receiver  android:name="sms.purchasesdk.cartoon.sms.SMSReceiver"> 

         <intent-filterandroid:exported="false"> 

              <actionandroid:name="aspire.iap.SMS_SEND_ACTIOIN"/>    

              <actionandroid:name="aspire.iap.SMS_DELIVERED_ACTION"/>

         </intent-filter> 

    </receiver>

    短信计费sdk需要在AndroidManifest.xml中注册一个receiver,这个receiver的作用是用来判断短信是否发送。

 

3.2    实现OnSMSPaycodeListener

OnSMSPaycodeListener的作用请参考3.1.3节的说明。本节仅说明如何在程序中实现这个接口 。

public class IAPListener implements OnSMSPaycodeListener{

   private final String TAG = "IAPListener";

   private Democontext;

   private IAPHandleriapHandler;

 

   public IAPListener(Context context, IAPHandler iapHandler) {

      this.context = (Demo) context;

      this.iapHandler = iapHandler;

   }

 

  

   @Override

   public void onBillingFinish(int code,HashMap arg1) {

      Log.d(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) {

         /**

          * 商品购买成功或者已经购买。此时会返回商品的paycodeorderID,以及剩余时间(租赁类型商品)

          */

         if (arg1 !=null) {

            paycode = (String) arg1.get(OnSMSPaycodeListener.PAYCODE);

            if (paycode !=null && paycode.trim().length() != 0) {

                result = result + ",Paycode:" + paycode;

            }

            tradeID = (String) arg1.get(OnSMSPaycodeListener.TRADEID);

            if (tradeID !=null && tradeID.trim().length() != 0) {

                result = result + ",tradeid:" + tradeID;

            }

         }

      } else {

         /**

          * 表示订购失败。

          */

         result = "订购结果:" + SMSPaycode.getReason(code);

      }

      context.dismissProgressDialog();

      System.out.println(result);

 

   }

 

}

 

3.3    调用计费接口

具体调用可参考实例代码中3.4.1节 。

 

0 0
原创粉丝点击