[SOLVED] Extension-admob compile error

Hi,

@fbricker I’m using your extension-admob and receive the following error:

C:\Development\Android SDK\tools\ant\build.xml:573: com.android.io.StreamException: java.io.FileNotFoundException:
C:\Users\Dean\OpenFL\Magic 8 Ball\bin\android\bin\deps\google-play-services_lib\AndroidManifest.xml (The system cannot find the file specified)

I’ve followed your installation instructions, installing google-play-services_lib and android-support-v4, and added to my project.xml:

<set name="openfl-legacy" />
<haxelib name="extension-admob" />
<android target-sdk-version="23" if="android" />
Haxe 3.2.1
actuate: [1.8.6]
box2d: [1.2.3]
extension-admob: [1.5.0]
extension-android-support-v4: [1.0.0]
extension-googleplayservices-lib: [1.1.0]
format: [3.2.1]
hxcpp: [3.2.205]
layout: [1.2.1]
lime-samples: [2.6.0]
lime-tools: [1.5.7]
lime: [2.9.1]
openfl-samples: [3.3.1]
openfl: [3.6.1]
svg: [1.0.9]
swf: [2.2.0]

Portion of my project code:

package;

import extension.admob.AdMob;
import extension.admob.GravityMode;


class Main extends Sprite 
{
	
	public function new() 
	{
		super();
		
		AdMob.enableTestingAds();
		
		AdMob.initAndroid(BANNER_ID, INTERSTITIAL_ID, GravityMode.BOTTOM);
		
		addEventListener(Event.ADDED_TO_STAGE, init);
	}
	
	private function init(e):Void
	{
		
		initialize();
		
		resize (stage.stageWidth, stage.stageHeight);
		
		stage.addEventListener (Event.RESIZE, stage_onResize);
		stage.addEventListener (KeyboardEvent.KEY_UP, stageKeyUp);
		
		AdMob.showBanner();
	}
	
	
	private function initialize():Void
	{
		// ... initialization code...
	}
	
	
	private function gameOver():Void
	{
		//... game over code...
		
		// show every 10 games and > 2 minutes elapsed
		AdMob.showInterstitial(120, 10);
	}
	
	
	private function resize (newWidth:Int, newHeight:Int):Void 
	{
		// ... resize code...
		
		AdMob.onResize();
	}
	
	
	private function stage_onResize(e:Event):Void
	{
		resize (stage.stageWidth, stage.stageHeight);
	}
	
	// ...
}

What am I doing wrong? I appreciate any help with this. Thanks.

Hi, google published a broken version of google-play-services-library on the android SDK manager.
If you have package “Google Play Services” version 30, you should downgrade it to version 29 or wait for version 31.

You can get version 29 here:
https://dl-ssl.google.com/android/repository/google_play_services_8487000_r29.zip

You should place this under:
(ANDROID-SDK-PATH)/extras/google/google_play_services

Then make sure this folder exists.
(ANDROID-SDK-PATH)/extras/google/google_play_services/libproject

Thanks for the quick reply, fbricker, and for providing v29 zip. I had v30 installed and v29 solved the problem.

I really appreciate it!

EDIT:
Just tested it on my phone and it works perfectly. Thanks for this extension. It made adding ads to my app easy.

@fbricker
The banner ads change properly when the screen is rotated, but the interstitial doesn’t rotate. It’s always portrait. Is there something more I need to do than this?

private function stage_onResize(e:Event):Void
{
	resize (stage.stageWidth, stage.stageHeight);
	AdMob.onResize();
}

Also, I didn’t realize I should use special testing ID’s for testing. After getting ad impressions while testing I investigated and found these to use.

Banner Ad Unit ID:
ca-app-pub-3940256099942544/6300978111

Interstitial Ad Unit ID:
ca-app-pub-3940256099942544/1033173712

You may want to add them in your usage instructions, or just have the extension plug them in automatically when using AdMob.enableTestingAds();

EDIT:
It looks like I still receive impressions when using the test ID’s, so extension-admob does handle those when using AdMob.enableTestingAds()? I get the test ads either way. My main concern is that I don’t violate the admob policy. Sorry for my lack of understanding.

