2

Is there any way to integrate ads such as Google's Admob library into gluon mobile on either android or iOS or hopefully both?

This is the gradle file, I have downloaded the Google Play Services library and the google Repository :

buildscript {
    repositories {
        jcenter()       
    }
    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.2.0'
    }
}

apply plugin: 'org.javafxports.jfxmobile'

repositories {
    jcenter()
    maven {
        url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
    }
}

mainClassName = 'graphing.calculator.Calculator'

dependencies {
    compile 'com.gluonhq:charm:4.3.0'
    androidCompile 'com.google.android.gms:play-services-ads:9.4.0'
}

jfxmobile {
    downConfig {
        version = '3.2.0'
        plugins 'display', 'lifecycle', 'statusbar', 'storage'
    }
    android {
        manifest = 'src/android/AndroidManifest.xml'
        androidSdk = '/Users/aniket/Library/Android/sdk'
    }
    ios {
        arch = "arm64"
        infoPList = file('src/ios/Default-Info.plist')
        forceLinkClasses = [
                'com.gluonhq.**.*',
                'javax.annotations.**.*',
                'javax.inject.**.*',
                'javax.json.**.*',
                'org.glassfish.json.**.*'
        ]
    }
}

project.afterEvaluate {
    explodeAarDependencies(project.configurations.androidCompile)
}
Aniket Joshi
  • 115
  • 1
  • 8

1 Answers1

2

Yes, there is a way, for both Android and iOS.

This answer already contains a snippet of how it could be done on Android. But I'll update it here using and extending the Charm Down library. I won't include the iOS solution, though, as it requires modifications in the jfxmobile plugin, as I'll explain later.

Create a new project with the Gluon plugin, and modify the following. You'll have to keep the package names I mention, but you can name your project (and package) as you want.

  1. build.gradle script

You need to include the Google Play Services library:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.3.4'
    }
}

apply plugin: 'org.javafxports.jfxmobile'

repositories {
    jcenter()
    maven {
        url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
    }
}

mainClassName = 'com.gluonhq.adview.GluonAdView' // this can be changed

dependencies {
    compile 'com.gluonhq:charm:4.3.2'

    androidCompile 'com.google.android.gms:play-services-ads:9.4.0'
}

jfxmobile {
    downConfig {
        version '3.2.4'
        plugins 'display', 'lifecycle', 'statusbar', 'storage'
    }
    android {
        manifest = 'src/android/AndroidManifest.xml'
    }
    ios {
        infoPList = file('src/ios/Default-Info.plist')
        forceLinkClasses = [
                'com.gluonhq.**.*',
                'javax.annotations.**.*',
                'javax.inject.**.*',
                'javax.json.**.*',
                'org.glassfish.json.**.*'
        ]
    }
}

project.afterEvaluate {
    explodeAarDependencies(project.configurations.androidCompile)
}

Note the last task: it explodes the aar files on the android/google local repositories, to extract the jars (in this case the Google Play Services jar and all its dependencies).

Note also that after modifying the build file, you need to reload the project (to sync the project and manage the new dependencies).

  1. Source Packages/Java

Besides the project files, you need to add this package: com.gluonhq.charm.down.plugins, and these classes:

AdViewService interface

public interface AdViewService {
    void setAdUnit(String unitId, String testDeviceId, boolean test);
}

AdViewServiceFactory class

public class AdViewServiceFactory extends DefaultServiceFactory<AdViewService> {

    public AdViewServiceFactory() {
        super(AdViewService.class);
    }

}
  1. Android/Java Packages

In the Android/Java package, add this package: com.gluonhq.charm.down.plugins.android, and this class:

AndroidAdViewService class

import android.view.Gravity;
import android.widget.LinearLayout;
import com.gluonhq.charm.down.Services;
import com.gluonhq.charm.down.plugins.LifecycleEvent;
import com.gluonhq.charm.down.plugins.LifecycleService;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import javafxports.android.FXActivity;
import com.gluonhq.charm.down.plugins.AdViewService;

public class AndroidAdViewService implements AdViewService {

    private AdView adView;

    @Override
    public void setAdUnit(String unitId, String testDeviceId, boolean test) {
        FXActivity.getInstance().runOnUiThread(() -> {
            LinearLayout layout = new LinearLayout(FXActivity.getInstance());
            layout.setVerticalGravity(Gravity.BOTTOM);
            layout.setOrientation(LinearLayout.VERTICAL);

            adView = new AdView(FXActivity.getInstance());
            adView.setAdSize(AdSize.SMART_BANNER);
            adView.setAdUnitId(unitId);

            AdRequest adRequest;
            if (test) {
                adRequest = new AdRequest.Builder()
                    .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)        // All emulators
                    .addTestDevice(testDeviceId)        // from logcat!
                    .build();
            } else {
                adRequest = new AdRequest.Builder().build();
            }

            adView.loadAd(adRequest);
            adView.setAdListener(new AdListener() {
                @Override
                public void onAdLoaded() {
                    super.onAdLoaded();
                }
            });

            layout.addView(adView);

            FXActivity.getViewGroup().addView(layout);
        });

