<file_sep>package com.yc.adplatform.business;

import android.content.Context;
import android.text.TextUtils;

import com.alibaba.fastjson.TypeReference;
import com.yc.adplatform.securityhttp.domain.GoagalInfo;
import com.yc.adplatform.securityhttp.domain.ResultInfo;
import com.yc.adplatform.securityhttp.engin.BaseEngin;
import com.yc.uuid.UDIDInfo;

import java.util.HashMap;
import java.util.Map;

import rx.Observable;

public class InitEngin extends BaseEngin {

    private String url;

    public InitEngin(Context context) {
        super(context);
    }

    @Override
    public String getUrl() {
        return this.url;
    }

    public Observable<ResultInfo<InitInfo>> getInItInfo(String url, String appId, UDIDInfo udidInfo) {
        this.url = url;
        Map<String, String> params = new HashMap<>();
        params.put("app_id", appId);
        params.put("oaid", udidInfo.getOaid());
        params.put("imei", TextUtils.isEmpty(udidInfo.getImei()) ? udidInfo.getImei() : GoagalInfo.get().uuid);
        params.put("imei2", TextUtils.isEmpty(udidInfo.getImei2()) ? udidInfo.getImei2() : "");
        return rxpost(new TypeReference<ResultInfo<InitInfo>>() {
        }.getType(), params, true, true, true);
    }

}
<file_sep>package com.yc.adplatformsdkexample;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;


import java.util.ArrayList;
import java.util.List;

public class PermissionHelper {
    private String[] mustPermissions = new String[]{
            Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};

    public void setMustPermissions(String[] mustPermissions) {
        this.mustPermissions = mustPermissions;
    }

    public void checkAndRequestPermission(Activity activity, OnRequestPermissionsCallback onRequestPermissionsCallback) {
        this.onRequestPermissionsCallback = onRequestPermissionsCallback;

        if (Build.VERSION.SDK_INT < 23) {
            if (onRequestPermissionsCallback != null) {
                onRequestPermissionsCallback.onRequestPermissionSuccess();
            }
            return;
        }

        if (checkMustPermissions(activity)) {
            if (onRequestPermissionsCallback != null) {
                onRequestPermissionsCallback.onRequestPermissionSuccess();
            }
            return;
        }
        ActivityCompat.requestPermissions(activity, mustPermissions, 1024);
    }

    @TargetApi(23)
    public boolean checkMustPermissions(Activity activity) {
        if (mustPermissions == null || mustPermissions.length == 0) {
            return true;
        }
        List<String> lackedPermission = new ArrayList<>();
        for (String permissions : mustPermissions) {
            if (!(ContextCompat.checkSelfPermission(activity, permissions) == PackageManager.PERMISSION_GRANTED)) {
                lackedPermission.add(permissions);
            }
        }

        if (0 == lackedPermission.size()) {
            return true;
        }

        return false;
    }

    public void onRequestPermissionsResult(Activity activity, int requestCode) {
        if(!(activity instanceof Activity)){
            return;
        }
        if (requestCode == 1024 && checkMustPermissions(activity)) {
            if (onRequestPermissionsCallback != null) {
                onRequestPermissionsCallback.onRequestPermissionSuccess();
            }
        } else {
            if (onRequestPermissionsCallback != null) {
                onRequestPermissionsCallback.onRequestPermissionError();
            }
        }
    }

    private OnRequestPermissionsCallback onRequestPermissionsCallback;

    public interface OnRequestPermissionsCallback {
        void onRequestPermissionSuccess();

        void onRequestPermissionError();
    }
}
<file_sep>package com.yc.adplatform.log;

import com.yc.adplatform.securityhttp.domain.GoagalInfo;
import com.yc.adplatform.securityhttp.utils.LogUtil;

import rx.Observable;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

public class AdLog {
    public static void sendLog(final String ip, final int port, final String appId, final String userId, final String adPosition, final String adCode, final String adType) {
        String data = userId + "," + appId + "," + adPosition + "," + adCode + "," + adType;
        LogUtil.msg("adlog:"+data);
        Observable.just(data).observeOn(Schedulers.newThread()).subscribe(new Action1<String>() {
            @Override
            public void call(String data) {
                LogSDK.getInstance().send(ip, port, data);
            }
        });
    }
}
<file_sep>package com.yc.adplatform.securityhttp.net.interfaces;


