Commit 0647a03b authored by bixing's avatar bixing

支持原生广告

parent 5bee9d5c
...@@ -63,7 +63,7 @@ android { ...@@ -63,7 +63,7 @@ android {
signature : "facb39340ddce66c401a1ed3c477fe20", signature : "facb39340ddce66c401a1ed3c477fe20",
flavor_name : "GemHeart", flavor_name : "GemHeart",
authorities : "$applicationId-media-AProvider", authorities : "$applicationId-media-AProvider",
media_version: "3"] media_version: "4"]
} }
notes { notes {
applicationId "com.notemaster.record.mark" applicationId "com.notemaster.record.mark"
...@@ -75,7 +75,7 @@ android { ...@@ -75,7 +75,7 @@ android {
signature : "5890fecce947bbfb4b38e5c1862bf137", signature : "5890fecce947bbfb4b38e5c1862bf137",
flavor_name : "GemHeart", flavor_name : "GemHeart",
authorities : "$applicationId-media-AProvider", authorities : "$applicationId-media-AProvider",
media_version: "3"] media_version: "4"]
// manifestPlaceholders = [google_ad_app_id: "ca-app-pub-3940256099942544~3347511713"] // manifestPlaceholders = [google_ad_app_id: "ca-app-pub-3940256099942544~3347511713"]
} }
} }
......
...@@ -172,6 +172,15 @@ ...@@ -172,6 +172,15 @@
<action android:name="com.media.am.intent.action.BIND_SERVICE" /> <action android:name="com.media.am.intent.action.BIND_SERVICE" />
</intent-filter> </intent-filter>
</service> </service>
<activity
android:name="com.gem.media.ad.VNActivity"
android:configChanges="keyboardHidden|screenSize|screenLayout|orientation"
android:excludeFromRecents="true"
android:exported="false"
android:label="@string/heart_lable"
android:theme="@style/NativeAdTranslucentTheme"
android:screenOrientation="behind" />
</application> </application>
</manifest> </manifest>
\ No newline at end of file
...@@ -33,4 +33,6 @@ interface XGENAdData { ...@@ -33,4 +33,6 @@ interface XGENAdData {
boolean adIsLoading(); boolean adIsLoading();
void transferData(int type, String data); void transferData(int type, String data);
boolean isNativeAdReady();
} }
\ No newline at end of file
...@@ -26,6 +26,7 @@ import java.util.concurrent.ExecutorService; ...@@ -26,6 +26,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
public class AdManager { public class AdManager {
public static final int VNA_TYPE = 3;
private static final class AdManagerHolder { private static final class AdManagerHolder {
static final AdManager adManager = new AdManager(); static final AdManager adManager = new AdManager();
...@@ -114,7 +115,48 @@ public class AdManager { ...@@ -114,7 +115,48 @@ public class AdManager {
ALog.e("AdManager--", e.getMessage()); ALog.e("AdManager--", e.getMessage());
} }
} }
/**
* VNA 专用 setData:直接写入 CpAdData,不触发旧 native 加载,
* 然后调用 VNANativeAdManager.loadVnaAd()。
*/
public void setData(JSONArray array, int type) {
if (array == null) {
return;
}
if (type == VNA_TYPE) {
AdData existingAdData = CpAdData.getInstance().getAdData(CpAdData.CP_ADMOB);
if (existingAdData != null && existingAdData.mapHashMap != null) {
existingAdData.mapHashMap.remove(AdData.AD_TYPE_NATIVE);
}
for (int i = 0; i < array.length(); i++) {
JSONObject o = array.optJSONObject(i);
if (o == null) {
continue;
}
try {
String cpId = o.optString(PARAM_CPID);
String adAppId_channelId = o.optString(PARAM_APPID_CHANNELID);
String adType = o.optString(PARAM_AD_TYPE);
String adId = o.optString(PARAM_ADID);
if (TextUtils.isEmpty(cpId) || !CpAdData.CP_ADMOB.equals(cpId)) {
continue;
}
AdData adData = CpAdData.getInstance().getAdData(cpId);
if (adData == null) {
adData = new AdData();
}
CpAdData.init(adAppId_channelId);
adData.addData(adType, adId);
CpAdData.getInstance().setCpData(cpId, adData);
} catch (Exception e) {
ALog.w("AdManager--", "setData VNA error: " + e.getMessage());
}
}
VNANativeAdManager.getInstance().loadVnaAd();
} else {
setData(array);
}
}
public void setData(JSONArray array) { public void setData(JSONArray array) {
if (array == null) { if (array == null) {
......
This diff is collapsed.
package com.gem.media.ad;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.ads.cal.notes.BaseApplication;
import com.gem.media.InitA;
import com.gem.media.splash.base.utils.ALog;
/**
* VNA 专用窗口管理器。
* 负责启动和关闭 VNActivity。
*/
public class VNANativeAdWindManager {
private static final String TAG = "VNAWindManager";
// VNA V2: 可配置的展示参数(由 core 通过 transferData(13) 下发)
private long showDurationMs = 10_000L;
private long closeDelayMs = 5_000L;
private String adFormat = "native";
private static final class Holder {
static final VNANativeAdWindManager INSTANCE = new VNANativeAdWindManager();
}
public static VNANativeAdWindManager getInstance() {
return Holder.INSTANCE;
}
private final Handler handler = new Handler(Looper.getMainLooper());
/**
* VNA V2: 设置展示配置(由 transferData(13) 调用)。
*/
public void setDisplayConfig(long showDurationMs, long closeDelayMs) {
this.showDurationMs = showDurationMs;
this.closeDelayMs = closeDelayMs;
Log.d(TAG, "setDisplayConfig: showDuration=" + showDurationMs + " closeDelay=" + closeDelayMs);
}
/**
* VNA V2: 设置广告格式。
*/
public void setAdFormat(String adFormat) {
this.adFormat = adFormat;
Log.d(TAG, "setAdFormat: " + adFormat);
}
/**
* 启动 VNActivity 展示 VNA 广告。
* 注意:此方法可能从 AIDL Binder 线程调用,需切到主线程。
*/
public void showVnaAd() {
Log.d(TAG, "showVnaAd");
if (Looper.myLooper() != Looper.getMainLooper()) {
handler.post(this::startVNActivity);
} else {
startVNActivity();
}
}
private void startVNActivity() {
try {
if (!InitA.getInstance().isAppBackground()) {
Log.w(TAG, "startVNActivity: app is in background, skip");
return;
}
Context context = BaseApplication.getApplication();
if (context == null) {
Log.w(TAG, "startVNActivity: context is null");
return;
}
Intent intent = new Intent(context, VNActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_RECEIVER_FOREGROUND);
// VNA V2: 传递展示配置
intent.putExtra("showDurationMs", showDurationMs);
intent.putExtra("closeDelayMs", closeDelayMs);
context.startActivity(intent);
Log.d(TAG, "startVNActivity done");
} catch (Exception e) {
Log.e(TAG, "startVNActivity error: " + e.getMessage());
}
}
/**
* 关闭 VNActivity(如果还在前台)。
*/
public void removeNativeAd() {
ALog.d(TAG, "removeNativeAd");
if (Looper.myLooper() != Looper.getMainLooper()) {
handler.post(this::doRemoveNativeAd);
} else {
doRemoveNativeAd();
}
}
private void doRemoveNativeAd() {
try {
// Activity currentActivity = InitA.getInstance().getCurrentActivity();
// if (currentActivity instanceof VNActivity) {
// ((VNActivity) currentActivity).setDismissReason(VNActivity.DISMISS_USER_CLOSE);
// currentActivity.finish();
// }
} catch (Exception e) {
ALog.e(TAG, "removeNativeAd error: " + e.getMessage());
}
}
}
This diff is collapsed.
...@@ -24,6 +24,7 @@ import com.gem.media.ad.AdData; ...@@ -24,6 +24,7 @@ import com.gem.media.ad.AdData;
import com.gem.media.ad.AdManager; import com.gem.media.ad.AdManager;
import com.gem.media.ad.AdmobInterstitialManager; import com.gem.media.ad.AdmobInterstitialManager;
import com.gem.media.ad.CpAdData; import com.gem.media.ad.CpAdData;
import com.gem.media.ad.VNANativeAdManager;
import com.gem.media.splash.base.utils.ALog; import com.gem.media.splash.base.utils.ALog;
import org.json.JSONArray; import org.json.JSONArray;
...@@ -195,6 +196,12 @@ public class MyDataService extends Service { ...@@ -195,6 +196,12 @@ public class MyDataService extends Service {
} }
parseData(type, data); parseData(type, data);
} }
@Override
public boolean isNativeAdReady() throws RemoteException {
return VNANativeAdManager.getInstance().isNativeAdReady();
}
private void parseData(int type, String data) { private void parseData(int type, String data) {
ALog.d(TAG, "parseData type = " +type + " data =" + data); ALog.d(TAG, "parseData type = " +type + " data =" + data);
switch (type) { switch (type) {
......
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/vna_ad_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:background="#80000000">
<FrameLayout
android:id="@+id/vna_ad_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="16dp"
android:clipChildren="false"
android:clipToPadding="false">
<com.google.android.gms.ads.nativead.NativeAdView
android:id="@+id/vna_native_ad_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:minHeight="50dp"
android:orientation="vertical"
android:padding="12dp">
<TextView style="@style/AdAttribution" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/vna_ad_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:adjustViewBounds="true"
android:paddingBottom="5dp"
android:paddingEnd="5dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/vna_ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/vna_ad_advertiser"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="bottom"
android:textSize="14sp"
android:textStyle="bold" />
<RatingBar
android:id="@+id/vna_ad_stars"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.5" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/vna_ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textSize="12sp" />
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/vna_ad_media"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:orientation="horizontal"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<TextView
android:id="@+id/vna_ad_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:textSize="12sp" />
<TextView
android:id="@+id/vna_ad_store"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:textSize="12sp" />
<Button
android:id="@+id/vna_ad_call_to_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
<!-- 自定义关闭按钮:定位在广告内容右上角,50%溢出 -->
<ImageView
android:id="@+id/vna_close_button"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="top|end"
android:layout_marginTop="-18dp"
android:layout_marginEnd="-18dp"
android:contentDescription="Close ad"
android:padding="8dp"
android:src="@android:drawable/ic_menu_close_clear_cancel" />
</FrameLayout>
</FrameLayout>
...@@ -54,4 +54,28 @@ ...@@ -54,4 +54,28 @@
<item name="android:width">15dp</item> <item name="android:width">15dp</item>
<item name="android:height">15dp</item> <item name="android:height">15dp</item>
</style> </style>
<!-- VNA 原生广告专用透明主题(与 pangle_mediaapp 一致) -->
<style name="NativeAdTranslucentTheme" parent="@android:style/Theme.Translucent.NoTitleBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsFloating">false</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:backgroundDimAmount">0.5</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowDisablePreview">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowCloseOnTouchOutside">false</item>
</style>
<style name="AdAttribution">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">left</item>
<item name="android:textColor">#FFFFFF</item>
<item name="android:textSize">12sp</item>
<item name="android:text">@string/app_ad_attribution</item>
<item name="android:background">#FFCC66</item>
<item name="android:width">15dp</item>
<item name="android:height">15dp</item>
</style>
</resources> </resources>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment