Android Dependency Integration

This guide explains how to properly integrate common Android libraries into your plugin project. Following these procedures ensures that your plugin works with the most Corona-compatible version of a library and also guarantees that your plugin will be compatible with other plugins that share the same dependency on a library.

Background

When Corona originally opened up the Corona Marketplace to accept content made by third parties, plugin developers could upload any .jar files needed to run their plugin. This resulted in plugins being submitted that would include versions of the Android Support Libraries or Google Play Services. The version of these .jar files would often be the latest version available when the plugin was initially developed, but they were not typically updated when newer versions of the plugin were released.

Essentially, with different versions of libraries floating around inside of plugins, incompatibilities would occur between a plugin needing, for instance, Google Play Services version 8.4 and another plugin needing Google Play Services version 4.2.

Dependency Plugins

In Corona, dependency plugins are special plugins that address version incompatibilities between dependencies which multiple plugins may have. They contain all of the resources for the latest version of a particular library that Corona supports, plus any additional resources to aid in integration and proper usage of a library.

If your project depends on a common Android library like the Android Support Libraries or Google Play Services, you'll need to include a dependency plugin to incorporate that library into your plugin submission. This is to ensure compatibility with other plugins that may be dependent on these libraries.

The following table outlines which libraries are supported by Corona as dependency plugins. While developing your plugin that meets the above criteria, you should test it against the library version encapsulated in a dependency plugin.

Library Dependency Plugin Name Version
Android Support v4 shared.android.support.v4 23.4.0
Android Support v7 – AppCompat shared.android.support.v7.appcompat 23.4.0
Android Support v7 – CardView shared.android.support.v7.cardview 23.4.0
Android Support v7 – RecyclerView shared.android.support.v7.recyclerview 23.4.0
Google Actions, Base Client Library shared.google.play.services.base 9.6.1
Google Analytics shared.google.play.services.analytics 9.6.1
Google Cloud Messaging shared.google.play.services.gcm 9.6.1
Google Drive shared.google.play.services.drive 9.6.1
Google Location shared.google.play.services.location 9.6.1
Google Mobile Ads (AdMob) shared.google.play.services.ads 9.6.1
Google Play Game Services shared.google.play.services.games 9.6.1

Android Support Libraries

Any library with a dependency plugin name containing shared.android.support is part of Google's Android Support Libraries. These dependency plugins encapsulate the respective components listed here and are analogous to adding the following to the dependencies block of your project's build.gradle:

compile 'com.android.support:[COMPONENT_NAME]:[VERSION_NUMBER]'

Google Play Services

Any library with a dependency plugin name containing shared.google.play.services is part of Google Play Services. These dependency plugins encapsulate the respective components listed here and are analogous to adding the following to the dependencies block of your project's build.gradle:

compile 'com.google.android.gms:play-services-[COMPONENT_NAME]:[VERSION_NUMBER]'

Base Logic Layer

The shared.google.play.services.base dependency plugin also includes a base logic layer that will check if the environment on the device is safe for using Google Play Services and attempt to resolve any issues with using the Google Play Services .apk. This is to follow Google's guidelines on ensuring devices have the Google Play Services APK. Resolution attempts are made by presenting either an alert or a notification with context about the issue and how to resolve it. From an alert, the end user would then tap a button and be taken somewhere else on their device to resolve the problem. From a notification, tapping on it will launch the app and present an alert with similar context.

Behavior Changes

When the shared.google.play.services.base dependency plugin is included, your app's main.lua will not begin to execute until any environment issues for using Google Play Services are resolved by the end user. Should an environment change affecting Google Play Services occur during your app's execution, such as the end user disabling Google Play Services on their device, the end user will be presented with an alert or notification similar to when the app was initially launched, prior to main.lua executing.