        Services.get(LifecycleService.class).ifPresent(service -> {
            service.addListener(LifecycleEvent.RESUME, () -> FXActivity.getInstance().runOnUiThread(() -> adView.resume()));
            service.addListener(LifecycleEvent.PAUSE, () -> FXActivity.getInstance().runOnUiThread(() -> adView.pause()));
        });
    }

}

It makes use of com.google.android.gms.ads.AdView. If your Android dependencies already include Google Play Services, you won't have any problem with the imports. Otherwise, go back to step 1.

Note that I'm setting a layout where the banner will go to the bottom of the screen. Change this at your convenience.

  1. AndroidManifest.xml

You need to add this to the manifest:

<?xml version="1.0" encoding="UTF-8"?>
<manifest ...>
        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <application ...>
                <activity .../>
                <meta-data android:name="com.google.android.gms.version" android:value="9452000" />
                <activity android:name="com.google.android.gms.ads.AdActivity" 
                          android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
                          android:theme="@android:style/Theme.Translucent"/>
        </application>
</manifest>

Note the Google Play Services value corresponds with the 9.4.0 version.

  1. Sample

Now you can add the service to your project. For that you'll need an Ad unit Id. You can create an account on Google AdMob to add your app, and get the App ID for the banner unit.

AdMob

To get the test device id, you'll have to run the app first, and find in the console the id with adb logcat.

public BasicView(String name) {
    super(name);

    Services.get(AdViewService.class).ifPresent(ads -> {
        ads.setAdUnit("ca-app-pub-17652XXXXXXXXXX/83XXXXXXXX", "0283A9A0758XXXXXXXXXXXXXXXX", true);
    });

    Label label = new Label("Hello JavaFX World!");
    ...
}
  1. Run the sample on your Android device

You should see the ads at the bottom, and some logs at the console as well.

04-02 12:42:45.352 25520 25520 I Ads     : Starting ad request.
04-02 12:42:47.844 25520 25520 I Ads     : Scheduling ad refresh 60000 milliseconds from now.
04-02 12:42:47.889 25520 25520 I Ads     : Ad finished loading.

  1. iOS

For iOS it is possible as well. The problem is that it requires downloading the Google Mobile Ads SDK, and adding the GoogleMobileAds.framework to the list of frameworks, so when compiling the native code it finds it.

This should be done in the jfxmobile-plugin, so it is out of scope in this question for now.

Community
  • 1
  • 1
José Pereda
  • 44,311
  • 7
  • 104
  • 132
  • Thank you! This is fantastic! So an iOS implementation for 3rd party libraries such as these that use ".framework" files won't be usable with Gluon until the plug in is updated with an ability to add them as dependencies? – Aniket Joshi Apr 02 '17 at 20:56
  • For now, the plugin doesn't allow adding local frameworks. I believe it should be possible modifying it to allow adding frameworks from local paths with some new clause that could be included in the `build.gradle` file. – José Pereda Apr 02 '17 at 21:04
  • The following error : Could not find com.google.android.gms:play-services-ads:10.2.1. Searched in the following locations: https://jcenter.bintray.com/com/google/android/gms/play-services-ads/10.2.1/play-services-ads-10.2.1.pom https://jcenter.bintray.com/com/google/android/gms/play-services-ads/10.2.1/play-services-ads-10.2.1.jar appears every time I try to build this – Aniket Joshi Apr 03 '17 at 03:22
  • I also attempted it with the version 9.4.0 but when that did not work, I attempted to use 10.2.1, the newest version, and that did not work either – Aniket Joshi Apr 03 '17 at 03:24
  • The issue seems to be with the gradle file rather than the manifest file. The gradle file seems unable to find the location of the dependencies and download them, so building the project never succeeds. I cannot seem to make it past step 1 after editing the gradle file. – Aniket Joshi Apr 03 '17 at 11:52
  • Ok, notice that Google Play Services is installed locally on your machine, you won't get it from a remote repository. For that, the jfxmobile plugin looks for the Android and Google local repositories. Make sure you have installed Google Play Services using the Android SDK Manager. – José Pereda Apr 03 '17 at 11:55
  • I updated the question with my gradle file, but I still can't seem to access the proper libraries, The stacktrace continues to say "Could not find com.google.android.gms:play-services-ads:9.4.0." I have downloaded the Google Play Services and Google Repository libraries – Aniket Joshi Apr 03 '17 at 13:49
  • See this [answer](http://stackoverflow.com/a/42143741/3956070): it shows the steps to install the android/google repositories. It is also important that you define your ANDROID_HOME path in a gradle.properties file, not in the build file. – José Pereda Apr 03 '17 at 13:55
  • 2
    Is it possible to have a more detailed guide about how to do this on IOS too? – FFdeveloper Jun 28 '17 at 11:39
  • Would like to know how to do this on iOS. – Warren Nocos Nov 12 '19 at 00:22