install_referrer_kit
Google Play Install Referrer for DartNative apps.
It keeps the Flutter play_install_referrer
API, so code written for it ports by changing one import:
// import 'package:play_install_referrer/play_install_referrer.dart';
import 'package:install_referrer_kit/install_referrer_kit.dart';
The call goes over FFI and JNI to Play's InstallReferrerClient; there are
no platform channels. Android only. On iOS the read resolves with a null
referrer (see below).
Install
dependencies:
install_referrer_kit:
hosted: https://dartpub.dev
version: ^0.1.0
dn pub get # regenerates lib/dartnative_plugin_registrant.dart
DartNativePluginRegistrant.registerAll() in main() loads the plugin. No
other setup is needed.
Use
Future<Map<String, String>> installCampaign() async {
try {
final details = await PlayInstallReferrer.installReferrer;
final referrer = details.installReferrer;
if (referrer == null || referrer.isEmpty) return const {};
// e.g. utm_source=google-play&utm_medium=organic
return Uri.splitQueryString(referrer);
} on InstallReferrerException catch (e) {
// e.isUnavailable: no Play Store, or one too old for the API.
return const {};
}
}
ReferrerDetails has upstream's getters:
| Getter | Meaning |
|---|---|
installReferrer |
The referrer URL of the installed package (URL-encoded), or null |
referrerClickTimestampSeconds |
When the referrer click happened (client clock) |
installBeginTimestampSeconds |
When installation began (client clock) |
referrerClickTimestampServerSeconds |
When the referrer click happened (server clock) |
installBeginTimestampServerSeconds |
When installation began (server clock) |
installVersion |
The app's version when it was first installed, or null |
googlePlayInstantParam |
Whether the app's instant experience was launched in the past 7 days |
Play keeps the referrer for 90 days after install. Read it once, early, and remember that you did. The first successful answer is cached for the process.
Platform setup
Android
Nothing to add to the app. The plugin's Gradle module depends on
com.android.installreferrer:installreferrer:2.2 (no transitive
dependencies). Gradle fetches it from Google's Maven repository; this package
doesn't bundle or modify it. It stays under the
Android Software Development Kit License.
Its manifest merges one normal permission,
com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE
(no user prompt). R8 rules ship with the plugin.
Only builds installed from Google Play get a real campaign referrer. On an emulator or a sideloaded build expect one of:
FEATURE_NOT_SUPPORTED(responseCode2) on a Google APIs image, whose Play Store stub is too old for the API;SERVICE_UNAVAILABLE(responseCode1) with no Play Store at all;- typically
utm_source=google-play&utm_medium=organicwith zero timestamps on a device with a current Play Store.
To test a real referrer, install through a Play test track from a link such
as https://play.google.com/store/apps/details?id=<app>&referrer=utm_source%3Dtest.
iOS
iOS has no install referrer, and the package ships no iOS code, pod or
symbols. PlayInstallReferrer.installReferrer resolves with
ReferrerDetails.unsupported: installReferrer and installVersion null,
timestamps 0, googlePlayInstantParam false. It never throws.
Errors
Failures throw InstallReferrerException (Flutter's PlatformException
doesn't exist in DartNative). code keeps play_install_referrer's strings:
code |
When |
|---|---|
SERVICE_UNAVAILABLE |
The connection to the Play Store couldn't be established. |
FEATURE_NOT_SUPPORTED |
The installed Play Store doesn't support the API. |
SERVICE_DISCONNECTED |
The Play Store service dropped the connection (after one retry). |
DEVELOPER_ERROR |
Play reported incorrect usage. |
PERMISSION_ERROR |
The app isn't allowed to bind to the service. |
DEAD_OBJECT_EXCEPTION |
The connection died while being used. |
UNKNOWN_ERROR |
An unknown Play response code. |
UNEXPECTED_ERROR |
Any other exception. |
NATIVE_UNAVAILABLE |
The native library didn't load. |
responseCode holds Play's InstallReferrerResponse value when the service
answered. isUnavailable is true for SERVICE_UNAVAILABLE,
FEATURE_NOT_SUPPORTED, PERMISSION_ERROR and NATIVE_UNAVAILABLE.
Differences from play_install_referrer
InstallReferrerExceptioninstead ofPlatformException, with the same codes.- On iOS the read resolves with a null referrer instead of throwing
MissingPluginException. - Errors are not cached: a failed read can be retried in the same process. Upstream returned its first error until the app was restarted.
- A second service disconnect fails the read with
SERVICE_DISCONNECTED; upstream left it pending forever. ReferrerDetails==,hashCodeandtoStringcover all seven fields (upstream: four), and its constructor isconst.
Testing
debugSetInstallReferrerBackend(backend) from
package:install_referrer_kit/testing.dart routes PlayInstallReferrer
through a fake InstallReferrerBackend in pure-Dart tests.
cd example && dn run -d <device>
The example reads the referrer on start, shows every field, and logs results and exceptions verbatim.
Credits & license
The API, ReferrerDetails and its documentation, and the Install Referrer
connection flow and error codes are adapted from
play_install_referrer
0.5.0 by Lukas Schmierer (BSD-style license). The method channel was
replaced by an FFI/JNI bridge, and error caching and the hang after a second
disconnect were fixed. See THIRD_PARTY_NOTICES.
The Play Install Referrer library
(com.android.installreferrer:installreferrer) is Google's, under the
Android Software Development Kit License; it is a Gradle dependency, not part
of this package.
This package is MIT, see LICENSE.