If the end user just re-enabled Google Play Services and they still need to download an update to Google Play Services, your app will display an alert requesting the end user reboot their device. This reboot is strictly enforced if your app includes the "android.permission.RECEIVE_BOOT_COMPLETED" permission. In this case, your app won't be able to get past this alert until the end user reboots the device. If the "android.permission.RECEIVE_BOOT_COMPLETED" permission is not requested by your app, it will recommend the user reboot their device, but will have no means of enforcing it. This reboot is recommended to get around potential DF-DLA-15 errors from the Google Play store while updating Google Play Services.

Limitations

Note that the base logic layer does not account for issues that may occur while trying to connect to Google Play Services and use Google's APIs. It will only guarantee that the app has access to the correct version of the Google Play Services .apk at all times. When it's time for your plugin to connect to Google Play Services, be sure to follow the Accessing Google APIs and Runtime Permissions guides.

Enterprise Gotchas

To use the base logic layer with a Corona Enterprise project, you will need to identify which components of Google Play Services are being used with <meta-data> tags in the <application> block of your application's AndroidManifest.xml. These tags are used to identify components of Google Play Services that may need additional process. The format for these <meta-data> tags is as follows:

<meta-data android:name="usesGooglePlayServicesComponent[PascalCase_NAME_OF_COMPONENT]" android:value="true" />

Here, [PascalCase_NAME_OF_COMPONENT] corresponds to the [COMPONENT_NAME] that would be specified in the dependencies block of your project's build.gradle. For example, if the dependencies block of your build.gradle includes compile 'com.google.android.gms:play-services-ads:9.6.1', you would need to include the following in the <application> block of AndroidManifest.xml:

<meta-data android:name="usesGooglePlayServicesComponentAds" android:value="true" />

Including Dependency Plugins

To include a dependency plugin when submitting your plugin, add an entry to the coronaManifestdependencies table of your plugin's android/metadata.lua:

local metadata =
{
    plugin =
    {
        -- ...
    },
    coronaManifest = {
        dependencies = {
            ["shared.google.play.services.ads"] = "com.coronalabs",
        },
    },
}

return metadata
Notes
  • The publisher ID for all of the dependency plugins is "com.coronalabs", so entries in the dependencies table should always be of the format ["DEPENDENCY_PLUGIN_NAME"] = "com.coronalabs",.

  • Including one dependency plugin in the dependencies table will also include any dependencies it has. See the Dependency Plugin Chaining section for more information.

Need a common library that's not currently supported? When submitting your plugin, please let us know about any common libraries you're using that may need to be encapsulated as dependency plugins, for example other components of Google Play Services.

Testing Against Dependencies

Most dependency plugins simply wrap the distribution of a library accessible from the Android SDK Manager. In these cases, simply including the correct version of the library in the dependencies block of the plugin's build.gradle (Module: plugin) file is sufficient for testing. For example, a plugin that depends on the CardView library can be accurately tested by adding compile 'com.android.support:cardview-v7:23.4.0' to the dependencies block of the build.gradle (Module: plugin) file.

Other dependency plugins may require additional resources to test against. Any dependency plugin that falls in this category will have an entry in the tarball of plugins provided in the release files of Corona Enterprise, for example within CoronaEnterprisePlugins.2016.2992.tgz. For a dependency plugin with this requirement, be sure to:

Dependency Plugin Chaining

Just as your plugin may rely upon a dependency plugin, a dependency plugin itself may depend upon other dependency plugins. The following flow chart illustrates the chaining between dependency plugins:

Dependency Plugins and Permissions

When using a dependency plugin, some permissions may be automatically added to your app. The following table illustrates which permissions are added for which dependency plugins.

Dependency Plugin Permissions
google.play.services.ads "android.permission.ACCESS_NETWORK_STATE"
"android.permission.INTERNET"
google.play.services.analytics "android.permission.ACCESS_NETWORK_STATE"
"android.permission.INTERNET"
"android.permission.WAKE_LOCK"
google.play.services.gcm "com.google.android.c2dm.permission.RECEIVE"
"android.permission.INTERNET"