添加了 Admob,现在收到了 AudioManager 日志的垃圾邮件
Added Admob and now getting spammed with AudioManager logs
我在我的 Flutter 应用中添加了 admob 横幅广告和插页式广告。看起来它在工作,但我收到了这些日志的垃圾邮件:
Instantiating com.google.android.gms.ads.ChimeraAdManagerCreatorImpl
I/Ads (15325): Use RequestConfiguration.Builder().setTestDeviceIds(Arrays.asList("0C008B27375A350F4FEE8604765FC4E4")) to get test ads on this device.
I/DynamiteModule(15325): Considering local module com.google.android.gms.ads.dynamite:0 and remote module com.google.android.gms.ads.dynamite:212910700
I/DynamiteModule(15325): Selected remote version of com.google.android.gms.ads.dynamite, version >= 212910700
I/DynamiteModule(15325): Considering local module com.google.android.gms.ads.dynamite:0 and remote module com.google.android.gms.ads.dynamite:212910700
I/DynamiteModule(15325): Selected remote version of com.google.android.gms.ads.dynamite, version >= 212910700
V/AudioManager(15325): getMode...
V/AudioManager(15325): isMusicActive...
V/AudioManager(15325): isSpeakerphoneOn: false
V/AudioManager(15325): getStreamVolume streamType: 3 volume: 15
V/AudioManager(15325): getStreamVolume streamType: 2 volume: 7
正如您在此处看到的那样,应用收听音量、音乐和扬声器 activity 并且这种情况一次又一次地发生。该日志不断出现。我确实在不同的 phones 上以发布模式尝试了我的应用程序的 apk 并得到了相同的结果。又崩溃了。
这是我的 Admob Class 代码:
import 'package:google_mobile_ads/google_mobile_ads.dart';
class Reklam {
static String get bannerUnit => "ca-app-pub-3940256099942544/6300978111";
InterstitialAd _interstitialAd;
int num_of_attempt_load = 0;
static initialization() {
if (MobileAds.instance == null) {
MobileAds.instance.initialize();
}
}
static BannerAd getBannerAd() {
final BannerAd myBanner = BannerAd(
adUnitId: 'ca-app-pub-MyAppBannerUnitId',
size: AdSize.banner,
request: AdRequest(),
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
print("Reklam yülendi");
},
onAdFailedToLoad: (Ad ad, LoadAdError error) {
print("Reklam yüklenemedi.");
ad.dispose();
},
onAdOpened: (Ad ad) {
print("Reklam açıldı");
}
),
);
return myBanner;
}
void createInterad() {
InterstitialAd.load(
adUnitId: 'ca-app-pub-MyAppInterstitialUnitId',
request: AdRequest(),
adLoadCallback: InterstitialAdLoadCallback(
onAdLoaded: (InterstitialAd ad) {
_interstitialAd = ad;
num_of_attempt_load = 0;
},
onAdFailedToLoad: (LoadAdError error) {
num_of_attempt_load + 1;
_interstitialAd = null;
if (num_of_attempt_load <= 2) {
createInterad();
}
}),
);
}
void showInterad() {
if (_interstitialAd == null) {
return;
}
_interstitialAd.fullScreenContentCallback = FullScreenContentCallback(
onAdShowedFullScreenContent: (InterstitialAd ad) {
print("ad onAdshowedFullscreen");
},
onAdDismissedFullScreenContent: (InterstitialAd ad) {
print("ad Disposed");
ad.dispose();
},
onAdFailedToShowFullScreenContent: (InterstitialAd ad,
AdError aderror) {
print('$ad OnAdFailed $aderror');
ad.dispose();
createInterad();
}
);
_interstitialAd.show();
_interstitialAd = null;
}
}
这里是横幅广告和插页式广告集成代码块到页面:
...
class SinavlarKisilerPageState extends State<SinavlarKisilerPage> {
...
Reklam _reklam = new Reklam(); //Admob Class' definiton as _reklam
@override
Widget build(BuildContext context) {
return Scaffold(
appbar:...,
body: ListView(
...
IconButton(
onPressed: () {
_reklam.createInterad(); //Interstitial Ads creats
}),
...
FloatingActionButton.extended(
onPressed: () async {
_reklam.showInterad(); //Interstitial Ads shows
}),
...
),
bottomNavigationBar: Container( height: 50, child: AdWidget(ad:
Reklam.getBannerAd()..load(), key: UniqueKey(),),), //Banner Ads integration
);
}
}
这是我的 android\build.gradle:
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.8'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
这是我的 android\app\build.gradle:
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 30
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.sinavci"
minSdkVersion 19
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation platform('com.google.firebase:firebase-bom:28.2.0')
implementation 'com.google.firebase:firebase-analytics'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.android.gms:play-services-ads:20.4.0'
}
最后 AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.MyApp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<application
android:label="MyApp"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-MyAppsAdmobId"/>
</application>
</manifest>
这是发布前的最后一步。请帮忙!!
10 月 8 日更新:
我确实找到了一些错误的原因。
首先,如果 phone 静音,Admob 始终会监听包括音量级别、音乐播放或 speakerOn 在内的声音活动,以消除完整的视频广告。所以这很正常。由于我的横幅广告加载连续失败,admob 会按照我的 Admob Class 中的编码对每次失败发送请求,所以我一次又一次地收到该日志消息,就像垃圾邮件一样。
我的应用程序崩溃的原因完全是 setState()
方法。当 setState()
刷新页面并设置新状态时,admob 发送新请求,之后不会出现新页面。我找不到它的解决方案,因为我必须使用 setState()
并且页面需要刷新到新状态。我该如何解决这个问题?请帮忙。
由于有人对我的问题投了赞成票,我将自己找到的解决方案放在这里。正如我在 10 月 8 日所说,原因是 setState()
所以解决方案很简单。我在我的应用程序中使用 Navigator.push...
或 Navigator.pushReplacement...
而不是所有 setState()
函数并且错误已修复。但这在某个地方非常困难,因为我需要定义 class 的新最终必需参数以正确刷新页面或在 İnherited Widget Class
中定义一些其他参数以在刷新页面后按我想要的方式使用它们。所以问题解决了。我发现有一些原因,例如 provider
但我没有足够的时间来学习如何使用它,所以选择这种我知道的方式。
如果有人解释任何其他解决方案会更好,因为我对这个解决方案感觉不满意。必须有更好或更稳定的修复程序。
我在我的 Flutter 应用中添加了 admob 横幅广告和插页式广告。看起来它在工作,但我收到了这些日志的垃圾邮件:
Instantiating com.google.android.gms.ads.ChimeraAdManagerCreatorImpl
I/Ads (15325): Use RequestConfiguration.Builder().setTestDeviceIds(Arrays.asList("0C008B27375A350F4FEE8604765FC4E4")) to get test ads on this device.
I/DynamiteModule(15325): Considering local module com.google.android.gms.ads.dynamite:0 and remote module com.google.android.gms.ads.dynamite:212910700
I/DynamiteModule(15325): Selected remote version of com.google.android.gms.ads.dynamite, version >= 212910700
I/DynamiteModule(15325): Considering local module com.google.android.gms.ads.dynamite:0 and remote module com.google.android.gms.ads.dynamite:212910700
I/DynamiteModule(15325): Selected remote version of com.google.android.gms.ads.dynamite, version >= 212910700
V/AudioManager(15325): getMode...
V/AudioManager(15325): isMusicActive...
V/AudioManager(15325): isSpeakerphoneOn: false
V/AudioManager(15325): getStreamVolume streamType: 3 volume: 15
V/AudioManager(15325): getStreamVolume streamType: 2 volume: 7
正如您在此处看到的那样,应用收听音量、音乐和扬声器 activity 并且这种情况一次又一次地发生。该日志不断出现。我确实在不同的 phones 上以发布模式尝试了我的应用程序的 apk 并得到了相同的结果。又崩溃了。
这是我的 Admob Class 代码:
import 'package:google_mobile_ads/google_mobile_ads.dart';
class Reklam {
static String get bannerUnit => "ca-app-pub-3940256099942544/6300978111";
InterstitialAd _interstitialAd;
int num_of_attempt_load = 0;
static initialization() {
if (MobileAds.instance == null) {
MobileAds.instance.initialize();
}
}
static BannerAd getBannerAd() {
final BannerAd myBanner = BannerAd(
adUnitId: 'ca-app-pub-MyAppBannerUnitId',
size: AdSize.banner,
request: AdRequest(),
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
print("Reklam yülendi");
},
onAdFailedToLoad: (Ad ad, LoadAdError error) {
print("Reklam yüklenemedi.");
ad.dispose();
},
onAdOpened: (Ad ad) {
print("Reklam açıldı");
}
),
);
return myBanner;
}
void createInterad() {
InterstitialAd.load(
adUnitId: 'ca-app-pub-MyAppInterstitialUnitId',
request: AdRequest(),
adLoadCallback: InterstitialAdLoadCallback(
onAdLoaded: (InterstitialAd ad) {
_interstitialAd = ad;
num_of_attempt_load = 0;
},
onAdFailedToLoad: (LoadAdError error) {
num_of_attempt_load + 1;
_interstitialAd = null;
if (num_of_attempt_load <= 2) {
createInterad();
}
}),
);
}
void showInterad() {
if (_interstitialAd == null) {
return;
}
_interstitialAd.fullScreenContentCallback = FullScreenContentCallback(
onAdShowedFullScreenContent: (InterstitialAd ad) {
print("ad onAdshowedFullscreen");
},
onAdDismissedFullScreenContent: (InterstitialAd ad) {
print("ad Disposed");
ad.dispose();
},
onAdFailedToShowFullScreenContent: (InterstitialAd ad,
AdError aderror) {
print('$ad OnAdFailed $aderror');
ad.dispose();
createInterad();
}
);
_interstitialAd.show();
_interstitialAd = null;
}
}
这里是横幅广告和插页式广告集成代码块到页面:
...
class SinavlarKisilerPageState extends State<SinavlarKisilerPage> {
...
Reklam _reklam = new Reklam(); //Admob Class' definiton as _reklam
@override
Widget build(BuildContext context) {
return Scaffold(
appbar:...,
body: ListView(
...
IconButton(
onPressed: () {
_reklam.createInterad(); //Interstitial Ads creats
}),
...
FloatingActionButton.extended(
onPressed: () async {
_reklam.showInterad(); //Interstitial Ads shows
}),
...
),
bottomNavigationBar: Container( height: 50, child: AdWidget(ad:
Reklam.getBannerAd()..load(), key: UniqueKey(),),), //Banner Ads integration
);
}
}
这是我的 android\build.gradle:
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.8'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
这是我的 android\app\build.gradle:
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 30
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.sinavci"
minSdkVersion 19
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation platform('com.google.firebase:firebase-bom:28.2.0')
implementation 'com.google.firebase:firebase-analytics'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.android.gms:play-services-ads:20.4.0'
}
最后 AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.MyApp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<application
android:label="MyApp"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-MyAppsAdmobId"/>
</application>
</manifest>
这是发布前的最后一步。请帮忙!!
10 月 8 日更新:
我确实找到了一些错误的原因。 首先,如果 phone 静音,Admob 始终会监听包括音量级别、音乐播放或 speakerOn 在内的声音活动,以消除完整的视频广告。所以这很正常。由于我的横幅广告加载连续失败,admob 会按照我的 Admob Class 中的编码对每次失败发送请求,所以我一次又一次地收到该日志消息,就像垃圾邮件一样。
我的应用程序崩溃的原因完全是 setState()
方法。当 setState()
刷新页面并设置新状态时,admob 发送新请求,之后不会出现新页面。我找不到它的解决方案,因为我必须使用 setState()
并且页面需要刷新到新状态。我该如何解决这个问题?请帮忙。
由于有人对我的问题投了赞成票,我将自己找到的解决方案放在这里。正如我在 10 月 8 日所说,原因是 setState()
所以解决方案很简单。我在我的应用程序中使用 Navigator.push...
或 Navigator.pushReplacement...
而不是所有 setState()
函数并且错误已修复。但这在某个地方非常困难,因为我需要定义 class 的新最终必需参数以正确刷新页面或在 İnherited Widget Class
中定义一些其他参数以在刷新页面后按我想要的方式使用它们。所以问题解决了。我发现有一些原因,例如 provider
但我没有足够的时间来学习如何使用它,所以选择这种我知道的方式。
如果有人解释任何其他解决方案会更好,因为我对这个解决方案感觉不满意。必须有更好或更稳定的修复程序。