第一步:准备好,穿山甲的gromore广告的appid,广告ID(注:ID和代码位ID要区分好),参考下图

android studio 接入穿山甲开屏广告 app穿山甲广告_ide

第二步:引入sdk
在build.gradle项目中

repositories {
         google()
         jcenter()
         mavenCentral()
         maven {
             url 'https://artifact.bytedance.com/repository/pangle'
         }    }
 allprojects {
     repositories {
         google()
         jcenter()
         maven {url "https://jitpack.io"}
         mavenCentral()
         maven {
             url 'https://artifact.bytedance.com/repository/pangle'
         }
     }
 }

 在app的build.gradle中引入sdk
 //GroMore_sdk
     implementation "com.gromore.cn:gromore-sdk:4.0.0.1"  //groMore sdk
     implementation "com.gromore.cn:pangle-adapter:5.1.0.2.0" //穿山甲 adapter
     implementation "com.gromore.cn:ks-adapter:3.3.38.0"  //快手 adapter  这个根据自己需求添加
     implementation "com.gromore.cn:gdt-adapter:4.510.1380.0"  //优量汇 adapter  这个根据自己需求添加第三步:权限和filePath添加
      <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <!--摄像机权限-->
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 悬浮窗 -->
     <!--手机震动权限-->
     <uses-permission android:name="android.permission.VIBRATE" />
     <!--读取本地图片权限-->
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <permission
         android:name="${applicationId}.openadsdk.permission.TT_PANGOLIN"
         android:protectionLevel="signature" />
     <uses-permission android:name="${applicationId}.openadsdk.permission.TT_PANGOLIN" /> <!-- 可选权限 -->
     <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"
         tools:ignore="ScopedStorage" />
     <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"  /> <!-- 穿山甲3400版本新增:建议添加“query_all_package”权限,穿山甲将通过此权限在Android R系统上判定广告对应的应用是否在用户的app上安装,避免投放错误的广告,以此提高用户的广告体验。若添加此权限,需要在您的用户隐私文档中声明! -->
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />//下面根据自己需求添加,参考穿山甲,让全球APP更有价值
<!-- Pangle start================== -->
        <provider
            android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
            android:authorities="${applicationId}.TTFileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/pangle_file_paths" />
        </provider>       <provider
            android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
            android:authorities="${applicationId}.TTMultiProvider"
            android:exported="false" />
        <!-- Pangle end================== -->第四步:初始化sdk
 官方提供的初始化必须在appliaction中,但是上架会有隐私政策不过
 我测试了可以在引导页oncerate()中初始化,我的项目是有个开屏广告的,我就是在开屏广告中初始化的
  //MSDK的初始化需要放在Application中进行
             GMAdManagerHolder.init(this);
  第五步:加载激励视频
   public class RewardVideoActivity2 extends BaseActivity{
    private String TAG="Reward";
     private AdRewardManager mAdRewardManager; //激励视频管理类
     private boolean mLoadSuccess; //是否加载成功
     private boolean mIsLoadedAndShow;//广告加载成功并展示
     private GMRewardedAdListener mGMRewardedAdListener;    @Override
     public int setLayout() {
         return R.layout.activity_rewardvideo;
     }    @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         ButterKnife.bind(this);
         GMMediationAdSdk.requestPermissionIfNecessary(this);
         initListener();
         initAdLoader();
     }
     private void initAdLoader() {
         Log.e(TAG, "initAdLoader");
         if (GMMediationAdSdk.configLoadSuccess()) {
             Log.e("wangjj","GMMediationAdSdk加载成功");
         }else {
             Log.e("wangjj","GMMediationAdSdk加载失败");
         }
         mAdRewardManager = new AdRewardManager(this, new GMRewardedAdLoadCallback() {
             @Override
             public void onRewardVideoLoadFail(AdError adError) {
                 mLoadSuccess = false;
                 Log.e(TAG, "load RewardVideo ad error : " + adError.code + ", " + adError.message);
                 mAdRewardManager.printLoadFailAdnInfo();
             }            @Override
             public void onRewardVideoAdLoad() {
                 mLoadSuccess = true;
                 Log.e(TAG, "load RewardVideo ad success !");
                 // 获取本次waterfall加载中,加载失败的adn错误信息。
                 mAdRewardManager.printLoadAdInfo(); //打印已经加载广告的信息
                 mAdRewardManager.printLoadFailAdnInfo();//打印加载失败的adn错误信息
             }            @Override
             public void onRewardVideoCached() {
                 mLoadSuccess = true;
                 Log.e(TAG, "onRewardVideoCached....缓存成功");
                 Log.e(TAG,"激励视频素材缓存成功!");
                 showRewardAd();
             }
         });
         mAdRewardManager.loadAdWithCallback("102285687", GMAdConstant.VERTICAL);
     }    /**
      * 展示广告
      */
     private void showRewardAd() {
         if (mLoadSuccess && mAdRewardManager != null) {
             if (mAdRewardManager.getGMRewardAd() != null && mAdRewardManager.getGMRewardAd().isReady()) {
                 //在获取到广告后展示,强烈建议在onRewardVideoCached回调后,展示广告,提升播放体验
                 //该方法直接展示广告,如果展示失败了(如过期),会回调onVideoError()
                 //展示广告,并传入广告展示的场景
                 mAdRewardManager.getGMRewardAd().setRewardAdListener(mGMRewardedAdListener);
 //                mAdRewardManager.getGMRewardAd().setRewardPlayAgainListener(mGMRewardedPlayAgainListener);
                 mAdRewardManager.getGMRewardAd().showRewardAd(this);
                 mAdRewardManager.printSHowAdInfo();//打印已经展示的广告信息
                 mLoadSuccess = false;
             } else {
                 Log.e(TAG,"当前广告不满足show的条件");
             }
         } else {
             Log.e(TAG,"请先加载广告");
         }
     }   private void initListener(){
        mGMRewardedAdListener = new GMRewardedAdListener() {           /**
             * 广告的展示回调 每个广告仅回调一次
             */
            public void onRewardedAdShow() {
                Log.e(TAG,"onRewardedAdShow");           }
           /**
             * show失败回调。如果show时发现无可用广告(比如广告过期或者isReady=false),会触发该回调。
             * 开发者应该结合自己的广告加载、展示流程,在该回调里进行重新加载。
             * @param adError showFail的具体原因
             */
            @Override
            public void onRewardedAdShowFail(AdError adError) {
                if (adError == null) {
                    return;
                }
                Log.e(TAG,"onRewardedAdShowFail, errCode: " + adError.code + ", errMsg: " + adError.message);
                // 开发者应该结合自己的广告加载、展示流程,在该回调里进行重新加载
            }           /**
             * 注意Admob的激励视频不会回调该方法
             */
            @Override
            public void onRewardClick() {
                Log.e(TAG, "onRewardClick");           }
           /**
             * 广告关闭的回调
             */
            public void onRewardedAdClosed() {
                Log.e(TAG,"onRewardedAdClosed");
                 finish();
            }           /**
             * 视频播放完毕的回调 Admob广告不存在该回调
             */
            public void onVideoComplete() {
                Log.e(TAG,"onVideoComplete");           }
           /**
             * 1、视频播放失败的回调
             */
            public void onVideoError() {
                Log.e(TAG,"onVideoError");           }
           /**
             * 激励视频播放完毕,验证是否有效发放奖励的回调
             */
            public void onRewardVerify(RewardItem rewardItem) {
                Map<String, Object> customData = rewardItem.getCustomData();
                if (customData != null) {
                    // 首先判断是否启用了GroMore的服务端验证
                    Boolean isGroMoreServerSideVerify = (Boolean) customData.get(RewardItem.KEY_IS_GROMORE_SERVER_SIDE_VERIFY);
                    if (isGroMoreServerSideVerify != null && isGroMoreServerSideVerify) {
                        // 开启了GroMore的服务端激励验证,这里可以获取GroMore的服务端激励验证信息
                        boolean isVerify = rewardItem.rewardVerify();
                        // 如果isVerify=false,则可以根据下面的错误码来判断为什么是false,
                        //  1、如果errorCode为40001/40002/50001/50002,则是因为请求异常导致,媒体可以根据自己的判断决定是否发放奖励。
                        //  2、否则,就是媒体服务端回传的验证结果是false,此时应该不发放奖励。                       Integer reason = (Integer) customData.get(RewardItem.KEY_REASON);
                        if (reason != null) {
                            Log.e(TAG,"rewardItem,开发者服务器回传的reason,开发者不传时为空");
                        }
                        Integer errorCode = (Integer) customData.get(RewardItem.KEY_ERROR_CODE);
                        if (errorCode != null) {
                            String errorMsg = (String) customData.get(RewardItem.KEY_ERROR_MSG);
                            Log.e(TAG,"rewardItem, gromore服务端验证异常时的错误信息,未发生异常时为0或20000:errorCode:" + errorCode + ", errMsg: " + errorMsg);
                        }
                        String gromoreExtra = (String) customData.get(RewardItem.KEY_GROMORE_EXTRA);
                        Log.e(TAG,"rewardItem, 开发者通过AdSlot传入的extra信息,会透传给媒体的服务器。开发者不传时为空,extra:" + gromoreExtra);
                        String transId = (String) customData.get(RewardItem.KEY_TRANS_ID);
                        Log.e(TAG,"rewardItem, gromore服务端验证产生的transId,一次广告播放会产生的唯一的transid: " + transId);
                    } else {
                        Logger.e("获得奖励了");
                        getJiek();
 //                       // 未开启GroMore的服务端激励验证,这里获取adn的激励验证信息
 //                       String adnName = (String) customData.get(RewardItem.KEY_ADN_NAME);
 //                       if (!TextUtils.isEmpty(adnName)) {
 //                           switch (adnName) {
 //                               case RewardItem.KEY_GDT:
 //                                   Log.e(TAG,"rewardItem gdt: " + customData.get(RewardItem.KEY_GDT_TRANS_ID));
 //                                   break;
 //                           }
 //                       }
                    }
                }
                Log.e(TAG,"onRewardVerify");
            }           /**
             * - Mintegral GDT Admob广告不存在该回调
             */
            @Override
            public void onSkippedVideo() {           }
       };
    }     @Override
     protected void onDestroy() {
         super.onDestroy();
         if (mAdRewardManager != null) {
             mAdRewardManager.destroy();
         }
     }
 }
  相关类
