这个月一直在搞 ReactNative Android 广告模块,但是对接一直有点麻烦,我这里先出一篇博客来讲一下对接的方法吧,我还在继续探索跟进简单的对接方法比如 npm 的模块发布呀,React Native link,以及 npm init 时自动化配置等等…

我本来想搭建一个私有的 npm 模块仓库的,但是弄了几个程序总是感觉不够满意,我们还是用 git 来操作一下吧

1.添加 ttad 模块

这里使用 git 来下载我们的广告模块,不过 git 又有两种添加方法 ssh 协议和 http 协议这里我都讲一下吧

在项目的 package.json 文件在 devDependencies 下添加模块

# git协议,这里需要配置 git 的 sshkey
{
...
  "devDependencies": {
   ...
    "@hxf/ttad": "git+ssh://git@code.haxibiao.cn:android/ttad.git"
  },
...
}

# http协议,下面链接处username和password分别输入你的git账号和密码
{
...
  "devDependencies": {
   ...
    "@hxf/ttad": "git+http://username:password@code.haxibiao.cn:android/ttad.git"
  },
...
}

2.在 Android 中引用导入相关模块

进入项目下面的 android 目录,首先打开 settings.gradle 文件在最后添加下面代码

include ':toolkits'
project(':toolkits').projectDir = new File('../node_modules/@hxf/ttad')

然后再进入 app 目录下打开 build.gradle 文件添加 repositories 部分和 dependencies 中的两句代码

apply plugin: "com.android.application"

import com.android.build.OutputFile


....

repositories {
    flatDir {
        dirs 'libs', project(':toolkits').file('libs')
    }
}


dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    .....

    implementation project(':toolkits')
    // 穿山甲必须
    compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.2'

    ....
}

....

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

然后打开当前文件夹下的 src 目录进入 main 打开 AndroidManifest.xml 对比下面代码添加相关代码( 广告权限申请,广告sdk部分 )

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.dongdianyi">

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

    <!--广告相关权限-->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <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_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <!--广告相关权限结束-->

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

        <!--广告sdk-->
        <activity android:name="com.haxibiao.ad.ttadsdk.SplashActivity"  android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
            <meta-data android:name="splash_title_color" android:value="#407FCF" />
        </activity>

        <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/file_paths" />
        </provider>
        <provider
            android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
            android:authorities="${applicationId}.TTMultiProvider"
            android:exported="false" />
        <!--广告sdk结束-->

    </application>

</manifest>

然后进入 res 目录下创建一个 xml 文件夹然后在 xml 文件夹中创建一个 file_paths.xml 文件输入如下代码保存 ( 这个是配置穿山甲广告下载目录的,一般如下配置就好了 )

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<paths xmlns:android="http://schemas.android.com/apk/res/android">
		<external-path path="" name="download" />

		<!--为了适配头条的ad sdk 所有路径可以设置 path = "." -->
		<external-files-path name="." path="Download" />
	</paths>
</resources>

然后返回一层进入 java 目录,打开下面的子文件夹找到 MainActivity.java 添加如下代码

package com.dongdianyi;

import android.content.Intent;
import android.os.Bundle;

import com.facebook.react.ReactActivity;

// 导入广告模块需要的包
import com.haxibiao.ad.AdBoss;
import org.json.JSONException;
import org.json.JSONObject;


public class MainActivity extends ReactActivity {

  /**
   * Returns the name of the main component registered from JavaScript. This is used to schedule
   * rendering of the component.
   */
  @Override
  protected String getMainComponentName() {
    return "dongdianyi";
  }

  // 广告模块开始
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    AdBoss.init(this, "06112233");  
    // 初始化穿山甲广告 appid 这里的 06112233  写入自己的 appid
  }

  // 激励视频结果回调
  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    try {
      if (resultCode == RESULT_OK && requestCode == 10000) {
        JSONObject json = new JSONObject();
        json.put("video_play", intent.getBooleanExtra("video_play", false));
        json.put("ad_click", intent.getBooleanExtra("ad_click", false));
        json.put("apk_install", intent.getBooleanExtra("apk_install", false));
        json.put("verify_status", intent.getBooleanExtra("verify_status", false));
        AdBoss.myBlockingQueue.add(json.toString());
      }
    } catch (JSONException e) {
      e.printStackTrace();
      AdBoss.myBlockingQueue.add(null);
    }
  }
  // 广告模块代码结束

}

然后打开同级目录下的 MainApplication.java 文件 ( 大量相同代码我就用 .... 忽略了哈 )

package com.dongdianyi;

import android.app.Application;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

// 导入广告模块需要的包
import com.haxibiao.ad.AdPackage;
import com.haxibiao.toolkits.ToolkitsPackage;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost =
      new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for example:
          // packages.add(new MyReactNativePackage());
            packages.add(new ToolkitsPackage());
            packages.add(new AdPackage());  // 添加广告模块
          return packages;
        }

        ....

}

好了,到这里原生导入的工作已经完成…

3. JS 添加广告模块

在你的代码中添加一个 loadSplashAd.js 文件添加如下代码

import {
  NativeModules,
  Platform,
} from 'react-native';

let module = NativeModules.Splash;

let adArgs = {
  tt_appid: '684521', // 这里输入你的 appid
  tt_codeid: '8789124521', // 这里输入开屏广告位代码id
};

export const loadSplashAd = () => {
  if (Platform.OS === 'ios') {
    console.log('ios 不走这启动splash ad..');
    return;
  }
  return module.loadSplashAd(adArgs);
};

export default loadSplashAd;

然后在你的 app.js 中启动开屏广告就好了,( 下面是我的 App.js 代码仅供参考 )

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React, {useEffect} from 'react';

import loadSplashAd from './loadSplashAd';

import { Text } from 'react-native';

const App: () => React$Node = () => {

  useEffect(() => {
    loadSplashAd();
  });

  return (
          <Text>Hello World</Text>
  );
};

export default App;

最后别忘记重新 react-native run-android 哦…