Hi, about landscape/portrait: Admob has issues managing orientation changes. This is one of the oldest non-fixed bugs of admob itself (for some ads they just rely on the auto-screen-orientation feature of the phone, which most of the people disables since it’s quite annoying, but it seems like google ignores that fact). :stuck_out_tongue:

About testing ads: You don’t need to create different ad-blocks for that. Just make sure to call enableTestingAds() before calling init(…);

PS: Please refer further issues/support requests on this extesnion direction on github, so the knowledge stays all together on one place.

Hi, finally we created a new library called “extension-googleplayservices-basement” and published updates to all libraries using this library to use the new one.

extension-googleplayservices-basement contains the smaller libraries in which google separated, and will include just the required pieces to your projects according to each extension requirements.

This is good, since you’ll be saving some MB on your games :+1:

So, to be clear:

  • Just doing haxelib upgrade will upgrade google play games, amazon sns, facebookads, and admob extensions to the last SDK versions (no API changes were made, so you shouldn’t have issues at all).
  • extension-googleplayservices-lib is official deprecated (we’ll leave it working for some time until most people migrates to the new extension).
  • Now the SDKs comes inside the extensions (you won’t need to download anything from your Android Device Manager).

But you’re still not using Gradle? Consider switching to my library instead.

Advantages: it doesn’t clutter up the deps folder, it lets you choose from all Google Play Services features (plus support-v7 and appcompat-v7), and it displays an upgrade notice if and only if the user needs to upgrade. The notice even tells you which part of the SDK you need to upgrade, so you only have to download one thing.

Currently working on pull requests.

You could get in trouble for doing this.

(Emphasis added.)

Edit: that said, it looks like it’s ok to redistribute the support-v4 and appcompat-v7 libraries. Everything under extras/android/m2repository is licensed under the Apache License. Problem is, this isn’t true of extras/google/m2repository, which is where the Play Services files are found.

Hmmm… good point.
I thought we couldn’t use gradle with OpenFL yet (that’s why I made it this way). I’ll take a look at your extension and your pull request :slight_smile:

OpenFL 4.1 added Gradle support. Joshua mentioned it near the bottom of the release blog post, but I guess that might be easy to miss.

Let me know if you have any questions! :slight_smile:

I see… so I have a bigger issue now :confused: right now we’re using OpenFL 3.6.1 / Lime 2.9.1, since we’re stuck with Lime Legacy on some developments (and I understand legacy was removed some releases ago).

Thing is, we’re not the only ones using legacy, so moving to gradle will force people to migrate to OpenFL 4.1 (which I think will be good in the long term, but not right now).

So: Can you confirm if the ANT version still works with OpenFL 4.1? Maybe we can make some intermediate implementation to allow ANT on OpenFL 3.X (and also to NME users), and Gladle to OpenFL 4.1+ users… What do you think?

I’m still using Legacy myself, and I added the Gradle code manually. But my build isn’t exactly suitable for distribution, so supporting both sounds like the best option.

It would help to include different libraries based on the version of OpenFL, but sadly, that only works in template files, not include.xml. In case you’re wondering, it would have looked like this:

<haxelib name="google-play-services" if="openfl>=4.1" />
<haxelib name="extension-googleplayservices-basement" unless="openfl>=4.1" />

(You could try if="openfl-legacy", but that just isn’t the same.)


I don’t use version 4.1 myself, but I see one likely issue. But before I get to that, here’s what goes on during the build:

  1. Lime creates an Android project based on the files in lime/3,1,0/templates/android. One of the files is build.gradle, which tells Gradle how to build the project (much like build.xml for Ant builds).
  2. Lime copies dependencies into the deps folder and lists them in settings.gradle.
  3. Lime runs Gradle, and Gradle looks through settings.gradle. For each dependency, Gradle first looks for a build.gradle file. If it finds one, it uses it.
  4. If Gradle doesn’t find a build.gradle file but does find a build.xml file, it concludes it’s looking at an Ant project.
  5. Ant projects use a different folder structure than Gradle’s preferred structure, but fortunately, Gradle is flexible. This code tells Gradle where to find Java source files, JAR files, resources, and AndroidManifest.xml.