import com.yc.adplatform.securityhttp.net.entry.Response;
import com.yc.adplatform.securityhttp.net.entry.UpFileInfo;
import com.yc.adplatform.securityhttp.net.exception.NullResonseListenerException;
import com.yc.adplatform.securityhttp.net.listeners.OnHttpResonseListener;

import java.io.IOException;
import java.util.Map;

import okhttp3.MediaType;

/**
 * Created by zhangkai on 16/8/18.
 */
public interface IHttpRequest {

    Response get(String url, Map<String, String> params, Map<String, String> headers, boolean isEncryptResponse) throws
            IOException;

    void aget(String url, Map<String, String> params, Map<String, String> headers, boolean isEncryptResponse, final OnHttpResonseListener
            httpResonseListener) throws IOException,
            NullResonseListenerException;

    Response post(String url, Map<String, String> params, Map<String, String> headers, boolean isrsa, boolean iszip,
                  boolean
                          isEncryptResponse) throws IOException, NullResonseListenerException;

    public Response post(String url, Map<String, String> header, MediaType type, String
            body) throws IOException, NullResonseListenerException;

    void apost(String url, Map<String, String> params, Map<String, String> headers, boolean isrsa, boolean iszip,
               boolean
                       isEncryptResponse, final OnHttpResonseListener httpResonseListener)
            throws
            IOException, NullResonseListenerException;

    Response uploadFile(String url, UpFileInfo upFileInfo, Map<String, String> params, Map<String, String> headers,
                        boolean
                                isEncryptResponse
    ) throws IOException;


    void auploadFile(String url, UpFileInfo upFileInfo, Map<String, String> params, Map<String, String> headers, boolean
            isEncryptResponse,
                     OnHttpResonseListener
                             httpResonseListener) throws IOException, NullResonseListenerException;


    void cancel(String url);

}
<file_sep>package com.yc.adplatform.securityhttp.domain;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.provider.Settings;
import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.tencent.mmkv.MMKV;
import com.yc.adplatform.securityhttp.utils.FileUtil;
import com.yc.adplatform.securityhttp.utils.LogUtil;
import com.yc.adplatform.securityhttp.utils.PathUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * Created by zhangkai on 16/9/19.
 */
public class GoagalInfo {

    public String publicKey;

    public ChannelInfo channelInfo = null;
    private PackageInfo packageInfo = null;

    public String uuid = "";
    public String channel = "default";
    public String configPath = "";

    private static GoagalInfo goagalInfo = new GoagalInfo();
    public static GoagalInfo get() {
        return goagalInfo;
    }

    public void init(Context context) {
        configPath = PathUtil.getConfigPath(context);

        String result1 = null;
        String result2 = null;
        ApplicationInfo appinfo = context.getApplicationInfo();
        String sourceDir = appinfo.sourceDir;
        ZipFile zf = null;
        try {
            zf = new ZipFile(sourceDir);
            ZipEntry ze1 = zf.getEntry("META-INF/gamechannel.json");
            InputStream in1 = zf.getInputStream(ze1);
            result1 = FileUtil.readString(in1);
            LogUtil.msg("渠道->" + result1);

            ZipEntry ze2 = zf.getEntry("META-INF/rsa_public_key.pem");
            InputStream in2 = zf.getInputStream(ze2);
            result2 = FileUtil.readString(in2);
            LogUtil.msg("公钥->" + result2);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.msg("apk中gamechannel或rsa_public_key文件不存在", LogUtil.W);
        } finally {
            if (zf != null) {
                try {
                    zf.close();
                } catch (IOException e2) {
                    // TODO Auto-generated catch block
                    e2.printStackTrace();
                }
            }
        }

        String name = gamechannelFilename;
        if (result1 != null) {
            FileUtil.writeInfoToFile(result1, configPath, name);
        } else {
            result1 = FileUtil.readInfoFromFile(configPath, name);
        }

        if (result1 != null) {
            channel = result1;
        }

        name = rasPublickeylFilename;
        if (result2 != null) {
            publicKey = getPublicKey(result2);
            FileUtil.writeInfoToFile(result2, configPath, name);
        } else {
            result2 = FileUtil.readInfoFromFile(configPath, name);
            if (result2 != null) {
                publicKey = getPublicKey(result2);
            }
        }

        channelInfo = getChannelInfo();
        uuid = getUid(context);

    }

