diff --git a/build.gradle b/build.gradle
index 6761f15..e15b91d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -26,7 +26,8 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
-
+ ext.kotlin_version = '1.2.50'
+
repositories {
google()
jcenter()
@@ -37,6 +38,7 @@ buildscript {
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.8.2'
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.2'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/button-merchant/src/main/java/com/usebutton/merchant/ButtonInternalImpl.java b/button-merchant/src/main/java/com/usebutton/merchant/ButtonInternalImpl.java
index 9d61168..40e5fa7 100644
--- a/button-merchant/src/main/java/com/usebutton/merchant/ButtonInternalImpl.java
+++ b/button-merchant/src/main/java/com/usebutton/merchant/ButtonInternalImpl.java
@@ -82,7 +82,7 @@ public void trackOrder(ButtonRepository buttonRepository, DeviceManager manager,
@NonNull Order order, @Nullable final UserActivityListener listener) {
if (buttonRepository.getApplicationId() == null) {
if (listener != null) {
- listener.onError(new ApplicationIdNotFoundException());
+ listener.onResult(new ApplicationIdNotFoundException());
}
return;
@@ -93,14 +93,14 @@ public void trackOrder(ButtonRepository buttonRepository, DeviceManager manager,
@Override
public void onTaskComplete(@Nullable Object object) {
if (listener != null) {
- listener.onSuccess();
+ listener.onResult(null);
}
}
@Override
public void onTaskError(Throwable throwable) {
if (listener != null) {
- listener.onError(throwable);
+ listener.onResult(throwable);
}
}
};
@@ -137,12 +137,12 @@ public void handlePostInstallIntent(final ButtonRepository buttonRepository,
DeviceManager deviceManager) {
if (buttonRepository.getApplicationId() == null) {
- listener.onNoPostInstallIntent(new ApplicationIdNotFoundException());
+ listener.onResult(null, new ApplicationIdNotFoundException());
return;
}
if (deviceManager.isOldInstallation() || buttonRepository.checkedDeferredDeepLink()) {
- listener.onNoPostInstallIntent(null);
+ listener.onResult(null, null);
return;
}
@@ -162,16 +162,16 @@ public void onTaskComplete(@Nullable PostInstallLink postInstallLink) {
setAttributionToken(buttonRepository, attribution.getBtnRef());
}
- listener.onPostInstallIntent(deepLinkIntent);
+ listener.onResult(deepLinkIntent, null);
return;
}
- listener.onNoPostInstallIntent(null);
+ listener.onResult(null, null);
}
@Override
public void onTaskError(Throwable throwable) {
- listener.onNoPostInstallIntent(throwable);
+ listener.onResult(null, throwable);
}
}, deviceManager);
}
diff --git a/button-merchant/src/main/java/com/usebutton/merchant/PostInstallIntentListener.java b/button-merchant/src/main/java/com/usebutton/merchant/PostInstallIntentListener.java
index 87be077..d6f9d58 100644
--- a/button-merchant/src/main/java/com/usebutton/merchant/PostInstallIntentListener.java
+++ b/button-merchant/src/main/java/com/usebutton/merchant/PostInstallIntentListener.java
@@ -26,22 +26,22 @@
package com.usebutton.merchant;
import android.content.Intent;
-import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
* Callbacks for post-install intent handler.
*/
public interface PostInstallIntentListener {
-
- /**
- * A post-install url was found. You are responsible for navigating the user
- * -to the appropriate content by starting the attached intent.
- */
- void onPostInstallIntent(@NonNull Intent intent);
-
/**
- * No post-install url was found. Continue with your normal launch sequence.
+ * This callback is used to notify the application that the request to check for a post-app
+ * install deep link is complete. If a deep link was found, it will be returned here. If an
+ * error was encountered while making the request, it will optionally be returned here.
+ *
+ * @param intent if a post-install link was found it will be returned here in the intent data.
+ * The intent can be started to navigate the user to the appropriate location in the app. If no
+ * post-install intent was found, this param will be {@code null}.
+ * @param t if an error was encountered while making the request it will be returned in this
+ * param, otherwise {@code null}.
*/
- void onNoPostInstallIntent(@Nullable Throwable t);
+ void onResult(@Nullable Intent intent, @Nullable Throwable t);
}
diff --git a/button-merchant/src/main/java/com/usebutton/merchant/UserActivityListener.java b/button-merchant/src/main/java/com/usebutton/merchant/UserActivityListener.java
index 512a979..7f2ac03 100644
--- a/button-merchant/src/main/java/com/usebutton/merchant/UserActivityListener.java
+++ b/button-merchant/src/main/java/com/usebutton/merchant/UserActivityListener.java
@@ -33,7 +33,5 @@
* @see ButtonMerchant#trackOrder(android.content.Context, Order, UserActivityListener)
*/
public interface UserActivityListener {
- void onSuccess();
-
- void onError(@Nullable Throwable t);
+ void onResult(@Nullable Throwable t);
}
diff --git a/button-merchant/src/test/java/com/usebutton/merchant/ButtonInternalImplTest.java b/button-merchant/src/test/java/com/usebutton/merchant/ButtonInternalImplTest.java
index 5ff1755..f426f90 100644
--- a/button-merchant/src/test/java/com/usebutton/merchant/ButtonInternalImplTest.java
+++ b/button-merchant/src/test/java/com/usebutton/merchant/ButtonInternalImplTest.java
@@ -121,7 +121,7 @@ public void trackOrder_nullApplicationId() {
buttonInternal.trackOrder(buttonRepository, mock(DeviceManager.class), mock(Order.class),
listener);
- verify(listener).onError(any(ApplicationIdNotFoundException.class));
+ verify(listener).onResult(any(ApplicationIdNotFoundException.class));
verify(buttonRepository, never()).postUserActivity(any(DeviceManager.class),
any(Order.class),
any(Task.Listener.class));
@@ -160,7 +160,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
buttonInternal.trackOrder(buttonRepository, mock(DeviceManager.class), mock(Order.class),
listener);
- verify(listener).onSuccess();
+ verify(listener).onResult(null);
}
@Test
@@ -184,7 +184,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
buttonInternal.trackOrder(buttonRepository, mock(DeviceManager.class), mock(Order.class),
listener);
- verify(listener).onError(throwable);
+ verify(listener).onResult(throwable);
}
@Test
@@ -297,8 +297,7 @@ public void handlePostInstallIntent_returnValidPostInstallLink_setSourceToken()
listenerArgumentCaptor.getValue().onTaskComplete(postInstallLink);
- verify(postInstallIntentListener).onPostInstallIntent(any(Intent.class));
- verify(postInstallIntentListener, never()).onNoPostInstallIntent(any(Throwable.class));
+ verify(postInstallIntentListener).onResult(any(Intent.class), (Throwable) isNull());
verify(buttonRepository).setSourceToken("valid_source_token");
}
@@ -324,8 +323,7 @@ public void handlePostInstallIntent_returnInvalidPostInstallLink_doNotSetSourceT
listenerArgumentCaptor.getValue().onTaskComplete(postInstallLink);
- verify(postInstallIntentListener, never()).onPostInstallIntent(any(Intent.class));
- verify(postInstallIntentListener).onNoPostInstallIntent((Throwable) isNull());
+ verify(postInstallIntentListener).onResult(null, null);
verify(buttonRepository, never()).setSourceToken(anyString());
}
@@ -343,9 +341,8 @@ public void handlePostInstallIntent_nullApplicationId_throwException() {
verify(buttonRepository, never()).getPendingLink(any(Task.Listener.class),
any(DeviceManager.class));
- verify(postInstallIntentListener, never()).onPostInstallIntent(any(Intent.class));
verify(buttonRepository, never()).setSourceToken(anyString());
- verify(postInstallIntentListener).onNoPostInstallIntent(
+ verify(postInstallIntentListener).onResult((Intent) isNull(),
any(ApplicationIdNotFoundException.class));
}
@@ -368,8 +365,8 @@ public void handlePostInstallIntent_throwButtonNetworkException() {
listenerArgumentCaptor.getValue().onTaskError(new ButtonNetworkException(""));
- verify(postInstallIntentListener).onNoPostInstallIntent(any(ButtonNetworkException.class));
- verify(postInstallIntentListener, never()).onPostInstallIntent(any(Intent.class));
+ verify(postInstallIntentListener).onResult((Intent) isNull(),
+ any(ButtonNetworkException.class));
}
@Test
@@ -404,7 +401,7 @@ public void handlePostInstallIntent_oldInstallation_doNotUpdateCheckDeferredDeep
"com.usebutton.merchant",
deviceManager);
- verify(postInstallIntentListener).onNoPostInstallIntent((Throwable) isNull());
+ verify(postInstallIntentListener).onResult(null, null);
verify(buttonRepository, never()).updateCheckDeferredDeepLink(anyBoolean());
}
@@ -422,7 +419,7 @@ public void handlePostInstallIntent_checkedDeferredDeepLink_doNotUpdateCheckDefe
"com.usebutton.merchant",
deviceManager);
- verify(postInstallIntentListener).onNoPostInstallIntent((Throwable) isNull());
+ verify(postInstallIntentListener).onResult((Intent) isNull(), (Throwable) isNull());
verify(buttonRepository, never()).updateCheckDeferredDeepLink(anyBoolean());
}
-}
\ No newline at end of file
+}
diff --git a/sample/build.gradle b/sample/build.gradle
index c6bfea0..3105200 100644
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -24,6 +24,7 @@
*/
apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
def BUTTON_MERCHANT_API_KEY = hasProperty('buttonMerchantAppId') ? '"' + buttonMerchantAppId + '"'
: '"app-1234567890abcdef"'
@@ -59,6 +60,7 @@ dependencies {
implementation "com.android.support:appcompat-v7:$supportLibVersion"
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation "com.android.support:design:$supportLibVersion"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation "junit:junit:$junitVersion"
androidTestImplementation "com.android.support.test:runner:$testRunnerVersion"
androidTestImplementation "com.android.support.test.espresso:espresso-core:$espressoVersion"
diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml
index 12285b7..06b40db 100644
--- a/sample/src/main/AndroidManifest.xml
+++ b/sample/src/main/AndroidManifest.xml
@@ -60,6 +60,11 @@
+
+
diff --git a/sample/src/main/java/com/usebutton/merchant/sample/KotlinActivity.kt b/sample/src/main/java/com/usebutton/merchant/sample/KotlinActivity.kt
new file mode 100644
index 0000000..b5cd6b1
--- /dev/null
+++ b/sample/src/main/java/com/usebutton/merchant/sample/KotlinActivity.kt
@@ -0,0 +1,128 @@
+package com.usebutton.merchant.sample
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.Toolbar
+import android.util.Log
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import android.widget.TextView
+import android.widget.Toast
+import com.usebutton.merchant.ButtonMerchant
+import com.usebutton.merchant.Order.Builder
+import com.usebutton.merchant.sample.R.id
+import java.util.Random
+
+class KotlinActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ val toolbar = findViewById(R.id.toolbar)
+ setSupportActionBar(toolbar)
+
+ ButtonMerchant.trackIncomingIntent(this, intent)
+ val token = ButtonMerchant.getAttributionToken(this)
+ Log.d(TAG, "Attribution Token is $token")
+
+ val textView = findViewById(R.id.attribution_token)
+ textView.text = ButtonMerchant.getAttributionToken(this)
+
+ checkForPostInstallIntent()
+ initTrackNewIntentButton()
+ initTackOrderButton()
+ initClearDataButton()
+ initAttributionTokenListener()
+ }
+
+ private fun checkForPostInstallIntent() {
+ ButtonMerchant.handlePostInstallIntent(this) { intent, t ->
+ if (intent != null) {
+ startActivity(intent)
+ } else if (t != null) {
+ Log.e(TAG, "Error checking post install intent", t)
+ }
+ }
+ }
+
+ private fun initTrackNewIntentButton() {
+ findViewById(id.track_new_intent).setOnClickListener { v ->
+ val intent = Intent()
+ intent.data = Uri.parse(TEST_URL + Random().nextInt(100000))
+ ButtonMerchant.trackIncomingIntent(v.context, intent)
+ }
+ }
+
+ private fun initTackOrderButton() {
+ findViewById(id.track_order).setOnClickListener {
+ val order = Builder("order-id-123")
+ .setAmount(8999)
+ .setCurrencyCode("USD")
+ .build()
+ ButtonMerchant.trackOrder(this, order) { t ->
+ if (t == null) {
+ toastify("Order track success")
+ } else {
+ toastify("Order track error")
+ }
+ }
+ }
+ }
+
+ private fun initClearDataButton() {
+ findViewById(id.clear_all_data).setOnClickListener {
+ ButtonMerchant.clearAllData(this)
+ Log.d(TAG, "Cleared all data")
+
+ val token = ButtonMerchant.getAttributionToken(this)
+ Log.d(TAG, "Attribution Token is $token")
+
+ val textView = findViewById(id.attribution_token)
+ textView.text = ButtonMerchant.getAttributionToken(this)
+ }
+ }
+
+ private fun initAttributionTokenListener() {
+ ButtonMerchant.addAttributionTokenListener(this) { token ->
+ runOnUiThread {
+ findViewById(id.attribution_token).text = token
+ }
+ }
+ }
+
+ private fun toastify(message: String) {
+ runOnUiThread {
+ Toast.makeText(this@KotlinActivity, message, Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ companion object {
+ private const val TAG = "KotlinActivity"
+ private const val TEST_URL = "https://sample-merchant.usebutton.com/?btn_ref=srctok-test"
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(R.menu.main_menu, menu)
+ val kotlinItem = menu.findItem(R.id.action_switch_kotlin)
+ val javaItem = menu.findItem(R.id.action_switch_java)
+ kotlinItem.isVisible = false
+ javaItem.isVisible = true
+ return true
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ when (item.itemId) {
+ R.id.action_switch_kotlin -> {
+ }
+ R.id.action_switch_java -> {
+ val i = Intent(this@KotlinActivity, MainActivity::class.java)
+ finish()
+ startActivity(i)
+ }
+ }
+ return super.onOptionsItemSelected(item)
+ }
+}
diff --git a/sample/src/main/java/com/usebutton/merchant/sample/MainActivity.java b/sample/src/main/java/com/usebutton/merchant/sample/MainActivity.java
index 62a6817..090024b 100644
--- a/sample/src/main/java/com/usebutton/merchant/sample/MainActivity.java
+++ b/sample/src/main/java/com/usebutton/merchant/sample/MainActivity.java
@@ -34,6 +34,8 @@
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
@@ -68,17 +70,13 @@ protected void onCreate(Bundle savedInstanceState) {
ButtonMerchant.handlePostInstallIntent(this, new PostInstallIntentListener() {
@Override
- public void onPostInstallIntent(@NonNull Intent intent) {
- if (intent.getData() != null) {
- Log.d(TAG, "onPostInstallIntent: " + intent + " btn_ref: "
- + intent.getData().getQueryParameter("btn_ref"));
+ public void onResult(@Nullable Intent intent, @Nullable Throwable t) {
+ if (intent != null) {
+ startActivity(intent);
+ } else if (t != null) {
+ Log.e(TAG, "Error checking post install intent", t);
}
}
-
- @Override
- public void onNoPostInstallIntent(@Nullable Throwable t) {
- Log.d(TAG, "onNoPostInstallIntent", t);
- }
});
final Context context = this;
@@ -92,23 +90,17 @@ public void onClick(View v) {
.build();
ButtonMerchant.trackOrder(context, order, new UserActivityListener() {
@Override
- public void onSuccess() {
+ public void onResult(@Nullable final Throwable t) {
runOnUiThread(new Runnable() {
@Override
public void run() {
- Toast.makeText(context, "Order track success",
- Toast.LENGTH_SHORT).show();
- }
- });
- }
-
- @Override
- public void onError(@Nullable Throwable t) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(MainActivity.this, "Order track error",
- Toast.LENGTH_SHORT).show();
+ if (t == null) {
+ Toast.makeText(context, "Order track success",
+ Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(MainActivity.this, "Order track error",
+ Toast.LENGTH_SHORT).show();
+ }
}
});
}
@@ -156,4 +148,30 @@ public void run() {
}
});
}
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main_menu, menu);
+ MenuItem javaItem = menu.findItem(R.id.action_switch_java);
+ MenuItem kotlinItem = menu.findItem(R.id.action_switch_kotlin);
+ javaItem.setVisible(false);
+ kotlinItem.setVisible(true);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_switch_java:
+ break;
+ case R.id.action_switch_kotlin:
+ Intent i = new Intent(MainActivity.this, KotlinActivity.class);
+ finish();
+ startActivity(i);
+ break;
+ default:
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
}
diff --git a/sample/src/main/res/menu/main_menu.xml b/sample/src/main/res/menu/main_menu.xml
new file mode 100644
index 0000000..5174efb
--- /dev/null
+++ b/sample/src/main/res/menu/main_menu.xml
@@ -0,0 +1,39 @@
+
+
+
+
\ No newline at end of file
diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml
index b13179d..57551df 100644
--- a/sample/src/main/res/values/strings.xml
+++ b/sample/src/main/res/values/strings.xml
@@ -26,4 +26,6 @@
Button Merchant
Settings
+ Switch to Java
+ Switch to Kotlin