For many projects, that’s all Gradle needs to emulate Ant. The problem here is that you use project.properties to declare dependencies, and Gradle doesn’t parse that. Gradle wants dependencies to be listed in build.gradle, and the syntax is different. I might be able to write a regex to parse project.properties and turn it into Gradle’s format, but that wouldn’t be easy, it could break, and it wouldn’t be available until the next Lime release.

Better solution: write a build.gradle file to go alongside your build.xml file. Gradle will use the former and ignore the latter, while Ant will use the latter and ignore the former.

The file would look different from the one in my pull request. In fact, it would look very much like the auto-generated code, just with dependencies:

buildscript {
    repositories {
        maven {
            url "http://repo1.maven.org/maven2/"
        }
    }
    
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
    }
}

apply plugin: 'android-library'

android {
    compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
    buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
    
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            res.srcDirs = ['res']
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(':deps:extension-api')
    compile 'com.google.android.gms:play-services-plus:9.4.0'
    compile 'com.google.android.gms:play-services-drive:9.4.0'
    compile 'com.google.android.gms:play-services-games:9.4.0'
}

(Importing those will automatically import the “Base” and “Basement” projects.)

Or you could import my library and let my library take care of things like error messages and version numbers:

dependencies {
    //...
    compile project(':deps:google-play-services')
}

This would require extra code in your import.xml file, but as far as I know, it wouldn’t hurt either type of build. The Gradle build would ignore extension-googleplayservices-basement, and the Ant build would ignore google-play-games. And by “ignore,” I mean that it wouldn’t impact compile time or output file size.

That’s great… I think we should definitely go this way (using google-play-services for 4.1+ and extension-googleplayservices-basement for the older versions).

I’ll try to make it this week by taking some of your pull requests as an example for the gradle part of the extension (unless you already have some extension with both build.gladle and build.xml working together to look at :slight_smile:)

PS: I think I’ll be contacting you directly on Slack to speed things up when I put my hands into this.

Thanks for your time!!!

Actually, if the plan is to merge the two, then don’t use the pull requests I submitted. They move files to where Gradle expects them, but as I explained above, Ant is pickier about file locations.

I think it might be as simple as taking your existing code and adding the build.gradle file I described (in my previous post, not in the pull requests), but I’ll have to double-check.

Hi, I’ve updated and published a new version of extension-amazon-sns.

I think it supports Gradle and Ant (I tested with Ant / openfl 3.6.1 and it’s working, but I couldn’t deeply test it with OpenFL 4.1 or 4.2, as I couldn’t make anything compile for android on OpenFL 4.1+ -not even pirate pig-).

So, if you have a working OpenFL 4.1+ environment, can you please test it for me?

PS:
I’ve made the extension to use the ANT version if=“openfl-next || openfl-legacy” as I saw that both defines are no longer pressent on openfl 4.1 and 4.2.
For the gladle version of the extension, I’m using your google-play-services extension.

Thanks!

Good call! I thought of using openfl-legacy, but I abandoned the idea because it didn’t account for 3.6.1 in “Next” mode. But now that you point it out, one of those is always defined in 3.6.1.

This will make everything a lot simpler, and it certainly looks like you implemented it correctly. Testing now…

Success! I’m using the following:

lime 3.2.1
openfl 4.2.0
hxcpp 3.3.49
extension-amazon-sns git
extension-googleplayservices-basement 1.0.2 (required because of haxelib.json)
extension-android-support-v4 1.0.0 (ditto)
google-play-services git
openfl-samples 4.0.0
android-ndk-r9d

And here’s how I did it:

  1. Create DisplayingABitmap.
  2. Add “<haxelib name="extension-amazon-sns" />” to project.xml.
  3. Add “extension.amazonsns.AmazonSNS.initGCM('SAMPLE-ID');” to Main.hx.
  4. Optional: because this pull request hasn’t been accepted yet, use a template to set buildDir. (This also means installing the app manually, because Lime won’t be able to find it.)
  5. Compile.

Output:

AmazonSNS-Extension: getMessages: missed 0 message(s)
AmazonSNS-Extension: getMessages: Seeking for intent messages...
AmazonSNS-Extension: getMessages: No messages
trace   : AmazonSNS.hx:62: Registration error: INVALID_SENDER

I assume this is expected, given that I literally used “SAMPLE-ID” as the id.