-
Notifications
You must be signed in to change notification settings - Fork 285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Native platform ads are not displayed properly on Android #1171
Comments
Hi @YBill, can you further elaborate |
@YBill, disregard the previous question - I can observe it simply by tapping |
I've ran into this as well. Below is a reproducer:
// lib/main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
const _androidNativeAdUnitId = 'ca-app-pub-3940256099942544/2247696110';
const _factoryId = 'myAd';
void main() {
WidgetsFlutterBinding.ensureInitialized();
MobileAds.instance.initialize();
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: AdPage(),
);
}
}
class AdPage extends StatefulWidget {
const AdPage({super.key});
@override
State<AdPage> createState() => _AdPageState();
}
class _AdPageState extends State<AdPage> {
(NativeAd?,)? _nativeAd;
@override
void initState() {
super.initState();
NativeAd(
adUnitId: _androidNativeAdUnitId,
listener: NativeAdListener(
onAdLoaded: _onLoaded,
onAdFailedToLoad: _onFailedToLoad,
),
factoryId: _factoryId,
request: const AdManagerAdRequest(),
).load();
}
void _onLoaded(Ad ad) {
if (mounted) {
setState(() {
_nativeAd = (ad as NativeAd,);
});
} else {
ad.dispose();
}
}
void _onFailedToLoad(Ad ad, LoadAdError error) {
ad.dispose();
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Failed to load an ad: ${error.message}')),
);
setState(() {
_nativeAd = (null,);
});
}
}
@override
void dispose() {
_nativeAd?.$1?.dispose();
_nativeAd = null;
super.dispose();
}
@override
Widget build(BuildContext context) {
final ad = _nativeAd;
return Scaffold(
body: Center(
child: SizedBox(
height: 400,
child: switch (ad) {
(NativeAd ad,) => AdWidget(ad: ad),
(null,) => const Text('Load failed'),
null => const Center(
child: CircularProgressIndicator(),
),
},
),
),
floatingActionButton: switch (ad) {
(NativeAd ad,) => TextButton(
onPressed: () {
setState(() {
_nativeAd = null;
});
Timer(const Duration(seconds: 1), () {
setState(() {
_nativeAd = (ad,);
});
});
},
child: const Text('Hide and show again'),
),
(null,) => null,
null => const CircularProgressIndicator(),
},
);
}
} <!-- android/app/src/main/res/layout/my_ad.xml -->
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/ad_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:text="Ad Title"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Ad Body"
android:textSize="14sp" />
<TextView
android:id="@+id/ad_call_to_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="Call to Action" />
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/ad_main_content"
android:layout_width="250dp"
android:layout_height="175dp"
android:layout_marginBottom="16dp" />
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginBottom="8dp" />
<TextView
android:id="@+id/ad_attribution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:background="#000000"
android:textColor="#ffffff"
android:padding="4dp"
android:text="Ad"
android:textSize="12sp" />
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView> // android/app/src/main/kotlin/com/example/ads_app/MainActivity.kt
package com.example.ads_app
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
GoogleMobileAdsPlugin.registerNativeAdFactory(
flutterEngine, "myAd", AdFactory(layoutInflater))
}
override fun cleanUpFlutterEngine(flutterEngine: FlutterEngine) {
super.cleanUpFlutterEngine(flutterEngine)
GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "myAd")
}
} // android/app/src/main/kotlin/com/example/ads_app/AdFactory.kt
package com.example.ads_app
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.google.android.gms.ads.nativead.MediaView
import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.nativead.NativeAdView
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.NativeAdFactory
class AdFactory(
private val inflater: LayoutInflater,
): NativeAdFactory {
override fun createNativeAd(
nativeAd: NativeAd,
customOptions: MutableMap<String, Any>?
): NativeAdView {
val adView = inflater.inflate(R.layout.my_ad, null) as NativeAdView
val adTitle = adView.findViewById<TextView>(R.id.ad_title)
val adBody = adView.findViewById<TextView>(R.id.ad_body)
val adCallToAction = adView.findViewById<TextView>(R.id.ad_call_to_action)
val adMainContent = adView.findViewById<MediaView>(R.id.ad_main_content)
val adAppIcon = adView.findViewById<ImageView>(R.id.ad_app_icon)
adView.headlineView = adTitle
adView.bodyView = adBody
adView.callToActionView = adCallToAction
adView.mediaView = adMainContent
adView.iconView = adAppIcon
adTitle.text = nativeAd.headline
adBody.text = nativeAd.body
adCallToAction.text = nativeAd.callToAction
adMainContent.mediaContent = nativeAd.mediaContent
val icon = nativeAd.icon
if (icon != null) {
adAppIcon.setImageDrawable(icon.drawable)
} else {
adAppIcon.visibility = View.GONE
}
adView.setNativeAd(nativeAd)
return adView
}
} Add the following meta data just before the <meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713"/> |
@malandr2 Any news on this issue? |
Hi @jellynoone, no update to share at this time but it is something the team is aware of. |
I use the platform Native ads, the ads are loaded successfully and displayed successfully, but the ads are not visible.
onAdLoaded, onAdImpression, and onPaidEvent callbacks are all executed.
But the ad is there, and when I click on it, it will be displayed immediately and I will be redirected to the store.
I click the taskbar and then call back the page and it will be displayed.
You can reproduce it by directly using the Demo provided by Admob. It is not necessary to reproduce it, but if you kill the process and re-enter it, the probability of reproduction is very high.
[https://github.com/googleads/googleads-mobile-flutter] - native_platform_example
Below are the normal and abnormal screenshots:
Phone model:Galaxy Note9
Android version:Android 10
Flutter version:Flutter 3.24.0 • channel stable
Dart version:Dart 3.5.0
The text was updated successfully, but these errors were encountered: