https://mp.weixin.qq.com/s/-0H36WDyDcGy4hCEL-CXmw
0、核心思路:
js可以调用java的静态方法,jsb函数
java也可以调用js的方法
1、创建libs文件夹,并copy open_ad_sdk.aar
注意要在studio内创建libs目录(project视角)!后面的操作也是,每操作一步,File->sync project with gradle files
如果发现 有问题
打开项目主工程(通常是app module)的build.gradle
将compileSdkVersion指定为28
android {
//编译版本号
compileSdkVersion 28
.....................
}
2、用android studio打开项目,在Gradle Scripts下的 build.gradle(Module:cyboss),注意有多个同名文件
在dependencies{
下copy
implementation('com.android.support:support-v4:24.2.0')
}
在 defaultConfig添加
ndk {
// 设置支持的 SO 库构架,注意这里要根据你的实际情况来设置 abiFilters ‘armeabi-v7a’, ‘arm64-v8a’, ‘x86’, ‘x86_64’, ‘arm64-v8a’
abiFilters 'armeabi-v7a'
}
3、
AndroidManifest 配置 permission 和 provider
provider 放在
4、AppActivity.java 需要引用
import android.content.Intent;
import android.content.res.Configuration;
import com.bytedance.sdk.openadsdk.TTAdConfig;
import com.bytedance.sdk.openadsdk.TTAdConstant;
import com.bytedance.sdk.openadsdk.TTAdManager;
import com.bytedance.sdk.openadsdk.TTAdSdk;
5、遇到未定义的类型,也需要引用
import com.bytedance.sdk.openadsdk.TTAdNative;
6、JS内调用java的静态方法
jsb方法,可以调用java类里面的静态方法
反过来也可以
7、xml配置
android:name="org.cocos2dx.javascript.MyApplication"
放在applicaiton 标签的第一个
8、express模版广告
AdSlot adSlot = new AdSlot.Builder()
.setCodeId(codeId)
.setSupportDeepLink(true)
.setImageAcceptedSize(1080, 1920)
.setRewardAmount(1) //奖励的数量
//模板广告需要设置期望个性化模板广告的大小,单位dp,激励视频场景,只要设置的值大于0即可
.setExpressViewAcceptedSize(500,500)
.setUserID("5081714")//用户id,必传参数
.setOrientation(orientation) //必填参数,期望视频的播放方向:TTAdConstant.HORIZONTAL 或 TTAdConstant.VERTICAL
.build();
激励视频等可能是模版类型的广告,参数需要使用express;
9、android resource link问题
关闭项目,重启
10、MyApplicaiton.java
package org.cocos2dx.javascript;
import android.app.Application;
public class MyApplication extends Application {
@Override
public void onCreate(){
super.onCreate();
//穿山甲SDK初始化
//强烈建议在应用对应的Application#onCreate()方法中调用,避免出现content为null的异常
TTAdManagerHolder.init(this);
}
}
11、TTAdManagerHolder.java 从sdk demo 内 copy进来
12、AndroidManifest.xml
13、file_paths.xml 创建时选择类型为 APP APPLICATIONS.XML
14、DisplayUtil.java
package org.cocos2dx.javascript;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
public class DisplayUtils {
private DisplayUtils()
{
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
/**
* 获得屏幕宽度
*
* @param context
* @return
*/
public static int getScreenWidth(Context context)
{
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.widthPixels;
}
/**
* 获得屏幕高度
*
* @param context
* @return
*/
public static int getScreenHeight(Context context)
{
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.heightPixels;
}
/**
* 获得状态栏的高度
*
* @param context
* @return
*/
public static int getStatusHeight(Context context)
{
int statusHeight = -1;
try
{
Class> clazz = Class.forName("com.android.internal.R$dimen.xml");
Object object = clazz.newInstance();
int height = Integer.parseInt(clazz.getField("status_bar_height")
.get(object).toString());
statusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e)
{
e.printStackTrace();
}
return statusHeight;
}
/**
* 获取当前屏幕截图,包含状态栏
*
* @param activity
* @return
*/
public static Bitmap snapShotWithStatusBar(Activity activity)
{
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
int width = getScreenWidth(activity);
int height = getScreenHeight(activity);
Bitmap bp = null;
bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
view.destroyDrawingCache();
return bp;
}
/**
* 获取当前屏幕截图,不包含状态栏
*
* @param activity
* @return
*/
public static Bitmap snapShotWithoutStatusBar(Activity activity)
{
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
int width = getScreenWidth(activity);
int height = getScreenHeight(activity);
Bitmap bp = null;
bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height
- statusBarHeight);
view.destroyDrawingCache();
return bp;
}
}
15、
AppActivity.java
/**************************************************************************** Copyright (c) 2015-2016 Chukong Technologies Inc. Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************/ package org.cocos2dx.javascript; import org.cocos2dx.lib.Cocos2dxActivity; import org.cocos2dx.lib.Cocos2dxGLSurfaceView; import org.cocos2dx.lib.Cocos2dxJavascriptJavaBridge; import android.os.Bundle; import android.content.Intent; import android.content.res.Configuration; import android.support.annotation.MainThread; import android.util.Log; import android.view.View; import com.bytedance.sdk.openadsdk.AdSlot; 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.TTInteractionAd; import com.bytedance.sdk.openadsdk.TTNativeExpressAd; import com.bytedance.sdk.openadsdk.TTRewardVideoAd; import com.bytedance.sdk.openadsdk.TTSplashAd; import java.util.List; public class AppActivity extends Cocos2dxActivity { private TTAdNative mTTAdNative; static public AppActivity activity; //inline private static String inLine_id = "945273297"; private TTNativeExpressAd mTTAd; private long startTime = 0; private static String fullVideo_id = "945273298"; //rewardVideo private static String rewardVideo_id = "945273299"; private TTRewardVideoAd mttRewardVideoAd; private static String banner_id = "945273296"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508 if (!isTaskRoot()) { // Android launched another instance of the root activity into an existing task // so just quietly finish and go away, dropping the user back into the activity // at the top of the stack (ie: the last state of this task) // Don't need to finish it again since it's finished in super.onCreate . return; } // DO OTHER INITIALIZATION BELOW SDKWrapper.getInstance().init(this); mTTAdNative = TTAdManagerHolder.get().createAdNative(this); activity = this; //提前加载激励视频; loadRewardVideo(); } static public void showSplash(){ } static public void showBanner(){ Log.e("cocos","显示banner广告"); } static public void showInline(){ //启动播放 Log.e("cocos","显示插屏广告"); AdSlot adSlot = new AdSlot.Builder() .setCodeId(inLine_id) //广告位id .setSupportDeepLink(true) .setAdCount(1) //请求广告数量为1到3条 .setExpressViewAcceptedSize(300, 450) //期望模板广告view的size,单位dp .build(); activity.mTTAdNative.loadInteractionExpressAd(adSlot, new TTAdNative.NativeExpressAdListener(){ @Override public void onError(int i, String s) { } @Override public void onNativeExpressAdLoad(Listads) { if (ads == null || ads.size() == 0) { return; } activity.mTTAd = ads.get(0); activity.bindAdListener(activity.mTTAd); activity.startTime = System.currentTimeMillis(); activity.mTTAd.render(); } }); } private void bindAdListener(TTNativeExpressAd ad) { ad.setExpressInteractionListener(new TTNativeExpressAd.AdInteractionListener() { @Override public void onAdClicked(View view, int i) { } @Override public void onAdShow(View view, int i) { } @Override public void onRenderFail(View view, String s, int i) { } @Override public void onRenderSuccess(View view, float v, float v1) { mTTAd.showInteractionExpressAd(activity); } @Override public void onAdDismiss() { } }); } //激励视频先加载好 private void loadRewardVideo(){ //TTAdConstant.VERTICAL AdSlot adSlot = new AdSlot.Builder() .setCodeId(rewardVideo_id) .setSupportDeepLink(true) .setRewardName("双倍经验值") //奖励的名称 .setRewardAmount(1) //奖励的数量 //模板广告需要设置期望个性化模板广告的大小,单位dp,激励视频场景,只要设置的值大于0即可 .setExpressViewAcceptedSize(500,500) .setUserID("user123")//用户id,必传参数 //.setMediaExtra("media_extra") //附加参数,可选 .setOrientation(TTAdConstant.VERTICAL) //必填参数,期望视频的播放方向:TTAdConstant.HORIZONTAL 或 TTAdConstant.VERTICAL .build(); mTTAdNative.loadRewardVideoAd(adSlot, new TTAdNative.RewardVideoAdListener() { @Override public void onError(int i, String s) { } @Override public void onRewardVideoAdLoad(TTRewardVideoAd ad) { mttRewardVideoAd = ad; mttRewardVideoAd.setRewardAdInteractionListener(new TTRewardVideoAd.RewardAdInteractionListener() { @Override public void onAdShow() { } @Override public void onAdVideoBarClick() { } @Override public void onAdClose() { Log.e("cocos", "视频播放完成关闭"); sendMyReward(); } //视频播放完成回调 @Override public void onVideoComplete() { Log.e("cocos", "视频播放完成回调"); } @Override public void onVideoError() { } @Override public void onRewardVerify(boolean b, int i, String s) { Log.e("cocos", "视频播放完成验证奖励"); } @Override public void onSkippedVideo() { } }); } @Override public void onRewardVideoCached() { } }); } //调用js发放奖励方法 public void sendMyReward() { activity.runOnGLThread(new Runnable() { @Override public void run() { Log.e("cocos", "java调用视频发放奖励方法"); String js = "UtilsPlatform.sendReward();"; Cocos2dxJavascriptJavaBridge.evalString(js); Log.e("cocos","rewardVideoAd evalString"); } }); } static public void showRewardedVideo(){ Log.e("cocos","显示激励视频广告"); activity.runOnUiThread(new Runnable() { @Override public void run() { if (activity.mttRewardVideoAd != null) { //step6:在获取到广告后展示 //该方法直接展示广告 activity.mttRewardVideoAd.showRewardVideoAd(activity); //展示广告,并传入广告展示的场景 activity.mttRewardVideoAd = null; } else { Log.e("cocos", "请先加载广告"); } } }); } static public void showFullScreenVideo(){ Log.e("cocos","显示全屏视频广告"); } @Override public Cocos2dxGLSurfaceView onCreateView() { Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this); // TestCpp should create stencil buffer glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8); SDKWrapper.getInstance().setGLSurfaceView(glSurfaceView, this); return glSurfaceView; } @Override protected void onResume() { super.onResume(); SDKWrapper.getInstance().onResume(); } @Override protected void onPause() { super.onPause(); SDKWrapper.getInstance().onPause(); } @Override protected void onDestroy() { super.onDestroy(); SDKWrapper.getInstance().onDestroy(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); SDKWrapper.getInstance().onActivityResult(requestCode, resultCode, data); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); SDKWrapper.getInstance().onNewIntent(intent); } @Override protected void onRestart() { super.onRestart(); SDKWrapper.getInstance().onRestart(); } @Override protected void onStop() { super.onStop(); SDKWrapper.getInstance().onStop(); } @Override public void onBackPressed() { SDKWrapper.getInstance().onBackPressed(); super.onBackPressed(); } @Override public void onConfigurationChanged(Configuration newConfig) { SDKWrapper.getInstance().onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { SDKWrapper.getInstance().onRestoreInstanceState(savedInstanceState); super.onRestoreInstanceState(savedInstanceState); } @Override protected void onSaveInstanceState(Bundle outState) { SDKWrapper.getInstance().onSaveInstanceState(outState); super.onSaveInstanceState(outState); } @Override protected void onStart() { SDKWrapper.getInstance().onStart(); super.onStart(); } }