    private String rasPublickeylFilename = "rsa_public_key.pem";
    private String gamechannelFilename = "gamechannel.json";

    public GoagalInfo setRasPublickeylFilename(String rasPublickeylFilename) {
        this.rasPublickeylFilename = rasPublickeylFilename;
        return this;
    }

    public GoagalInfo setGamechannelFilename(String gamechannelFilename) {
        this.gamechannelFilename = gamechannelFilename;
        return this;
    }

    private ChannelInfo getChannelInfo() {
        try {
            return JSON.parseObject(channel, ChannelInfo.class);
        } catch (Exception e) {
            LogUtil.msg("渠道信息解析错误->" + e.getMessage());
        }
        return null;
    }

    private String getPublicKey(InputStream in) {
        String result = "";
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(in));
            String mLine;
            while ((mLine = reader.readLine()) != null) {
                if (mLine.startsWith("----")) {
                    continue;
                }
                result += mLine;
            }
        } catch (Exception e) {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e2) {
                }
            }
        }
        return result;
    }

    public String getPublicKeyString() {
        publicKey = getPublicKey(publicKey);
        return publicKey;
    }

    public String getPublicKey(String key) {
        return key.replace("-----BEGIN RSA PRIVATE KEY-----", "")
                .replace("-----END RSA PRIVATE KEY-----", "")
                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "")
                .replace("\r", "")
                .replace("\n", "");
    }

    @SuppressLint("MissingPermission")
    public String getUid(Context context) {
        String uid = MMKV.defaultMMKV().getString("uuid", "");
        if (TextUtils.isEmpty(uid)) {
            uid = Settings.Secure.getString(context.getContentResolver(),
                    Settings.Secure.ANDROID_ID);
        }
        return uid;
    }

    public PackageInfo getPackageInfo(Context context) {
        PackageInfo pInfo = null;
        try {
            pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (pInfo == null) {
            pInfo = new PackageInfo();
            pInfo.versionCode = 50;
            pInfo.versionName = "2.3.2";
        }
        return pInfo;
    }
}
<file_sep>package com.yc.adplatformsdkexample.hook;

import android.content.pm.PackageInfo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class IPackageManagerProxy implements InvocationHandler {
    private Object mIPackageManager; // origin IPackageManager.

    public IPackageManagerProxy(Object iPackageManager) {
        mIPackageManager = iPackageManager;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId)
        if (method.getName().equals("getPackageInfo")) {
            PackageInfo result = (PackageInfo) method.invoke(mIPackageManager, args);
            if(result != null){
                result.signatures = HookSignature.getSignature();
                result.packageName = "com.whychl.TrickyCastle";
            }
            return result;
        }
        return method.invoke(mIPackageManager, args);
    }


}
<file_sep>package com.yc.adplatform.securityhttp.net.impls;


import com.yc.adplatform.securityhttp.net.contains.HttpConfig;
import com.yc.adplatform.securityhttp.net.entry.UpFileInfo;
import com.yc.adplatform.securityhttp.net.exception.NullResonseListenerException;
import com.yc.adplatform.securityhttp.net.interfaces.IHttpRequest;
import com.yc.adplatform.securityhttp.net.listeners.OnHttpResonseListener;
import com.yc.adplatform.securityhttp.net.utils.OKHttpUtil;
import com.yc.adplatform.securityhttp.utils.LogUtil;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;
import okhttp3.Request;
import okhttp3.Response;


/**
 * Created by zhangkai on 16/8/18.
 */
public class OKHttpRequest implements IHttpRequest {
    public static OKHttpRequest httpRequest;
    public static OkHttpClient client = null;

    private static Builder builder = OKHttpUtil.getHttpClientBuilder();

    public static Builder getBuilder() {
        return builder;
    }

    private OKHttpRequest() {
        client = builder.build();
    }

    public static OKHttpRequest getImpl() {
        synchronized (OKHttpRequest.class) {
            if (httpRequest == null) {
                httpRequest = new OKHttpRequest();
            }
        }
        return httpRequest;
    }