**
  * 可以用一个单例来保存TTAdManager实例,在需要初始化sdk的时候调用
  */
 public class GMAdManagerHolder {    private static boolean sInit=false;
    public static void init(Context context) {
         doInit(context);
     }    //step1:接入网盟广告sdk的初始化操作,详情见接入文档和穿山甲平台说明
     private static void doInit(@NonNull Context context) {
 //        if (!sInit) {
             GMMediationAdSdk.initialize(context, buildV2Config(context));
             sInit = true;
 //        }
     }    public static GMAdConfig buildV2Config(Context context) {
         /**
          * GMConfigUserInfoForSegment设置流量分组的信息
          * 注意:
          * 1、请每次都传入新的info对象
          * 2、字符串类型的值只能是大小写字母,数字,下划线,连字符,字符个数100以内 ( [A-Za-z0-9-_]{1,100} ) ,不符合规则的信息将被过滤掉,不起作用。
          */
         GMConfigUserInfoForSegment userInfo = new GMConfigUserInfoForSegment();
         userInfo.setUserId("msdk-demo");
         userInfo.setGender(UserInfoForSegment.GENDER_MALE);
         userInfo.setChannel("msdk-channel");
         userInfo.setSubChannel("msdk-sub-channel");
         userInfo.setAge(999);
         userInfo.setUserValueGroup("msdk-demo-user-value-group");        Map<String, String> customInfos = new HashMap<>();
         customInfos.put("aaaa", "test111");
         customInfos.put("bbbb", "test222");
         userInfo.setCustomInfos(customInfos);
         JSONObject jsonObject = null;
         //读取json文件,本地缓存的配置
 //        try {
 //            jsonObject = new JSONObject(getJson("androidlocalconfig.json", context));
 //        } catch (JSONException e) {
 //            e.printStackTrace();
 //        }        Map<String, Object> initConfig = new HashMap<>();
         initConfig.put("1111", "22222");
         initConfig.put("22222", "33333");
         initConfig.put("44444", "5555");        return new GMAdConfig.Builder()
                 .setAppId("appID")
                 .setAppName("app名称")
                 .setDebug(true)
                 .setPublisherDid(getAndroidId(context))
                 .setOpenAdnTest(false)
                 .setConfigUserInfoForSegment(userInfo)
                 .setPangleOption(new GMPangleOption.Builder()
                         .setIsPaid(false)
                         .setTitleBarTheme(GMAdConstant.TITLE_BAR_THEME_DARK)
                         .setAllowShowNotify(true)
                         .setAllowShowPageWhenScreenLock(true)
                         .setDirectDownloadNetworkType(GMAdConstant.NETWORK_STATE_WIFI, GMAdConstant.NETWORK_STATE_3G)
                         .setIsUseTextureView(true)
                         .setNeedClearTaskReset()
                         .setKeywords("")
                         .build())
                 .setGdtOption(new GMGdtOption.Builder()
                         .setWxInstalled(false)
                         .setOpensdkVer(null)
                         .setSupportH265(false)
                         .setSupportSplashZoomout(false)
                         .build())
                 /**
                  * 隐私协议设置,详见GMPrivacyConfig
                  */
                 .setPrivacyConfig(new GMPrivacyConfig() {
                     // 重写相应的函数,设置需要设置的权限开关,不重写的将采用默认值
                     // 例如,重写isCanUsePhoneState函数返回true,表示允许使用ReadPhoneState权限。
                     @Override
                     public boolean isCanUsePhoneState() {
                         return true;
                     }                    //当isCanUseWifiState=false时,可传入Mac地址信息,穿山甲sdk使用您传入的Mac地址信息
                     @Override
                     public String getMacAddress() {
                         return "";
                     }                    // 设置青少年合规,默认值GMAdConstant.ADULT_STATE.AGE_ADULT为成年人
                     @Override
                     public GMAdConstant.ADULT_STATE getAgeGroup() {
                         return GMAdConstant.ADULT_STATE.AGE_ADULT;
                     }
                 })
                 .setLocalExtra(initConfig)
                 .setCustomLocalConfig(jsonObject)
                 .build();
     }    public static String getAndroidId(Context context) {
         String androidId = null;
         try {
             androidId = Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);
         } catch (Exception e) {
             e.printStackTrace();
         }
         return androidId;
     }    public static String getJson(String fileName, Context context) {
         StringBuilder stringBuilder = new StringBuilder();
         try {
             InputStream is = context.getAssets().open(fileName);
             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
             String line;
             while ((line = bufferedReader.readLine()) != null) {
                 stringBuilder.append(line);
             }
         } catch (IOException e) {
             e.printStackTrace();
         }
         return stringBuilder.toString();
     }}
