광고용 웹 뷰 API를 사용하면 CustomTabSession의 태그에서 앱 신호를 사용할 수 있으므로 콘텐츠를 제공한 웹 게시자의 수익 창출을 개선하고 광고주를 스팸으로부터 보호할 수 있습니다.
작동 방식
GMA 차세대 SDK와의 통신은 다음 중 하나에 의해 트리거된 광고 이벤트에 대한 응답으로만 발생합니다.
GMA 차세대 SDK는 Android 프레임워크에서 제공하는 CustomTabsSession과의 postMessage 채널을 열어 통신을 지원합니다.
기본 요건
- GMA 차세대 SDK 0.6.0-alpha01 이상
- 모바일 앱의 기존 Chrome 맞춤 탭 구현. 워밍업 및 프리패치: 맞춤 탭 서비스 사용을 참고하세요.
- 디지털 애셋 링크를 사용하여 모바일 앱을 웹사이트에 연결 자세한 내용은 TWA용 PostMessage를 참고하세요.
SDK에 애플리케이션 ID 전달하기
이미 AdMob 애플리케이션 ID가 있는 경우 기존 애플리케이션 ID로 GMA 차세대 SDK를 초기화하세요.
AdMob 애플리케이션 ID가 없는 경우 GMA 차세대 SDK를 초기화할 때 InitializationConfig.WEBVIEW_APIS_FOR_ADS_APPLICATION_ID를 애플리케이션 ID로 전달하세요.
Kotlin
MobileAds.initialize(
this@MainActivity,
// Use this application ID to initialize the GMA Next Gen SDK if
// you don't have an AdMob application ID.
InitializationConfig.Builder(InitializationConfig.WEBVIEW_APIS_FOR_ADS_APPLICATION_ID)
.build(),
) {
// Adapter initialization complete.
}
자바
MobileAds.initialize(
this,
// Use this application ID to initialize the GMA Next Gen SDK if
// you don't have an AdMob application ID.
new InitializationConfig.Builder(InitializationConfig.WEBVIEW_APIS_FOR_ADS_APPLICATION_ID)
.build(),
initializationStatus -> {
// Adapter initialization is complete.
});
구현
Chrome 맞춤 탭 구현 내에서 onCustomTabsServiceConnected() 콜백의 코드를 수정합니다. newSession()을 MobileAds.registerCustomTabsSession()으로 바꿉니다. 이렇게 하면 postMessage 채널과의 연결이 설정되어 SDK 신호로 광고 태그를 보강할 수 있습니다. postMessage 채널을 연결하려면 디지털 애셋 링크가 필요합니다. 원하는 경우 CustomTabsCallback 매개변수를 설정하여 Chrome 맞춤 탭 이벤트를 수신 대기할 수 있습니다.
GMA 차세대 SDK에서 수신한 CustomTabsSession에서 메시지를 전송할 수 있지만 SDK에서 기존 채널을 재정의하는 새 채널을 요청하면 포트가 변경될 수 있습니다.
다음 코드 스니펫은 GMA 차세대 SDK를 사용하여 CustomTabsSession을 등록하는 방법을 보여줍니다.
Kotlin
import com.google.android.libraries.ads.mobile.sdk.MobileAds
class MainActivity : ComponentActivity() {
private var customTabsClient: CustomTabsClient? = null
private var customTabsSession: CustomTabsSession? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Get the default browser package name, this will be null if
// the default browser does not provide a CustomTabsService.
val packageName = CustomTabsClient.getPackageName(applicationContext, null);
if (packageName == null) {
// Do nothing as service connection is not supported.
return
}
CustomTabsClient.bindCustomTabsService(
applicationContext,
packageName,
object : CustomTabsServiceConnection() {
override fun onCustomTabsServiceConnected(
name: ComponentName, client: CustomTabsClient,
) {
customTabsClient = client
// Warm up the browser process.
customTabsClient?.warmup(0L)
// Create a new browser session using the GMA Next Gen SDK.
customTabsSession = MobileAds.INSTANCE.registerCustomTabsSession(
client,
// Checks the "Digital Asset Link" to connect the postMessage channel.
ORIGIN,
// Optional parameter to receive the delegated callbacks.
customTabsCallback
)
// Create a new browser session if the GMA Next Gen SDK is
// unable to create one.
if (customTabsSession == null) {
customTabsSession = client.newSession(customTabsCallback)
}
// Pass the custom tabs session into the intent.
val customTabsIntent = CustomTabsIntent.Builder(customTabsSession).build()
customTabsIntent.launchUrl(this@MainActivity,
Uri.parse("YOUR_URL"))
}
override fun onServiceDisconnected(componentName: ComponentName) {
// Remove the custom tabs client and custom tabs session.
customTabsClient = null
customTabsSession = null
}
})
}
// Listen for events from the CustomTabsSession delegated by the GMA Next Gen SDK.
private val customTabsCallback: CustomTabsCallback = object : CustomTabsCallback() {
@Synchronized
override fun onNavigationEvent(navigationEvent: Int, extras: Bundle?) {
// Called when a navigation event happens.
}
@Synchronized
override fun onMessageChannelReady(extras: Bundle?) {
// Called when the channel is ready for sending and receiving messages on both
// ends.
// This frequently happens, such as each time the SDK requests a
// new channel.
}
@Synchronized
override fun onPostMessage(message: String, extras: Bundle?) {
// Called when a tab controlled by this CustomTabsSession has sent a postMessage.
}
override fun onRelationshipValidationResult(
relation: Int, requestedOrigin: Uri, result: Boolean, extras: Bundle?
) {
// Called when a relationship validation result is available.
}
override fun onActivityResized(height: Int, width: Int, extras: Bundle) {
// Called when the tab is resized.
}
override fun extraCallback(callbackName: String, args: Bundle?) {
}
override fun extraCallbackWithResult(callbackName: String, args: Bundle?): Bundle? {
return null
}
}
companion object {
// Replace this URL with an associated website.
const val ORIGIN = "https://www.google.com"
}
}
Java
import com.google.android.libraries.ads.mobile.sdk.MobileAds;
class MainActivity extends ComponentActivity {
// Replace this URL with an associated website.
private static final String ORIGIN = "https://www.google.com";
private CustomTabsClient customTabsClient;
private CustomTabsSession customTabsSession;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the default browser package name, this will be null if
// the default browser does not provide a CustomTabsService.
String packageName = CustomTabsClient.getPackageName(getApplicationContext(), null);
if (packageName == null) {
// Do nothing as service connection is not supported.
return;
}
CustomTabsClient.bindCustomTabsService(
getApplicationContext(),
packageName,
new CustomTabsServiceConnection() {
@Override
public void onCustomTabsServiceConnected(@NonNull ComponentName name,
@NonNull CustomTabsClient client) {
customTabsClient = client;
// Warm up the browser process.
customTabsClient.warmup(0);
// Create a new browser session using the GMA Next Gen SDK.
customTabsSession = MobileAds.INSTANCE.registerCustomTabsSession(
client,
// Checks the "Digital Asset Link" to connect the postMessage channel.
ORIGIN,
// Optional parameter to receive the delegated callbacks.
customTabsCallback);
// Create a new browser session if the GMA Next Gen SDK is
// unable to create one.
if (customTabsSession == null) {
customTabsSession = client.newSession(customTabsCallback);
}
// Pass the custom tabs session into the intent.
CustomTabsIntent intent = new CustomTabsIntent.Builder(customTabsSession).build();
intent.launchUrl(MainActivity.this, Uri.parse("YOUR_URL"));
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
// Remove the custom tabs client and custom tabs session.
customTabsClient = null;
customTabsSession = null;
}
}
);
}
// Listen for events from the CustomTabsSession delegated by the GMA Next Gen SDK.
private final CustomTabsCallback customTabsCallback = new CustomTabsCallback() {
@Override
public void onNavigationEvent(int navigationEvent, @Nullable Bundle extras) {
// Called when a navigation event happens.
super.onNavigationEvent(navigationEvent, extras);
}
@Override
public void onMessageChannelReady(@Nullable Bundle extras) {
// Called when the channel is ready for sending and receiving messages on both
// ends.
// This frequently happens, such as each time the SDK requests a
// new channel.
super.onMessageChannelReady(extras);
}
@Override
public void onPostMessage(@NonNull String message, @Nullable Bundle extras) {
// Called when a tab controlled by this CustomTabsSession has sent a postMessage.
super.onPostMessage(message, extras);
}
@Override
public void onRelationshipValidationResult(int relation, @NonNull Uri requestedOrigin,
boolean result, @Nullable Bundle extras) {
// Called when a relationship validation result is available.
super.onRelationshipValidationResult(relation, requestedOrigin, result, extras);
}
@Override
public void onActivityResized(int height, int width, @NonNull Bundle extras) {
// Called when the tab is resized.
super.onActivityResized(height, width, extras);
}
@Override
public void extraCallback(@NonNull String callbackName, @Nullable Bundle args) {
super.extraCallback(callbackName, args);
}
@Nullable
@Override
public Bundle extraCallbackWithResult(@NonNull String callbackName, @Nullable Bundle args) {
return super.extraCallbackWithResult(callbackName, args);
}
};
}