    @Override
    public com.yc.adplatform.securityhttp.net.entry.Response get(String url, Map<String, String> params, Map<String, String> headers, boolean isEncryptResponse) throws IOException {
        Request.Builder builder = OKHttpUtil.getRequestBuilder(OKHttpUtil.buildUrl(url, params));
        OKHttpUtil.addHeaders(builder, headers);
        Request request = builder.build();
        return sendRequest(request, isEncryptResponse);
    }

    @Override
    public void aget(String url, Map<String, String> params, Map<String, String> headers, boolean isEncryptResponse, OnHttpResonseListener httpResonseListener) throws IOException, NullResonseListenerException {
        if (httpResonseListener == null) throw new NullResonseListenerException();

        Request.Builder builder = OKHttpUtil.getRequestBuilder(OKHttpUtil.buildUrl(url, params));
        OKHttpUtil.addHeaders(builder, headers);
        Request request = builder.build();

        sendRequest(request, isEncryptResponse, httpResonseListener);
    }


    @Override
    public com.yc.adplatform.securityhttp.net.entry.Response post(String url, Map<String, String> header, MediaType type, String
            body) throws IOException, NullResonseListenerException {

        Request request = OKHttpUtil.getRequest(url, header, type, body);
        return sendRequest(request, false);
    }

    @Override
    public com.yc.adplatform.securityhttp.net.entry.Response post(String url, Map<String, String> params, Map<String, String> headers, boolean isrsa, boolean iszip, boolean isEncryptResponse) throws IOException, NullResonseListenerException {
        Request request = OKHttpUtil.getRequest(url, params, headers, isrsa, iszip, isEncryptResponse);
        return sendRequest(request, isEncryptResponse);
    }


    @Override
    public void apost(String url, Map<String, String> params, Map<String, String> headers, boolean isrsa, boolean iszip, boolean isEncryptResponse, OnHttpResonseListener httpResonseListener) throws IOException, NullResonseListenerException {
        Request request = OKHttpUtil.getRequest(url, params, headers, isrsa, iszip, isEncryptResponse);
        sendRequest(request, isEncryptResponse, httpResonseListener);
    }


    @Override
    public com.yc.adplatform.securityhttp.net.entry.Response uploadFile(String url, UpFileInfo upFileInfo, Map<String, String> params, Map<String, String> headers, boolean isEncryptResponse) throws IOException {
        if (upFileInfo == null || (upFileInfo.file == null && upFileInfo.buffer == null))
            throw new FileNotFoundException("file is null");

        Request request = OKHttpUtil.getRequest(url, params, headers, upFileInfo, isEncryptResponse);

        return sendRequest(request, isEncryptResponse);
    }


    @Override
    public void auploadFile(String url, UpFileInfo upFileInfo, Map<String, String> params, Map<String, String> headers, boolean isEncryptResponse, OnHttpResonseListener httpResonseListener) throws IOException, NullResonseListenerException {
        if (httpResonseListener == null) throw new NullResonseListenerException();

        if (upFileInfo == null || (upFileInfo.file == null && upFileInfo.buffer == null)) throw new
                FileNotFoundException
                ("file is" +
                        " null");

        Request request = OKHttpUtil.getRequest(url, params, headers, upFileInfo, isEncryptResponse);

        sendRequest(request, isEncryptResponse, httpResonseListener);
    }


    @Override
    public void cancel(String url) {
        if (client == null) throw new NullPointerException("client == null");

        for (Call call : client.dispatcher().queuedCalls()) {
            if (url.equals(call.request().tag())) call.cancel();
        }
        for (Call call : client.dispatcher().runningCalls()) {
            if (url.equals(call.request().tag())) call.cancel();
        }
    }

    private com.yc.adplatform.securityhttp.net.entry.Response sendRequest(Request request, boolean isEncryptResponse) throws IOException {
        com.yc.adplatform.securityhttp.net.entry.Response nresponse = null;
        if (request == null) {
            LogUtil.msg("error request is null", LogUtil.E);
            return null;
        }
        Call call = client.newCall(request);
        Response response = call.execute();
        if (response.isSuccessful()) {
            String body = response.body().string();
            nresponse = OKHttpUtil.setResponse(response.code(), body);
            LogUtil.msg("服务器返回数据->" + body);
        }

        if (nresponse == null) {
            nresponse = new com.yc.adplatform.securityhttp.net.entry.Response();
            nresponse.body = "{\"code\":" + response.code() + ", \"message\":\"" + response.body().string().replaceAll("\"", "'") + "\"}";
            nresponse.code = response.code();
        }
        nresponse.response = response;
        return nresponse;
    }

