Java强联网代码
<1>添加包mmbilling1.2.1.jar和libcasdkjni.so、libidentifyapp.so两个文件
<2>loveshootBirdsAndroid.java
package com.qingxue.game; import mm.purchasesdk.OnPurchaseListener; import mm.purchasesdk.Purchase; import org.cocos2dx.lib.Cocos2dxActivity; import org.cocos2dx.lib.Cocos2dxGLSurfaceView; import android.app.ProgressDialog; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; public class LoveShootBirdsAndroid extends Cocos2dxActivity{ public final static int SHOW_STONE = 1; //单例 public static LoveShootBirdsAndroid instance = null; public Purchase purchase; private Context context; private ProgressDialog mProgressDialog; private IAPListener mListener; // 计费信息 private static final String APPID = "300008073477"; private static final String APPKEY = "ABF7F92E2A54F1AB"; // 计费点信息 private static final String LEASE_PAYCODE = "30000807347701"; private static native void getStone(); //购买石头,实现石头界面的刷新 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); instance = this; mProgressDialog = new ProgressDialog(this); mProgressDialog.setIndeterminate(true); mProgressDialog.setMessage("请稍候..."); context = this; IAPHandler iapHandler = new IAPHandler(this); /** * IAP组件初始化.包括下面3步。 */ /** * step1.实例化PurchaseListener。实例化传入的参数与您实现PurchaseListener接口的对象有关。 * 例如,此Demo代码中使用IAPListener继承PurchaseListener,其构造函数需要Context实例。 */ mListener = new IAPListener(this, iapHandler); /** * step2.获取Purchase实例。 */ purchase = Purchase.getInstance(); /** * step3.向Purhase传入应用信息。APPID,APPKEY。 需要传入参数APPID,APPKEY。 APPID,见开发者文档 * APPKEY,见开发者文档 */ try { purchase.setAppInfo(APPID, APPKEY); } catch (Exception e1) { e1.printStackTrace(); } /** * step4. IAP组件初始化开始, 参数PurchaseListener,初始化函数需传入step1时实例化的 * PurchaseListener。 */ try { purchase.init(context, mListener); } catch (Exception e) { e.printStackTrace(); } showProgressDialog(); } public Cocos2dxGLSurfaceView onCreateView() { Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this); // LoveShootBirdsAndroid should create stencil buffer glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8); return glSurfaceView; } static { System.loadLibrary("cocos2dcpp"); } private void showProgressDialog() { if (mProgressDialog == null) { mProgressDialog = new ProgressDialog(LoveShootBirdsAndroid.this); mProgressDialog.setIndeterminate(true); mProgressDialog.setMessage("请稍候....."); } if (!mProgressDialog.isShowing()) { mProgressDialog.show(); } } public void dismissProgressDialog() { if (mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.dismiss(); } } //获取实例 public static Object getInstance() { Log.e("instance", "jobj create Already"); return instance; } private Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch(msg.what) { case SHOW_STONE: buyStone(); break; } } }; public void buyStoneSend() { Log.e("buyStoneSend", "buyStoneSend"); Message msg = mHandler.obtainMessage(); msg.what = SHOW_STONE; msg.sendToTarget(); } public void buyStone() { Log.e("buyStone","buyStone"); order(instance, LEASE_PAYCODE, mListener); } public void order(Context context, String mPaycode , OnPurchaseListener listener) { Log.e("order","order"); try { purchase.order(context, mPaycode, mListener); } catch (Exception e) { e.printStackTrace(); } } public void MMpaySuccess(String code) { if(code == null) return; Log.e("MMpaySuccess",code); if(code.equals(LEASE_PAYCODE)) { Log.e("buyStoneSuccess","buyStoneSuccess"); //在这实现Java调用C++代码,实现石头的界面刷新 getStone(); } } public void MMpayFaild() { Log.e("faild","faild"); } } <3>IAPHandler.java package com.qingxue.game; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Handler; import android.os.Message; import android.widget.Toast; 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; private LoveShootBirdsAndroid context; public IAPHandler(Activity context) { this.context = (LoveShootBirdsAndroid) context; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); int what = msg.what; switch (what) { case INIT_FINISH: initShow((String) msg.obj); context.dismissProgressDialog(); break; default: break; } } private void initShow(String msg) { Toast.makeText(context, "初始化:" + msg, Toast.LENGTH_LONG).show(); } public void showDialog(String title, String msg) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(title); builder.setIcon(context.getResources().getDrawable(R.drawable.icon)); builder.setMessage((msg == null) ? "Undefined error" : msg); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dialog.dismiss(); } }); builder.create().show(); } } <4>IAPListener.java package com.qingxue.game; import java.util.HashMap; import mm.purchasesdk.OnPurchaseListener; import mm.purchasesdk.Purchase; import mm.purchasesdk.PurchaseCode; import android.content.Context; import android.os.Message; import android.util.Log; public class IAPListener implements OnPurchaseListener { private final String TAG = "IAPListener"; private LoveShootBirdsAndroid context; private IAPHandler iapHandler; public IAPListener(Context context, IAPHandler iapHandler) { this.context = (LoveShootBirdsAndroid) context; this.iapHandler = iapHandler; } @Override public void onInitFinish(int code) { Log.d(TAG, "Init finish, status code = " + code); Message message = iapHandler.obtainMessage(IAPHandler.INIT_FINISH); String result = "初始化结果:" + Purchase.getReason(code); message.obj = result; message.sendToTarget(); } @Override public void onBillingFinish(int code, HashMap arg1) { Log.e(TAG, "billing finish, status code = " + code); System.out.println("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 ) { /** * 商品购买成功或者已经购买。 此时会返回商品的paycode,orderID,以及剩余时间(租赁类型商品) */ if (arg1 != null) { paycode = (String) arg1.get(OnPurchaseListener.PAYCODE); if (paycode != null && paycode.trim().length() != 0) { result = result + ",Paycode:" + paycode; } tradeID = (String) arg1.get(OnPurchaseListener.TRADEID); if (tradeID != null && tradeID.trim().length() != 0) { result = result + ",tradeid:" + tradeID; } } //订购成功 context.MMpaySuccess(paycode); } else { /** * 表示订购失败。 */ //订购失败 result = "订购结果:" + Purchase.getReason(code); } if(paycode == null) context.MMpayFaild(); context.dismissProgressDialog(); System.out.println(result); } @Override public void onAfterApply() { // TODO Auto-generated method stub } @Override public void onAfterDownload() { // TODO Auto-generated method stub } @Override public void onBeforeApply() { // TODO Auto-generated method stub } @Override public void onBeforeDownload() { // TODO Auto-generated method stub } @Override public void onQueryFinish(int arg0, HashMap arg1) { // TODO Auto-generated method stub } @Override public void onUnsubscribeFinish(int arg0) { // TODO Auto-generated method stub } } AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.qingxue.game" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name" > <activity android:name=".LoveShootBirdsAndroid" android:configChanges="orientation" android:screenOrientation="landscape" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="mm.purchasesdk.iapservice.PurchaseService" android:exported="true" > <!-- android:process="mm.iapServices" > --> <intent-filter android:priority="230" > <action android:name="com.aspire.purchaseservice.BIND" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter android:priority="230" > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.SAFIAP.COMPONENT" > </category> </intent-filter> </service> <!-- android:excludeFromRecents="true" --> <!-- android:launchMode="singleInstance" --> <activity android:name="mm.purchasesdk.iapservice.BillingLayoutActivity" android:configChanges="orientation|keyboardHidden" android:theme="@android:style/Theme.Translucent" > <intent-filter android:priority="230" > <action android:name="com.qingxue.game.com.mmiap.activity" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <!-- android:process="safiap.framework.safframeworkmanager" begin --> <service android:name="safiap.framework.SafFrameworkManager" android:exported="true" android:process="safiap.framework" > <intent-filter android:priority="600" > <!-- ID for services declared in AIDL --> <action android:name="safiap.framework.sdk.ISAFFramework" /> </intent-filter> <intent-filter android:priority="600" > <!-- ID for services declared in AIDL --> <action android:name="safiap.framework.ACTION_START_DOWNLOAD" /> </intent-filter> <intent-filter android:priority="600" > <!-- ID for services declared in AIDL --> <action android:name="safiap.framework.ACTION_CHECK_UPDATE" /> </intent-filter> </service> <!-- receivers --> <receiver android:name="safiap.framework.CheckUpdateReceiver" > <intent-filter> <action android:name="safiap.framework.ACTION_CANCEL_NOTIFICATION" /> </intent-filter> <intent-filter> <action android:name="safiap.GET_SHARED_DATA" /> </intent-filter> <intent-filter> <action android:name="safiap.framework.ACTION_SET_TIMER" /> </intent-filter> </receiver> <activity android:name="safiap.framework.ui.UpdateHintActivity" android:configChanges="orientation" android:excludeFromRecents="true" android:launchMode="singleInstance" android:theme="@android:style/Theme.Translucent.NoTitleBar" > <intent-filter> <action android:name="safiap.framework.ACTION_TO_INSTALL" /> </intent-filter> <intent-filter> <action android:name="safiap.framework.ACTION_TO_INSTALL_IAP" /> </intent-filter> <intent-filter> <action android:name="safiap.framework.ACTION_NETWORK_ERROR_IAP" /> </intent-filter> <intent-filter> <action android:name="safiap.framework.ACTION_NETWORK_ERROR_FRAMEWORK" /> </intent-filter> </activity> <service android:name="safiap.framework.logreport.monitor.handler.LogreportHandler" android:process=":remote" /> <!-- android:process="safiap.framework.safframeworkmanager" end --> </application> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.READ_SMS" /> </manifest> C++部分 <1>头文件#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include <jni.h> #include "platform/android/jni/JniHelper.h" #include <android/log.h> #endif <2>支付部分代码C++调Javavoid GameScene::buyStone() { if(! CCDirector::sharedDirector()->isPaused()) { CCDirector::sharedDirector()->pause(); } #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断当前是否为Android平台 JniMethodInfo minfo; jobject jobj; if (JniHelper::getStaticMethodInfo(minfo, "com/qingxue/game/LoveShootBirdsAndroid", "getInstance", "()Ljava/lang/Object;")) { jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID); if (JniHelper::getMethodInfo(minfo, "com/qingxue/game/LoveShootBirdsAndroid", "buyStoneSend", "()V")) { CCLog("jobj start"); if(jobj == NULL) { return; } minfo.env->CallVoidMethod(jobj, minfo.methodID); if(CCDirector::sharedDirector()->isPaused()) { const char* LeavedStoneNum = ((CCString*)_gameScene->chnStrings->objectForKey("leavedStoneNum"))->m_sString.c_str(); _gameScene->_panelLayer->leavedStoneLabel->setString(CCString::createWithFormat("%s: %d",LeavedStoneNum, _gameScene->_panelLayer->leavedStoneNum)->getCString()); CCDirector::sharedDirector()->resume(); } CCLog("jobj end"); } } #endif }Java调用C++//在C++中对Java文件的private static native void getStone();方法实现为: #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断当前是否为Android平台 extern "C" { void Java_com_qingxue_game_GunStreet_getStone(JNIEnv* env, jobject thiz) { CCLog("Java_com_qingxue_game_GunStreet_getStone"); _gameScene->_panelLayer->leavedStoneNum += 15; const char* LeavedStoneNum = ((CCString*)_gameScene->chnStrings->objectForKey("leavedStoneNum"))->m_sString.c_str(); _gameScene->_panelLayer->leavedStoneLabel->setString(CCString::createWithFormat("%s: %d",LeavedStoneNum, _gameScene->_panelLayer->leavedStoneNum)->getCString()); } } #endif