寫這篇博客主要是為了使用Eclipse導出Jar包和Res文件去給Unity調用。之前我寫過一篇博客(https://www.cnblogs.com/weiqiangwaideshijie/p/7715861.html)是直接將Unity導出Android工程去接入SDK,現在換另外一種模式去接入SDK,使用的通訊框架還是之前的。
一 為了避免不必要的錯誤,我這邊是用Unity去導出一個空的Android工程而不是直接在Eclipse去直接新建一個acivity,再去引用Unity的Classes.jar文件。用Eclipse打開unity導出的空的工程,然后將之前寫的通訊框架導入進去,並且刪除untiy自帶的三個類
二 UnityPlayerActivity引用頭條的庫文件(箭頭所指的),在將頭條的Res文件給copy到UnityPlayerActivtiy里面,不要去覆蓋,不然Unity自帶的一些東西被覆蓋掉,導致manifest里面找不到對應的配置和資源。
三 然后配置我們的Manifest清單文件,這個直接CopyDemo里面自己需要的配置就可以了。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.usfun.cbddn" android:installLocation="preferExternal"> <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true" /> <!--必須要有的權限--> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.GET_TASKS" /> <!--最好能提供的權限--> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 如果有視頻相關的廣告且使用textureView播放,請務必添加,否則黑屏 --> <uses-permission android:name="android.permission.WAKE_LOCK" /> <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:isGame="true" android:banner="@drawable/app_banner"> <activity android:label="@string/app_name" android:name="com.cw.androidsdk.MainActivity" android:screenOrientation="fullSensor" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LEANBACK_LAUNCHER" /> </intent-filter> <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> </activity> <!-- 以下為頭條網盟sdk的配置 start --> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:launchMode="singleTask" android:name="com.bytedance.sdk.openadsdk.activity.TTLandingPageActivity" /> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:launchMode="singleTask" android:name="com.bytedance.sdk.openadsdk.activity.TTVideoLandingPageActivity" /> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:launchMode="singleTask" android:name="com.bytedance.sdk.openadsdk.activity.TTRewardVideoActivity" /> <activity android:configChanges="keyboardHidden|orientation|screenSize" android:launchMode="singleTask" android:name="com.bytedance.sdk.openadsdk.activity.TTFullScreenVideoActivity" /> <activity android:launchMode="singleTask" android:name="com.bytedance.sdk.openadsdk.activity.TTDelegateActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <service android:name="com.bytedance.sdk.openadsdk.multipro.aidl.BinderPoolService" /> <service android:name="com.ss.android.socialbase.downloader.notification.DownloadNotificationService" /> <service android:name="com.ss.android.socialbase.downloader.downloader.DownloadService" /> <service android:name="com.ss.android.socialbase.downloader.downloader.IndependentProcessDownloadService" android:process=":downloader"> <intent-filter> <action android:name="com.ss.android.socialbase.downloader.remote" /> </intent-filter> </service> <service android:name="com.ss.android.socialbase.downloader.impls.DownloadHandleService" /> <service android:name="com.ss.android.socialbase.appdownloader.AppDownloadHandleService" /> <activity android:launchMode="singleTask" android:name="com.ss.android.socialbase.appdownloader.view.DownloadSizeLimitActivity" android:theme="@android:style/Theme.Dialog" /> <activity android:launchMode="singleTask" android:name="com.ss.android.socialbase.appdownloader.view.DownloadTaskDeleteActivity" android:theme="@android:style/Theme.Dialog" /> <activity android:launchMode="standard" android:name="com.ss.android.downloadlib.activity.InteractionMiddleActivity" /> <receiver android:name="com.ss.android.downloadlib.core.download.DownloadReceiver" /> <!-- authorities前綴請使用自己的app包名 --> <provider android:authorities="com.usfun.cbddn.fileprovider" android:exported="false" android:grantUriPermissions="true" android:name="android.support.v4.content.FileProvider"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> <provider android:authorities="com.usfun.cbddn.TTMultiProvider" android:exported="false" android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider" /> <!-- 頭條網盟sdk的配置 end --> <meta-data android:name="android.max_aspect" android:value="2.4" /> </application> <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="24" /> <uses-feature android:glEsVersion="0x00020000" /> <uses-feature android:name="android.hardware.touchscreen" android:required="false" /> <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" /> <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" /> </manifest>
四 以上的步驟,我們就把環境給配置好了,最后,按照文檔去寫入播放廣告的代碼。我這邊直接入獎勵廣告。(下面有些和Unity交互代碼是這個項目不需要的,看加粗傾斜的代碼塊)
MainActivity
package com.cw.androidsdk; import android.os.Bundle; import com.bytedance.sdk.openadsdk.AdSlot; import com.bytedance.sdk.openadsdk.TTAdConfig; import com.bytedance.sdk.openadsdk.TTAdConstant; import com.bytedance.sdk.openadsdk.TTAdManager; import com.bytedance.sdk.openadsdk.TTAdNative; import com.bytedance.sdk.openadsdk.TTAdSdk; import com.bytedance.sdk.openadsdk.TTAppDownloadListener; import com.bytedance.sdk.openadsdk.TTFullScreenVideoAd; import com.bytedance.sdk.openadsdk.TTRewardVideoAd; import com.sdk.api.SDKAPI; import com.sdk.api.SDKUtility; import com.unity3d.player.UnityPlayer; import com.unity3d.player.UnityPlayerActivity; import java.util.UUID; import org.json.JSONException; import org.json.JSONObject; import android.R.string; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.graphics.PixelFormat; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.text.TextUtils; import android.util.Log; import android.view.Window; import android.widget.Toast; public class MainActivity extends UnityPlayerActivity { public static Activity CurrentActivity; public static MyHandler myHandler;// private TTAdNative mTTAdNative; private TTRewardVideoAd mttRewardVideoAd; private TTAdManager ttAdManager; @Override protected void onCreate(Bundle arg0) { // TODO Auto-generated method stub super.onCreate(arg0); CurrentActivity=this; myHandler=new MyHandler(); //如果明確某個進程不會使用到廣告SDK,可以只針對特定進程初始化廣告SDK的content //if (PROCESS_NAME_XXXX.equals(processName)) { // TTAdSdk.init(context, config); //} } @Override protected void onStart() { super.onStart(); } @Override protected void onPause() { super.onPause(); } @Override protected void onResume() { super.onResume(); } public void onNewIntent(Intent newIntent){ super.onNewIntent(newIntent); } @Override protected void onStop() { super.onStop(); } @Override protected void onDestroy() { super.onDestroy(); } @Override protected void onRestart() { super.onRestart(); } public class MyHandler extends Handler { public MyHandler() { } public MyHandler(Looper L) { super(L); } /* * 錕斤拷錕斤拷錕斤拷錕斤拷錕叫達拷梅錕斤拷錕斤拷錕斤拷錕斤拷芨錕斤拷錕較� * */ @Override public void handleMessage(Message msg) { if(msg.what==SDKUtility.Init) { //"5001121" Log.i("android", "Init"); // Toast.makeText(CurrentActivity, "Init", Toast.LENGTH_SHORT).show(); TTAdSdk.init(CurrentActivity, new TTAdConfig.Builder() .appId(SDKAPI.AppID) .useTextureView(false) //使用TextureView控件播放視頻,默認為SurfaceView,當有SurfaceView沖突的場景,可以使用TextureView .appName("APP測試媒體") .titleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK) .allowShowNotify(true) //是否允許sdk展示通知欄提示 .allowShowPageWhenScreenLock(true) //是否在鎖屏場景支持展示廣告落地頁 .debug(false) //測試階段打開,可以通過日志排查問題,上線時去除該調用 .directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_3G) //允許直接下載的網絡狀態集合 .supportMultiProcess(false) //是否支持多進程,true支持 .build()); ttAdManager = TTAdSdk.getAdManager(); mTTAdNative = TTAdSdk.getAdManager().createAdNative(CurrentActivity); // Toast.makeText(CurrentActivity, "初始化", Toast.LENGTH_SHORT).show(); }else if(msg.what==SDKUtility.Load_Full_ScreenVideo) { //901121430 Log.i("android", "loadAd"); // Toast.makeText(CurrentActivity, "loadAd", Toast.LENGTH_SHORT).show(); loadAd(SDKAPI.AdsID, TTAdConstant.HORIZONTAL); else if(msg.what==SDKUtility.LoginIn) { Log.i("android", "LoginIn"); }else if(msg.what==SDKUtility.LoginOut) { Log.i("android", "logout"); }else if(msg.what==SDKUtility.Pay) { }else if(msg.what==SDKUtility.OnExit) { }else if(msg.what==SDKUtility.SubmitExtraDataOnEnterGame) { }else if(msg.what==SDKUtility.SubmitExtraDataOnExitGame) { }else if(msg.what==SDKUtility.GamePause) { Log.i("android", "GamePause" } private boolean mHasShowDownloadActive = false; private void loadAd(String codeId, int orientation) { //step4:創建廣告請求參數AdSlot,具體參數含義參考文檔 AdSlot adSlot = new AdSlot.Builder() .setCodeId(codeId) .setSupportDeepLink(true) .setImageAcceptedSize(1080, 1920) .setRewardName("金幣") //獎勵的名稱 .setRewardAmount(3) //獎勵的數量 .setUserID("user123")//用戶id,必傳參數 .setMediaExtra("media_extra") //附加參數,可選 .setOrientation(orientation) //必填參數,期望視頻的播放方向:TTAdConstant.HORIZONTAL 或 TTAdConstant.VERTICAL .build(); //step5:請求廣告 mTTAdNative.loadRewardVideoAd(adSlot, new TTAdNative.RewardVideoAdListener() { @Override public void onError(int code, String message) { Log.i("android", message); // Toast.makeText(CurrentActivity, message, Toast.LENGTH_SHORT).show(); UnityPlayer.UnitySendMessage("TouTiaoSDKMgr", "UnCanPlay", ""); } //視頻廣告加載后,視頻資源緩存到本地的回調,在此回調后,播放本地視頻,流暢不阻塞。 @Override public void onRewardVideoCached() { // Toast.makeText(CurrentActivity, "onRewardVideoCached", Toast.LENGTH_SHORT).show(); UnityPlayer.UnitySendMessage("TouTiaoSDKMgr", "CanPlay", ""); } //視頻廣告的素材加載完畢,比如視頻url等,在此回調后,可以播放在線視頻,網絡不好可能出現加載緩沖,影響體驗。 @Override public void onRewardVideoAdLoad(TTRewardVideoAd ad) { Log.i("android", "加載完畢"); mttRewardVideoAd = ad; UnityPlayer.UnitySendMessage("TouTiaoSDKMgr", "CanPlay", ""); // mttRewardVideoAd.setShowDownLoadBar(false); mttRewardVideoAd.setRewardAdInteractionListener(new TTRewardVideoAd.RewardAdInteractionListener() { @Override public void onAdShow() { // Toast.makeText(CurrentActivity, "onAdShow", Toast.LENGTH_SHORT).show(); UnityPlayer.UnitySendMessage("TouTiaoSDKMgr", "AdShow", ""); } @Override public void onAdVideoBarClick() { // Toast.makeText(CurrentActivity, "onAdVideoBarClick", Toast.LENGTH_SHORT).show(); } @Override public void onAdClose() { // Toast.makeText(CurrentActivity, "onAdClose", Toast.LENGTH_SHORT).show(); } //視頻播放完成回調 @Override public void onVideoComplete() { //Toast.makeText(CurrentActivity, "onVideoComplete", Toast.LENGTH_SHORT).show(); UnityPlayer.UnitySendMessage("TouTiaoSDKMgr", "OnAdPlayComplete", ""); } //視頻播放完成后,獎勵驗證回調,rewardVerify:是否有效,rewardAmount:獎勵梳理,rewardName:獎勵名稱 @Override public void onRewardVerify(boolean rewardVerify, int rewardAmount, String rewardName) { // Toast.makeText(CurrentActivity, rewardVerify+" "+rewardAmount+" "+rewardName, Toast.LENGTH_SHORT).show(); } @Override public void onVideoError() { // Toast.makeText(CurrentActivity, "onVideoError", Toast.LENGTH_SHORT).show(); UnityPlayer.UnitySendMessage("TouTiaoSDKMgr", "OnPlayFail", ""); } }); mttRewardVideoAd.setDownloadListener(new TTAppDownloadListener() { @Override public void onIdle() { mHasShowDownloadActive = false; } @Override public void onDownloadActive(long totalBytes, long currBytes, String fileName, String appName) { if (!mHasShowDownloadActive) { mHasShowDownloadActive = true; // Toast.makeText(CurrentActivity, "下載中,點擊下載區域暫停", Toast.LENGTH_SHORT).show(); } } @Override public void onDownloadPaused(long totalBytes, long currBytes, String fileName, String appName) { // Toast.makeText(CurrentActivity, "下載暫停,點擊下載區域繼續", Toast.LENGTH_SHORT).show(); } @Override public void onDownloadFailed(long totalBytes, long currBytes, String fileName, String appName) { // Toast.makeText(CurrentActivity, "下載失敗,點擊下載區域重新下載", Toast.LENGTH_SHORT).show(); } @Override public void onDownloadFinished(long totalBytes, String fileName, String appName) { // Toast.makeText(CurrentActivity, "下載失敗,點擊下載區域重新下載", Toast.LENGTH_SHORT).show(); } @Override public void onInstalled(String fileName, String appName) { // Toast.makeText(CurrentActivity, "安裝完成,點擊下載區域打開", Toast.LENGTH_SHORT).show(); } }); } }); } }
SDKAIP
package com.sdk.api; import android.R.integer; import android.R.string; import android.text.GetChars; import android.util.Log; import com.cw.androidsdk.MainActivity; public class SDKAPI { public static String AppID=""; public static String AdsID=""; /* * SDK��ʼ�� * */ public static void OnInit(String appId,String adsId) { Log.i("android", "SDKAPI OnInit"); AppID=appId; AdsID=adsId; Log.i("android", "appId:"+appId); Log.i("android", "adsId:"+adsId); MainActivity.myHandler.sendEmptyMessage(SDKUtility.Init); } /* * ���� * */ public static void OnLogIn() { Log.i("android", "SDKAPI OnLogIn"); MainActivity.myHandler.sendEmptyMessage(SDKUtility.LoginIn); } public static void LoadAd() { Log.i("android", "SDKAPI LoadAd"); MainActivity.myHandler.sendEmptyMessage(SDKUtility.Load_Full_ScreenVideo); } public static void PlayAd() { Log.i("android", "SDKAPI PlayAd"); MainActivity.myHandler.sendEmptyMessage(SDKUtility.Play_Full_SrcennVideo); } /* * �dz� * */ public static void OnLogOut() { Log.i("android", "SDKAPI OnLogOut"); MainActivity.myHandler.sendEmptyMessage(SDKUtility.LoginOut); } /* * ֧�� * */ public static void OnPay(float requestAmount ,int productIndex ,String productName,String orderID ) { Log.i("android", "SDKAPI OnPay"); MainActivity.myHandler.sendEmptyMessage(SDKUtility.Pay); } /* * ��Ϸ��ͣ * */ public static void OnGamePause() { Log.i("android", "SDKAPI OnGamePause"); MainActivity.myHandler.sendEmptyMessage(SDKUtility.GamePause); } /* * �ύ������Ϣ *������Ϸ * �˳���Ϸ *����ؿ�* */ public static void OnSubmitExtraData(int id) { } /* * ������Ϸ�ύ���� * */ public static void OnSubmitExtraDataOnExitGame() { Log.i("android", "SDKAPI OnSubmitExtraDataOnExitGame"); MainActivity.myHandler.sendEmptyMessage(SDKUtility.SubmitExtraDataOnExitGame); } /* * �˳���Ϸ�ύ���� * */ public static void OnSubmitExtraDataOnEnterGame() { Log.i("android", "SDKAPI OnSubmitExtraDataOnEnterGame"); MainActivity.myHandler.sendEmptyMessage(SDKUtility.SubmitExtraDataOnEnterGame); } /* * �˳���Ϸ * */ public static void OnExit() { Log.i("android", "SDKAPI OnExit"); MainActivity.myHandler.sendEmptyMessage(SDKUtility.OnExit); } }
SDKUtility
package com.sdk.api; import android.R.integer; public class SDKUtility { public static final int Init=0; public static final int LoginIn=1; public static final int LoginOut=2; public static final int Pay=3; public static final int GamePause=4; public static final int SubmitExtraDataOnEnterGame=5; public static final int SubmitExtraDataOnExitGame=6; public static final int OnExit=7; public static final int Load_Full_ScreenVideo=9; public static final int Play_Full_SrcennVideo=8; }
五 導出Jar包。注意只要導出Src文件。
用好壓去打開jar包,里面就是我們這邊寫的通訊框架的三個文件(如果之前里面沒刪除unity自帶的三個類,這里到處jar包的時候,就會帶有那三個類,在給Unity使用的話,會報錯,我們也可以在這里手動刪除這三個類)
6 下面就是在Unity里面去調用了,將Jar包,Res文件和引用到的庫,manifest文件導入到unity里面,目錄如下:
7 編寫C#腳本去調用Androidd 的接口並且接受返回的回調。
/************* ** Company: DX **SrtiptName:TouTiaoSDKMgr ** Auth: CW ** Des: 文本描述 ** Ver.: V1.0.0 *************/ using UnityEngine; using System.Collections; using UnityEngine.UI; public class TouTiaoSDKMgr : MonoBehaviour { private AndroidJavaClass _jc = null; private Transform Sendertran; public static TouTiaoSDKMgr Instance; public string appID; public string AdsID; public bool IsCanPlay = false; private E_AdsType _currentAdsType = E_AdsType.Nil; void Awake() { Instance = this; _jc = new AndroidJavaClass("com.sdk.api.SDKAPI"); OnInit(); Debug.Log("Awake"); LoadAd(); } public void OnInit() { Debug.Log("OnInit"); _jc.CallStatic("OnInit", appID, AdsID); } public void LoadAd() { Debug.Log("LoadAd"); _jc.CallStatic("LoadAd"); } public void PlayAd() { Debug.Log("PlayAd"); _jc.CallStatic("PlayAd"); _jc.CallStatic("LoadAd"); } /// <summary> /// 播放視頻廣告 /// </summary> public void PlayVideoAds(E_AdsType adsType, int id, Transform sender = null) { if (IsCanPlay) { PlayAd(); } } public void AdShow() { } public void OnAdPlayComplete() { } public void OnPlayFail() { } public void CanPlay() { IsCanPlay = true; } public void UnCanPlay() { IsCanPlay = false; } }