    private void sendRequest(Request request, final boolean
            isEncryptResponse, final OnHttpResonseListener httpResonseListener) {
        if (request == null) {
            LogUtil.msg("aerror request is null", LogUtil.E);
            return;
        }

        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                com.yc.adplatform.securityhttp.net.entry.Response response = OKHttpUtil.setResponse(-1, HttpConfig.NET_ERROR);
                httpResonseListener.onFailure(response);
                LogUtil.msg("网络请求失败->" + e.getMessage(), LogUtil.W);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                com.yc.adplatform.securityhttp.net.entry.Response nresponse = null;
                String body = response.body().string();
                LogUtil.msg("服务器返回数据->" + body);
                nresponse = OKHttpUtil.setResponse(response.code(), body);
                nresponse.response = response;
                httpResonseListener.onSuccess(nresponse);
            }
        });
    }
}
<file_sep># "小游戏SDK” 对接文档


- 示例
   -  [MainActivity.java](https://github.com/YangChengTeam/AdPlatformSDKExample/blob/master/app/src/main/java/com/yc/adplatformsdkexample/MainActivity.java)

- 配置
  - 导入aar open_ad_sdk.aar  [下载open_ad_sdk](https://github.com/YangChengTeam/AdPlatformSDKExample/blob/master/app/libs/open_ad_sdk.aar)
  - 根目录build.gradle maven配置  [查看](https://github.com/YangChengTeam/AdPlatformSDKExample/blob/master/build.gradle)
    -   maven {url 'https://raw.githubusercontent.com/YangChengTeam/AdPlatformSDKExample/master/lib/AAR'}

  - 项目build.gradle  implementation 'com.yc.adplatformsdk:aar:1.3.0'  
  - AndroidManifest.xml 权限配置  [查看](https://github.com/YangChengTeam/AdPlatformSDKExample/blob/master/app/src/main/AndroidManifest.xml)

- 代码
   -  生成对象 
      - AdPlatformSDK adPlatformSDK = AdPlatformSDK.getInstance(this);
   -  设置默认广告默认值
      - adPlatformSDK.setAdConfigInfo() //
      - adPlatformSDK.setInitUrl()  //
   -  初始化 
      - adPlatformSDK.init()
   -  调用广告
      - 开屏 
         - adPlatformSDK.showSplashAd()
      - 信息流
         - adPlatformSDK.showExpressAd()
      - 横屏
         - adPlatformSDK.showBannerAd()
      - 激励视频  
         - 竖屏
             - adPlatformSDK.showRewardVideoVerticalAd()
         - 横屏
             - adPlatformSDK.showRewardVideoHorizontalAd()
      - 全屏视频  
         - 竖屏
             - adPlatformSDK.showFullScreenVideoVerticalAd()
         - 横屏
             - adPlatformSDK.showFullScreenVideoHorizontalAd()
      - 插屏 
         - adPlatformSDK.showInsertAd()
<file_sep>package com.yc.adplatform.log;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class LogSDK {
    public static LogSDK sInstance;
    private String mIp;
    private int mPort;

    public static LogSDK getInstance() {
        if (sInstance == null) {
            synchronized (LogSDK.class) {
                if (sInstance == null) {
                    sInstance = new LogSDK();
                }
            }
        }
        return sInstance;
    }

    public void init(String ip, int port) {
        this.mIp = ip;
        this.mPort = port;
    }

    public void send(String cvs) {
        send(mIp, mPort, cvs);
    }

    public void send(int port, String cvs) {
        send(mIp, port, cvs);
    }

    public void send(String ip, int port, String cvs) {
        DatagramSocket ds = null;
        try {
            InetAddress addr = InetAddress.getByName(ip);
            ds = new DatagramSocket();
            DatagramPacket dp;
            dp = new DatagramPacket(cvs.getBytes(), cvs.getBytes().length, addr, port);
            ds.setBroadcast(true);
            ds.send(dp);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ds != null) {
                ds.close();
            }
        }
    }
}