/**
  * 激励管理类。
  * 只需要复制粘贴到项目中,通过回调处理相应的业务逻辑即可使用完成广告加载&展示
  */
 public class AdRewardManager {
     private static final String TAG = "AdRewardManager";    /**
      * 激励对应的广告对象
      * 每次加载全屏视频广告的时候需要新建一个GMRewardAd,否则可能会出现广告填充问题
      */
     private GMRewardAd mGMRewardAd;
     private Activity mActivity;
     /**
      * 激励加载广告回调
      * 请在加载广告成功后展示广告
      */
     private GMRewardedAdLoadCallback mGMRewardedAdLoadCallback;
     /**
      * GMAdConstant.HORIZONTAL 或 GMAdConstant.VERTICAL
      */
     private int mOrientation; //方向
     private String mAdUnitId; //广告位    /**
      * ------------------------- 以下是必要实现,如果不实现会导致加载广告失败  --------------------------------------
      */    /**
      * 管理类构造函数
      * @param activity 激励展示的Activity
      * @param rewardedAdLoadCallback 激励加载广告回调
      */
     public AdRewardManager(Activity activity, GMRewardedAdLoadCallback rewardedAdLoadCallback) {
         mActivity = activity;
         mGMRewardedAdLoadCallback = rewardedAdLoadCallback;
     }    /**
      * 获取激励广告对象
      */
     public GMRewardAd getGMRewardAd() {
         return mGMRewardAd;
     }    /**
      * 加载激励广告,如果没有config配置会等到加载完config配置后才去请求广告
      * @param adUnitId  广告位ID
      * @param orientation 方向
      */
     public void loadAdWithCallback(final String adUnitId, final int orientation) {
         this.mOrientation = orientation;
         this.mAdUnitId = adUnitId;        if (GMMediationAdSdk.configLoadSuccess()) {
             Log.e("wangjj","GMMediationAdSdk加载成功");
             loadAd(adUnitId, orientation);
         } else {
             Log.e("wangjj","GMMediationAdSdk加载失败");
             GMMediationAdSdk.registerConfigCallback(mSettingConfigCallback);
         }
     }    /**
      * 加载激励广告,如果没有config配置会等到加载完config配置后才去请求广告
      * @param adUnitId  广告位ID
      * @param orientation 方向
      */
     private void loadAd(String adUnitId, int orientation) {
         mGMRewardAd = new GMRewardAd(mActivity, adUnitId);        /**
          * 激励视频服务端验证,GroMore会把设置的字符串透传给相应的ADN
          */
         Map<String, String> customData = new HashMap<>();
         customData.put(GMAdConstant.CUSTOM_DATA_KEY_PANGLE, "pangle media_extra");
         customData.put(GMAdConstant.CUSTOM_DATA_KEY_GDT, "gdt custom data");
         customData.put(GMAdConstant.CUSTOM_DATA_KEY_KS, "ks custom data");
         customData.put(GMAdConstant.CUSTOM_DATA_KEY_SIGMOB, "sigmob custom data");
         customData.put(GMAdConstant.CUSTOM_DATA_KEY_MINTEGRAL, "mintegral custom data");
         customData.put(GMAdConstant.CUSTOM_DATA_KEY_BAIDU, "baidu custom data");
         // 如果开启了gromre服务端激励验证,可以传以下信息,跟adn无关。
         customData.put(GMAdConstant.CUSTOM_DATA_KEY_GROMORE_EXTRA, "gromore serverside verify extra data"); // 会透传给媒体的服务器        /**
          * 创建激励广告请求类型参数GMAdSlotRewardVideo,具体参数含义参考文档
          */
         GMAdSlotRewardVideo adSlotRewardVideo = new GMAdSlotRewardVideo.Builder()
                 .setMuted(true)//对所有SDK的激励广告生效,除需要在平台配置的SDK,如穿山甲SDK
                 .setVolume(0f)//配合Admob的声音大小设置[0-1]
                 .setGMAdSlotGDTOption(GMAdOptionUtil.getGMAdSlotGDTOption().build())
                 .setGMAdSlotBaiduOption(GMAdOptionUtil.getGMAdSlotBaiduOption().build())
                 .setCustomData(customData)
                 .setRewardName("金币") //奖励的名称
                 .setRewardAmount(3)  //奖励的数量
                 .setUserID("用户ID")//用户id,必传参数
                 .setUseSurfaceView(false) // 是否使用SurfaceView绘制,默认false。目前仅针对百度生效,建议使用false,否则百度会黑屏。
                 .setOrientation(orientation)//必填参数,期望视频的播放方向:GMAdConstant.HORIZONTAL 或 GMAdConstant.VERTICAL
                 .setBidNotify(true)//开启bidding比价结果通知,默认值为false
                 .build();
         mGMRewardAd.loadAd(adSlotRewardVideo, mGMRewardedAdLoadCallback);
     }    /**
      * 在Activity onDestroy中需要调用清理资源
      */
     public void destroy() {
         if (mGMRewardAd != null) {
             mGMRewardAd.destroy();
         }
         mActivity = null;
         mGMRewardedAdLoadCallback = null;
         GMMediationAdSdk.unregisterConfigCallback(mSettingConfigCallback); //注销config回调
     }    /**
      * config配置回调
      */
     private GMSettingConfigCallback mSettingConfigCallback = new GMSettingConfigCallback() {
         @Override
         public void configLoad() {
             loadAd(mAdUnitId, mOrientation);
         }
     };     /**
      * ------------------------- 以下是非必要功能请选择性使用  --------------------------------------
      */    /**
      * 展示广告加载信息
      */
     public void printLoadAdInfo() {
         if (mGMRewardAd == null) {
             return;
         }
     }    /**
      * 打印加载失败的adn错误信息
      */
     public void printLoadFailAdnInfo() {
         if (mGMRewardAd == null) {
             return;
         }        // 获取本次waterfall加载中,加载失败的adn错误信息。
         Log.d(TAG, "reward ad loadinfos: " + mGMRewardAd.getAdLoadInfoList());
     }    /**
      * 打印已经展示的广告信息
      */
     public void printSHowAdInfo() {
         if (mGMRewardAd == null) {
             return;
         }
         GMAdEcpmInfo gmAdEcpmInfo = mGMRewardAd.getShowEcpm();
         if (gmAdEcpmInfo == null) {
             return;
         }
         String s = App.getContext().getResources().getString(R.string.show_info,
                 gmAdEcpmInfo.getAdNetworkRitId(),
                 gmAdEcpmInfo.getAdnName(),
                 gmAdEcpmInfo.getPreEcpm());
         Logger.e(TAG, s);
     }}