Panagiotis Triantafyllou

initial commit

Showing 271 changed files with 4781 additions and 0 deletions
1 +*.iml
2 +.gradle
3 +/local.properties
4 +/.idea/caches
5 +/.idea/libraries
6 +/.idea/modules.xml
7 +/.idea/workspace.xml
8 +/.idea/navEditor.xml
9 +/.idea/assetWizardSettings.xml
10 +.DS_Store
11 +/build
12 +/captures
13 +.externalNativeBuild
14 +.cxx
15 +local.properties
1 +apply plugin: 'com.android.application'
2 +
3 +android {
4 + compileSdkVersion 31
5 + buildToolsVersion "31.0.0"
6 +
7 + defaultConfig {
8 + applicationId "warp.ly.android_sdk"
9 + minSdkVersion 23
10 + targetSdkVersion 31
11 + versionCode 100
12 + versionName "1.0.0"
13 + }
14 +
15 + lintOptions {
16 + checkReleaseBuilds false
17 + // Or, if you prefer, you can continue to check for errors in release builds,
18 + // but continue the build even when errors are found:
19 + abortOnError false
20 + }
21 +
22 + signingConfigs {
23 + config {
24 + // Set the parameters based on the actual signing information.
25 + keyAlias 'warplydemo'
26 + keyPassword 'warplydemo'
27 + storeFile file('../keystore/warplydemo.jks')
28 + storePassword 'warplydemo'
29 + }
30 + }
31 +
32 + buildTypes {
33 + debug {
34 +
35 + }
36 + release {
37 + signingConfig signingConfigs.config
38 + minifyEnabled false
39 + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
40 + }
41 + }
42 +}
43 +
44 +dependencies {
45 + implementation fileTree(dir: 'libs', include: ['*.jar'])
46 + implementation project(':libraries:warply_android_sdk')
47 +
48 + //Support
49 + implementation 'androidx.appcompat:appcompat:1.4.1'
50 + implementation 'androidx.recyclerview:recyclerview:1.2.1'
51 + implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
52 +
53 + implementation 'org.altbeacon:android-beacon-library:2.19.3'
54 + implementation 'com.squareup.picasso:picasso:2.5.2'
55 +
56 +}
1 +# Add project specific ProGuard rules here.
2 +# By default, the flags in this file are appended to flags specified
3 +# in C:\Users\philimon\AppData\Local\Android\sdk1/tools/proguard/proguard-android.txt
4 +# You can edit the include path and order by changing the proguardFiles
5 +# directive in build.gradle.
6 +#
7 +# For more details, see
8 +# http://developer.android.com/guide/developing/tools/proguard.html
9 +
10 +# Add any project specific keep options here:
11 +
12 +# If your project uses WebView with JS, uncomment the following
13 +# and specify the fully qualified class name to the JavaScript interface
14 +# class:
15 +#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 +# public *;
17 +#}
18 +#-keep,includedescriptorclasses class com.google.android.gms.** { *; }
19 +#-keep,includedescriptorclasses class com.google.android.gms.internal.** { *; }
20 +#-keep class com.google.android.gms.internal.** {com.google.android.gms.internal.** initialize(android.content.Context);}
21 +-ignorewarnings
22 +-keepattributes *Annotation*
23 +-keepattributes Exceptions
24 +-keepattributes InnerClasses
25 +-keepattributes Signature
26 +-keepattributes SourceFile,LineNumberTable
27 +-keep class com.huawei.hianalytics.**{*;}
28 +-keep class com.huawei.updatesdk.**{*;}
29 +-keep class com.huawei.hms.**{*;}
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 +{
2 + "version": 3,
3 + "artifactType": {
4 + "type": "APK",
5 + "kind": "Directory"
6 + },
7 + "applicationId": "warp.ly.demo",
8 + "variantName": "release",
9 + "elements": [
10 + {
11 + "type": "SINGLE",
12 + "filters": [],
13 + "attributes": [],
14 + "versionCode": 100,
15 + "versionName": "1.0.0",
16 + "outputFile": "app-release.apk"
17 + }
18 + ],
19 + "elementType": "File"
20 +}
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 + package="warp.ly.android_sdk">
4 +
5 + <uses-permission android:name="android.permission.INTERNET" />
6 +
7 + <!-- Restrict Tablets -->
8 + <!-- <supports-screens-->
9 + <!-- android:largeScreens="true"-->
10 + <!-- android:normalScreens="true"-->
11 + <!-- android:smallScreens="true"-->
12 + <!-- android:xlargeScreens="false" />-->
13 +
14 + <application
15 + android:name="warp.ly.android_sdk.WarplyAndroidSDKApplication"
16 + android:allowBackup="false"
17 + android:exported="true"
18 + android:extractNativeLibs="true"
19 + android:fullBackupContent="false"
20 + android:hardwareAccelerated="true"
21 + android:icon="@drawable/ic_notification_logo"
22 + android:installLocation="internalOnly"
23 + android:label="@string/app_name"
24 + android:largeHeap="true"
25 + android:theme="@style/AppTheme">
26 +
27 + <activity
28 + android:name="warp.ly.android_sdk.activities.SplashActivity"
29 + android:exported="true"
30 + android:label="@string/app_name"
31 + android:screenOrientation="portrait">
32 + <intent-filter>
33 + <action android:name="android.intent.action.MAIN" />
34 +
35 + <category android:name="android.intent.category.LAUNCHER" />
36 + </intent-filter>
37 + </activity>
38 +
39 + <activity
40 + android:name="warp.ly.android_sdk.activities.MainActivity"
41 + android:exported="false"
42 + android:label="@string/title_activity_main"
43 + android:screenOrientation="portrait" />
44 +
45 +
46 + </application>
47 +
48 + <!-- For Huawei Push, only if we targetSdkVersion 30, comment if we are in Google build -->
49 + <!-- <queries>-->
50 + <!-- <intent>-->
51 + <!-- <action android:name="com.huawei.hms.core.aidlservice" />-->
52 + <!-- </intent>-->
53 + <!-- </queries>-->
54 +</manifest>
1 +# {@link ly.warp.sdk.utils.WarplyProperty}
2 +
3 +# The app uuid the warply sdk need to connect to the engage server
4 +Uuid=
5 +
6 +# If we need to see logs in Logcat
7 +Debug=false
8 +
9 +# Production or Development environment of the engage server
10 +# Production: https://engage.warp.ly
11 +# Development: https://engage-stage.warp.ly
12 +BaseURL=https://engage-stage.warp.ly
13 +
14 +#WebActionHandler=app_package_name.WarplyWebActionHandler
15 +
16 +# Replace the color with one you want the progress bar to have depending on you app theme-coloring
17 +# If not defined the colorPrimary will used
18 +#ProgressColor=red
19 +
20 +# Replace the drawable with one you want (this will show when web_view loading if not use warply logo will appear)
21 +# If not defined the launcher icon will used
22 +ProgressDrawable=ic_notify
23 +
24 +# If not defined the colorPrimary will used
25 +#PushColor=push_notifications_color
26 +
27 +# If not defined the launcher icon will used (better use the clipart icons for support black/white icons on 24+)
28 +PushIcon=ic_notify
29 +
30 +# If not defined the default will used
31 +#PushSound=push_sound
32 +
33 +# If the device packages need to be send to the engage server
34 +SendPackages=false
35 +
36 +# The language for some requests in case of multi language support
37 +Language=el
38 +
39 +# The merchant id for some requests
40 +MerchantId=20113
41 +
42 +# The login type must be one of the below:
43 +# email, msisdn, username
44 +LoginType=email
45 +
46 +# The deeplink url scheme for react native campaigns:
47 +# Example visit.greece.gr
48 +#DL_URL_SCHEME=
...\ No newline at end of file ...\ No newline at end of file
1 +package warp.ly.android_sdk;
2 +
3 +import android.content.res.Configuration;
4 +
5 +import ly.warp.sdk.receivers.WarplyBeaconsApplication;
6 +
7 +public class WarplyAndroidSDKApplication extends WarplyBeaconsApplication {
8 +
9 + // ===========================================================
10 + // Constants
11 + // ===========================================================
12 +
13 + // ===========================================================
14 + // Fields
15 + // ===========================================================
16 +
17 + // ===========================================================
18 + // Constructors
19 + // ===========================================================
20 +
21 + // ===========================================================
22 + // Getter & Setter
23 + // ===========================================================
24 +
25 + // ===========================================================
26 + // Methods for/from SuperClass/Interfaces
27 + // ===========================================================
28 +
29 + @Override
30 + public void onCreate() {
31 + super.onCreate();
32 +
33 +// registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
34 +// @Override
35 +// public void onActivityCreated(Activity activity, Bundle bundle) {
36 +// activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
37 +// }
38 +//
39 +// @Override
40 +// public void onActivityStarted(Activity activity) {
41 +//
42 +// }
43 +//
44 +// @Override
45 +// public void onActivityResumed(Activity activity) {
46 +//
47 +// }
48 +//
49 +// @Override
50 +// public void onActivityPaused(Activity activity) {
51 +//
52 +// }
53 +//
54 +// @Override
55 +// public void onActivityStopped(Activity activity) {
56 +//
57 +// }
58 +//
59 +// @Override
60 +// public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
61 +//
62 +// }
63 +//
64 +// @Override
65 +// public void onActivityDestroyed(Activity activity) {
66 +//
67 +// }
68 +// });
69 + }
70 +
71 + @Override
72 + public void onConfigurationChanged(Configuration newConfig) {
73 + super.onConfigurationChanged(newConfig);
74 + }
75 +
76 + // ===========================================================
77 + // Methods
78 + // ===========================================================
79 +
80 + // ===========================================================
81 + // Inner and Anonymous Classes
82 + // ===========================================================
83 +}
1 +package warp.ly.android_sdk.activities;
2 +
3 +import android.os.Bundle;
4 +import androidx.fragment.app.FragmentActivity;
5 +import android.widget.Toast;
6 +
7 +import ly.warp.sdk.io.request.WarplyInboxRequest;
8 +import ly.warp.sdk.utils.managers.WarplySessionManager;
9 +
10 +public abstract class BaseActivity extends FragmentActivity {
11 +
12 + // ===========================================================
13 + // Constants
14 + // ===========================================================
15 +
16 + protected final WarplyInboxRequest mInboxRequest = new WarplyInboxRequest().setUseCache(true);
17 +
18 + // ===========================================================
19 + // Fields
20 + // ===========================================================
21 +
22 + private Toast mToast;
23 +
24 + // ===========================================================
25 + // Methods for/from SuperClass/Interfaces
26 + // ===========================================================
27 +
28 + @Override
29 + protected void onCreate(Bundle savedInstanceState) {
30 + super.onCreate(savedInstanceState);
31 + WarplySessionManager.onCreateActivity(this);
32 + }
33 +
34 + @Override
35 + protected void onStart() {
36 + super.onStart();
37 + WarplySessionManager.onStartActivity(this);
38 + }
39 +
40 + @Override
41 + protected void onStop() {
42 + super.onStop();
43 + WarplySessionManager.onStopActivity(this);
44 + }
45 +
46 + // ===========================================================
47 + // Methods
48 + // ===========================================================
49 +
50 + protected void showToast(String message) {
51 +
52 + if (mToast != null) {
53 + mToast.cancel();
54 + }
55 + mToast = Toast.makeText(this, message, Toast.LENGTH_LONG);
56 + mToast.show();
57 + }
58 +
59 + // ===========================================================
60 + // Getter & Setter
61 + // ===========================================================
62 +
63 +
64 + // ===========================================================
65 + // Inner and Anonymous Classes
66 + // ===========================================================
67 +
68 +}
1 +package warp.ly.android_sdk.activities;
2 +
3 +import android.os.Bundle;
4 +
5 +import androidx.fragment.app.FragmentTabHost;
6 +
7 +import warp.ly.android_sdk.R;
8 +import warp.ly.android_sdk.fragments.InfoFragment;
9 +
10 +public class MainActivity extends BaseActivity {
11 +
12 + // ===========================================================
13 + // Constants
14 + // ===========================================================
15 +
16 + // ===========================================================
17 + // Fields
18 + // ===========================================================
19 +
20 + // ===========================================================
21 + // Methods for/from SuperClass/Interfaces
22 + // ===========================================================
23 +
24 + @Override
25 + public void onCreate(Bundle savedInstanceState) {
26 + super.onCreate(savedInstanceState);
27 + setContentView(R.layout.activity_main);
28 + initViews();
29 + }
30 +
31 + @Override
32 + protected void onResume() {
33 + super.onResume();
34 + }
35 +
36 + protected void initViews() {
37 + FragmentTabHost tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
38 + tabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
39 + tabHost.addTab(
40 + tabHost.newTabSpec("info").setIndicator("info", null),
41 + InfoFragment.class, null);
42 +
43 + }
44 +
45 + // ===========================================================
46 + // Methods
47 + // ===========================================================
48 +
49 + // ===========================================================
50 + // Inner and Anonymous Classes
51 + // ===========================================================
52 +
53 +}
1 +package warp.ly.android_sdk.activities;
2 +
3 +import android.content.Intent;
4 +import android.os.Bundle;
5 +
6 +import java.util.Timer;
7 +import java.util.TimerTask;
8 +
9 +import ly.warp.sdk.Warply;
10 +import ly.warp.sdk.io.callbacks.SimpleCallbackReceiver;
11 +import ly.warp.sdk.io.callbacks.WarplyReadyCallback;
12 +import ly.warp.sdk.utils.WarplyInitializer;
13 +import warp.ly.android_sdk.R;
14 +
15 +import static warp.ly.android_sdk.utils.Constants.SENDER_ID;
16 +
17 +public class SplashActivity extends BaseActivity {
18 +
19 + private WarplyInitializer mWarplyInitializer;
20 +
21 + @Override
22 + protected void onCreate(Bundle savedInstanceState) {
23 + super.onCreate(savedInstanceState);
24 + setContentView(R.layout.activity_splash);
25 +
26 + mWarplyInitializer = Warply.getInitializer(this, new WarplyReadyCallback() {
27 + @Override
28 + public void onWarplyReady() {
29 + checkForAppUpdate();
30 + }
31 +
32 + @Override
33 + public void onWarplyInitTimeOut() {
34 + showToast("Warply initialization timeout!");
35 + finish();
36 + }
37 +
38 + @Override
39 + public void onWarplyPermissionsDenied() {
40 + showToast("Warply permissions denied!");
41 +// onWarplyReady();
42 + }
43 + });
44 + }
45 +
46 + @Override
47 + protected void onResume() {
48 + super.onResume();
49 + mWarplyInitializer.initWithPermissions(this);
50 + }
51 +
52 +// @Override
53 +// public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
54 +// mWarplyInitializer.onRequestPermissionsResult(requestCode, permissions, grantResults);
55 +// super.onRequestPermissionsResult(requestCode, permissions, grantResults);
56 +// }
57 +
58 + private void checkForAppUpdate(){
59 +
60 + Warply.checkForAppUpdate(SplashActivity.this, new SimpleCallbackReceiver<Boolean>() {
61 + @Override
62 + public void onResult(Boolean updateAccepted, int errorCode) {
63 + if (!updateAccepted) {
64 + startNextActivity();
65 + }
66 + }
67 + });
68 + }
69 +
70 + private void startNextActivity() {
71 +
72 + if (!isFinishing()) {
73 + long MIN_SPLASH_TIME = 2000;
74 + new Timer().schedule(new TimerTask() {
75 +
76 + @Override
77 + public void run() {
78 +
79 + runOnUiThread(new Runnable() {
80 + public void run() {
81 + if (!isFinishing()) {
82 + Warply.registerGCM(SENDER_ID);
83 + startActivity(new Intent(SplashActivity.this,
84 + MainActivity.class));
85 + finish();
86 + }
87 + }
88 + });
89 + }
90 + }, MIN_SPLASH_TIME);
91 + }
92 + }
93 +}
1 +package warp.ly.android_sdk.fragments;
2 +
3 +import android.os.Bundle;
4 +
5 +import androidx.annotation.Nullable;
6 +import androidx.fragment.app.Fragment;
7 +
8 +import android.os.Handler;
9 +import android.os.Looper;
10 +import android.view.LayoutInflater;
11 +import android.view.View;
12 +import android.view.ViewGroup;
13 +import android.widget.TextView;
14 +
15 +import org.json.JSONException;
16 +import org.json.JSONObject;
17 +
18 +import ly.warp.sdk.io.callbacks.SimpleCallbackReceiver;
19 +import ly.warp.sdk.utils.WarplyDeviceInfoCollector;
20 +import ly.warp.sdk.utils.managers.WarplyAnalyticsManager;
21 +import warp.ly.android_sdk.R;
22 +
23 +import static ly.warp.sdk.utils.constants.WarpConstants.EVENT_PAGE_VIEW;
24 +
25 +public class InfoFragment extends Fragment implements View.OnClickListener {
26 +
27 + // ===========================================================
28 + // Constants
29 + // ===========================================================
30 +
31 + // ===========================================================
32 + // Fields
33 + // ===========================================================
34 +
35 + private TextView tvInfo;
36 +
37 + // ===========================================================
38 + // Methods for/from SuperClass/Interfaces
39 + // ===========================================================
40 +
41 +
42 + @Override
43 + public void onCreate(@Nullable Bundle savedInstanceState) {
44 + super.onCreate(savedInstanceState);
45 +
46 +// RateDialog.with(getContext())
47 +// .setInstallDate(0) // default -1, 0 means 1st launch day(install day).
48 +//// .setLaunchTimes(3) // default -1, 1 means 1st launch day(install day).
49 +// .setRemindInterval(1) // default 1
50 +// .setShowNeutralButton(false) // default true
51 +// .setOnClickButtonListener(which -> {
52 +// })
53 +// .setIsDebug(true) // this is for debug (ignore all conditions)
54 +// .launch();
55 + }
56 +
57 + @Override
58 + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
59 + return inflater.inflate(R.layout.fragment_info, container, false);
60 + }
61 +
62 + @Override
63 + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
64 + super.onViewCreated(view, savedInstanceState);
65 +
66 + tvInfo = (TextView) view.findViewById(R.id.tv_info);
67 + tvInfo.setOnClickListener(this);
68 + new WarplyDeviceInfoCollector(getActivity()).
69 + collectToJson(new SimpleCallbackReceiver<JSONObject>() {
70 + @Override
71 + public void onResult(JSONObject result, int errorCode) {
72 + super.onResult(result, errorCode);
73 + if (result != null) {
74 + new Handler(Looper.getMainLooper()).post(() -> {
75 + try {
76 + tvInfo.setText(result.toString(2));
77 + } catch (JSONException e) {
78 + e.printStackTrace();
79 + }
80 + });
81 + }
82 + }
83 + });
84 + }
85 +
86 + @Override
87 + public void onClick(View view) {
88 +// if(view.getId() == R.id.tv_info){
89 +// Intent sendIntent = new Intent();
90 +// sendIntent.setAction(Intent.ACTION_SEND);
91 +// sendIntent.putExtra(Intent.EXTRA_TEXT, tvInfo.getText().toString());
92 +// sendIntent.setType("text/plain");
93 +// startActivity(Intent.createChooser(sendIntent,"Share"));
94 +// }
95 +
96 +// RateDialog.showRateDialogIfMeetsConditions(getActivity());
97 +
98 + WarplyAnalyticsManager.logEventInApp(
99 + getContext(),
100 + null,
101 + EVENT_PAGE_VIEW + "home",
102 + null,
103 + true);
104 + }
105 +
106 + // ===========================================================
107 + // Methods
108 + // ===========================================================
109 +
110 + // ===========================================================
111 + // Inner and Anonymous Classes
112 + // ===========================================================
113 +
114 +}
1 +package warp.ly.android_sdk.utils;
2 +
3 +/**
4 + * Created by Panagiotis Triantafyllou on 14-Feb-19.
5 + */
6 +
7 +public class Constants {
8 +
9 + public static final String SENDER_ID = "791605800998";
10 +
11 +}
1 +package warp.ly.android_sdk.utils;
2 +
3 +import java.util.ArrayList;
4 +import java.util.List;
5 +import java.util.concurrent.Executors;
6 +import java.util.concurrent.ScheduledExecutorService;
7 +import java.util.concurrent.TimeUnit;
8 +
9 +import org.altbeacon.beacon.AltBeacon;
10 +import org.altbeacon.beacon.Beacon;
11 +
12 +/**
13 + * Created by Matt Tyler on 4/18/14.
14 + */
15 +public class TimedBeaconSimulator implements org.altbeacon.beacon.simulator.BeaconSimulator {
16 + protected static final String TAG = "TimedBeaconSimulator";
17 + private List<Beacon> beacons;
18 +
19 + /*
20 + * You may simulate detection of beacons by creating a class like this in your project.
21 + * This is especially useful for when you are testing in an Emulator or on a device without BluetoothLE capability.
22 + *
23 + * Uncomment lines 36, 37, and 139 - 142 of MonitoringActivity.java and
24 + * set USE_SIMULATED_BEACONS = true to initialize the sample code in this class.
25 + * If using a bluetooth incapable test device (i.e. Emulator), you will want to comment
26 + * out the verifyBluetooth() call on line 32 of MonitoringActivity.java as well.
27 + *
28 + * Any simulated beacons will automatically be ignored when building for production.
29 + */
30 + public boolean USE_SIMULATED_BEACONS = false;
31 +
32 + /**
33 + * Creates empty beacons ArrayList.
34 + */
35 + public TimedBeaconSimulator(){
36 + beacons = new ArrayList<Beacon>();
37 + }
38 +
39 + /**
40 + * Required getter method that is called regularly by the Android Beacon Library.
41 + * Any beacons returned by this method will appear within your test environment immediately.
42 + */
43 + public List<Beacon> getBeacons(){
44 + return beacons;
45 + }
46 +
47 + /**
48 + * Creates simulated beacons all at once.
49 + */
50 + public void createBasicSimulatedBeacons(){
51 + if (USE_SIMULATED_BEACONS) {
52 + Beacon beacon1 = new AltBeacon.Builder().setId1("DF7E1C79-43E9-44FF-886F-1D1F7DA6997A")
53 + .setId2("1").setId3("1").setRssi(-55).setTxPower(-55).build();
54 + Beacon beacon2 = new AltBeacon.Builder().setId1("DF7E1C79-43E9-44FF-886F-1D1F7DA6997A")
55 + .setId2("1").setId3("2").setRssi(-55).setTxPower(-55).build();
56 + Beacon beacon3 = new AltBeacon.Builder().setId1("DF7E1C79-43E9-44FF-886F-1D1F7DA6997A")
57 + .setId2("1").setId3("3").setRssi(-55).setTxPower(-55).build();
58 + Beacon beacon4 = new AltBeacon.Builder().setId1("DF7E1C79-43E9-44FF-886F-1D1F7DA6997A")
59 + .setId2("1").setId3("4").setRssi(-55).setTxPower(-55).build();
60 + beacons.add(beacon1);
61 + beacons.add(beacon2);
62 + beacons.add(beacon3);
63 + beacons.add(beacon4);
64 +
65 +
66 + }
67 + }
68 +
69 +
70 + private ScheduledExecutorService scheduleTaskExecutor;
71 +
72 +
73 + /**
74 + * Simulates a new beacon every 10 seconds until it runs out of new ones to add.
75 + */
76 + public void createTimedSimulatedBeacons(){
77 + if (USE_SIMULATED_BEACONS){
78 + beacons = new ArrayList<Beacon>();
79 + Beacon beacon1 = new AltBeacon.Builder().setId1("DF7E1C79-43E9-44FF-886F-1D1F7DA6997A")
80 + .setId2("1").setId3("1").setRssi(-55).setTxPower(-55).build();
81 + Beacon beacon2 = new AltBeacon.Builder().setId1("DF7E1C79-43E9-44FF-886F-1D1F7DA6997A")
82 + .setId2("1").setId3("2").setRssi(-55).setTxPower(-55).build();
83 + Beacon beacon3 = new AltBeacon.Builder().setId1("DF7E1C79-43E9-44FF-886F-1D1F7DA6997A")
84 + .setId2("1").setId3("3").setRssi(-55).setTxPower(-55).build();
85 + Beacon beacon4 = new AltBeacon.Builder().setId1("DF7E1C79-43E9-44FF-886F-1D1F7DA6997A")
86 + .setId2("1").setId3("4").setRssi(-55).setTxPower(-55).build();
87 + beacons.add(beacon1);
88 + beacons.add(beacon2);
89 + beacons.add(beacon3);
90 + beacons.add(beacon4);
91 +
92 + final List<Beacon> finalBeacons = new ArrayList<Beacon>(beacons);
93 +
94 + //Clearing beacons list to prevent all beacons from appearing immediately.
95 + //These will be added back into the beacons list from finalBeacons later.
96 + beacons.clear();
97 +
98 + scheduleTaskExecutor= Executors.newScheduledThreadPool(5);
99 +
100 + // This schedules an beacon to appear every 10 seconds:
101 + scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
102 + public void run() {
103 + try{
104 + //putting a single beacon back into the beacons list.
105 + if (finalBeacons.size() > beacons.size())
106 + beacons.add(finalBeacons.get(beacons.size()));
107 + else
108 + scheduleTaskExecutor.shutdown();
109 +
110 + }catch(Exception e){
111 + e.printStackTrace();
112 + }
113 + }
114 + }, 0, 10, TimeUnit.SECONDS);
115 + }
116 + }
117 +
118 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package warp.ly.android_sdk.views;
2 +
3 +
4 +import android.view.LayoutInflater;
5 +import android.view.ViewGroup;
6 +import android.widget.ImageView;
7 +import android.widget.TextView;
8 +import com.squareup.picasso.Picasso;
9 +
10 +import ly.warp.sdk.io.models.Campaign;
11 +import ly.warp.sdk.views.CampaignItemViewHolder;
12 +import warp.ly.android_sdk.R;
13 +
14 +
15 +public class CustomCampaignViewsHolder extends CampaignItemViewHolder {
16 +
17 + // ===========================================================
18 + // Constants
19 + // ===========================================================
20 +
21 + // ===========================================================
22 + // Fields
23 + // ===========================================================
24 +
25 + private TextView tvCampaignTitle,
26 + tvCampaignDescription;
27 + private ImageView ivCampaign;
28 +
29 + // ===========================================================
30 + // Constructors
31 + // ===========================================================
32 +
33 + public CustomCampaignViewsHolder(ViewGroup root) {
34 + super((ViewGroup) LayoutInflater.from(root.getContext()).
35 + inflate(R.layout.campaign_recycler_item, root, false));
36 + this.ivCampaign = (ImageView) itemView.findViewById(R.id.iv_campaign);
37 + this.tvCampaignTitle = (TextView) itemView.findViewById(R.id.tv_campaign_title);
38 + this.tvCampaignDescription = (TextView) itemView.findViewById(R.id.tv_campaign_description);
39 + }
40 +
41 + // ===========================================================
42 + // Methods for/from SuperClass/Interfaces
43 + // ===========================================================
44 +
45 + @Override
46 + public void setData(Campaign campaign, int position) {
47 +
48 + Picasso.with(itemView.getContext()).load(campaign.getImageUrl())
49 + .placeholder(R.drawable.ic_notification_logo).into(ivCampaign);
50 + this.tvCampaignTitle.setText(campaign.getTitle());
51 + this.tvCampaignDescription.setText(campaign.getSubtitle());
52 + }
53 +
54 + // ===========================================================
55 + // Methods
56 + // ===========================================================
57 +
58 +
59 + // ===========================================================
60 + // Getter & Setter
61 + // ===========================================================
62 +}
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<selector xmlns:android="http://schemas.android.com/apk/res/android">
3 +
4 + <item android:state_pressed="true"><shape android:shape="rectangle">
5 + <solid android:color="@android:color/darker_gray" />
6 + </shape></item>
7 +
8 +</selector>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<selector xmlns:android="http://schemas.android.com/apk/res/android">
3 +
4 + <item android:drawable="@drawable/next_gray_pressed_icon" android:state_pressed="true"/>
5 + <item android:drawable="@drawable/next_gray_icon"/>
6 +
7 +</selector>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 + android:layout_width="match_parent"
4 + android:layout_height="match_parent"
5 + android:background="#363F45">
6 +
7 + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
8 + android:id="@+id/swipe_refresh"
9 + android:layout_width="match_parent"
10 + android:layout_height="match_parent">
11 +
12 + <ListView
13 + android:id="@+id/lv_inbox"
14 + android:layout_width="match_parent"
15 + android:layout_height="match_parent"
16 + android:layout_marginTop="20dp"
17 + android:cacheColorHint="@android:color/transparent"
18 + android:divider="@android:color/darker_gray"
19 + android:dividerHeight="1dp"
20 + android:fadingEdge="none"
21 + android:fadingEdgeLength="0dp"
22 + android:listSelector="@drawable/selector_gray_light_list_item"
23 + android:overScrollMode="never"
24 + android:persistentDrawingCache="animation|scrolling"
25 + android:scrollbars="none"
26 + android:visibility="visible" />
27 + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
28 +
29 + <ProgressBar
30 + android:id="@+id/pb_inbox"
31 + style="?android:attr/progressBarStyleInverse"
32 + android:layout_width="wrap_content"
33 + android:layout_height="wrap_content"
34 + android:layout_centerInParent="true"
35 + android:layout_gravity="center"
36 + android:visibility="gone" />
37 +</RelativeLayout>
...\ No newline at end of file ...\ No newline at end of file
1 +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 + android:layout_width="match_parent"
3 + android:layout_height="match_parent"
4 + android:background="#363F45">
5 + <androidx.fragment.app.FragmentTabHost
6 + android:id="@android:id/tabhost"
7 + android:layout_width="match_parent"
8 + android:layout_height="match_parent">
9 +
10 + <LinearLayout
11 + android:layout_width="match_parent"
12 + android:layout_height="match_parent"
13 + android:gravity="center"
14 + android:orientation="vertical">
15 +
16 + <HorizontalScrollView
17 + android:id="@+id/horizontalScrollView"
18 + android:layout_width="wrap_content"
19 + android:layout_height="wrap_content"
20 + android:layout_gravity="bottom"
21 + android:background="@android:color/white"
22 + android:scrollbars="none">
23 +
24 + <TabWidget
25 + android:id="@android:id/tabs"
26 + android:layout_width="wrap_content"
27 + android:layout_height="wrap_content"
28 + android:layout_gravity="bottom"
29 + android:background="@android:color/white" />
30 + </HorizontalScrollView>
31 +
32 + <FrameLayout
33 + android:id="@android:id/tabcontent"
34 + android:layout_width="match_parent"
35 + android:layout_height="0dp"
36 + android:layout_weight="1" />
37 + </LinearLayout>
38 +
39 + </androidx.fragment.app.FragmentTabHost>
40 +
41 +</RelativeLayout>
1 +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 + xmlns:tools="http://schemas.android.com/tools"
3 + android:layout_width="match_parent"
4 + android:layout_height="match_parent"
5 + tools:context=".SplashActivity"
6 + android:background="#363F45">
7 +
8 + <ProgressBar
9 + android:id="@+id/progressBar"
10 + style="?android:attr/progressBarStyleLarge"
11 + android:layout_width="wrap_content"
12 + android:layout_height="wrap_content"
13 + android:layout_centerVertical="true"
14 + android:layout_centerHorizontal="true" />
15 +
16 + <ImageView
17 + android:layout_width="wrap_content"
18 + android:layout_height="wrap_content"
19 + android:id="@+id/imageView"
20 + android:layout_above="@+id/progressBar"
21 + android:layout_centerHorizontal="true"
22 + android:src="@drawable/warply_logo_white" />
23 +</RelativeLayout>
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 + android:layout_width="match_parent"
4 + android:layout_height="150dp"
5 + android:gravity="center"
6 + android:orientation="vertical"
7 + android:padding="5dp">
8 +
9 + <LinearLayout
10 + android:layout_width="match_parent"
11 + android:layout_height="wrap_content"
12 + android:gravity="center"
13 + android:orientation="horizontal"
14 + android:weightSum="3">
15 +
16 + <ImageView
17 + android:id="@+id/iv_campaign"
18 + android:layout_width="0dp"
19 + android:layout_height="wrap_content"
20 + android:layout_weight="1"
21 + android:scaleType="center"
22 + android:src="@drawable/ic_launcher" />
23 +
24 + <TextView
25 + android:id="@+id/tv_campaign_title"
26 + android:layout_width="0dp"
27 + android:layout_height="wrap_content"
28 + android:layout_weight="2"
29 + android:ellipsize="end"
30 + android:textColor="@android:color/white"
31 + android:textSize="12sp" />
32 + </LinearLayout>
33 +
34 + <TextView
35 + android:id="@+id/tv_campaign_description"
36 + android:layout_width="match_parent"
37 + android:layout_height="match_parent"
38 + android:layout_marginTop="15dp"
39 + android:ellipsize="end"
40 + android:textColor="@android:color/white" />
41 +
42 +</LinearLayout>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 + android:layout_width="match_parent"
4 + android:layout_height="wrap_content"
5 + android:orientation="horizontal">
6 +
7 + <ImageView
8 + android:id="@+id/iv_campaign"
9 + android:layout_width="wrap_content"
10 + android:layout_height="wrap_content" />
11 +
12 + <LinearLayout
13 + android:layout_width="match_parent"
14 + android:layout_height="wrap_content"
15 + android:layout_toEndOf="@id/iv_campaign"
16 + android:layout_toLeftOf="@+id/iv_next"
17 + android:layout_toRightOf="@id/iv_campaign"
18 + android:layout_toStartOf="@+id/iv_next"
19 + android:orientation="vertical"
20 + android:padding="10dp">
21 +
22 + <TextView
23 + android:id="@+id/tv_campaign_title"
24 + android:layout_width="wrap_content"
25 + android:layout_height="wrap_content"
26 + android:ellipsize="end"
27 + android:textColor="@android:color/white"
28 + android:textSize="20sp" />
29 +
30 + <TextView
31 + android:id="@+id/tv_campaign_description"
32 + android:layout_width="wrap_content"
33 + android:layout_height="wrap_content"
34 + android:layout_marginTop="15dp"
35 + android:ellipsize="end"
36 + android:textColor="@android:color/white" />
37 + </LinearLayout>
38 +
39 + <ImageView
40 + android:id="@+id/iv_next"
41 + android:layout_width="wrap_content"
42 + android:layout_height="wrap_content"
43 + android:layout_alignParentEnd="true"
44 + android:layout_alignParentRight="true"
45 + android:layout_centerVertical="true"
46 + android:layout_marginEnd="10dp"
47 + android:layout_marginRight="10dp"
48 + android:src="@drawable/selector_next_gray_btn" />
49 +
50 +</RelativeLayout>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 + android:layout_width="match_parent"
4 + android:layout_height="wrap_content"
5 + android:orientation="vertical"
6 + android:padding="10dp">
7 +
8 + <ImageView
9 + android:id="@+id/iv_campaign"
10 + android:layout_width="match_parent"
11 + android:layout_height="wrap_content"
12 + android:src="@drawable/ic_notification_logo" />
13 +
14 + <TextView
15 + android:id="@+id/tv_campaign_title"
16 + android:layout_width="wrap_content"
17 + android:layout_height="wrap_content"
18 + android:layout_marginTop="15dp"
19 + android:ellipsize="end"
20 + android:textColor="@android:color/white"
21 + android:textSize="20sp" />
22 +
23 + <TextView
24 + android:id="@+id/tv_campaign_description"
25 + android:layout_width="wrap_content"
26 + android:layout_height="wrap_content"
27 + android:layout_marginTop="5dp"
28 + android:ellipsize="end"
29 + android:textColor="@android:color/white" />
30 +
31 +</LinearLayout>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 + android:layout_width="match_parent"
4 + android:layout_height="match_parent">
5 +
6 + <ScrollView
7 + android:layout_width="match_parent"
8 + android:layout_height="match_parent"
9 + android:layout_margin="15dp">
10 +
11 + <TextView
12 + android:id="@+id/tv_info"
13 + android:layout_width="wrap_content"
14 + android:layout_height="wrap_content"
15 + android:text="@string/middle_activity_info"
16 + android:textAppearance="?android:attr/textAppearanceLarge"
17 + android:textColor="@android:color/white" />
18 + </ScrollView>
19 +</RelativeLayout>
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<resources>
3 + <color name="red">#e46565</color>
4 + <color name="push_notifications_color">#c00</color>
5 + <color name="colorAccent">#c00</color>
6 +</resources>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<resources>
3 +
4 + <string name="app_name">Warply Android SDK Maven Plugin</string>
5 + <string name="hello_world">Hello world!</string>
6 + <string name="action_settings">Settings</string>
7 + <string name="title_activity_main">MainActivity</string>
8 +
9 + <string name="middle_activity_info">Here you can find offers and other valuable info.</string>
10 + <string name="inbox_counter_template">[%1$s]</string>
11 +</resources>
1 +<resources>
2 +
3 + <!-- Base application theme. -->
4 + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
5 + <!-- Customize your theme here. -->
6 + </style>
7 +
8 +</resources>
1 +// Top-level build file where you can add configuration options common to all sub-projects/modules.
2 +
3 +buildscript {
4 + repositories {
5 + mavenCentral()
6 + google()
7 + maven { url 'https://developer.huawei.com/repo/' }
8 + }
9 + dependencies {
10 + classpath 'com.android.tools.build:gradle:7.0.4'
11 + classpath 'com.google.gms:google-services:4.3.10'
12 + classpath 'com.huawei.agconnect:agcp:1.6.2.300'
13 +
14 + // NOTE: Do not place your application dependencies here; they belong
15 + // in the individual module build.gradle files
16 + }
17 +}
18 +
19 +allprojects {
20 + repositories {
21 + mavenCentral()
22 + google()
23 + maven { url 'https://developer.huawei.com/repo/' }
24 + }
25 +}
1 +android.enableJetifier=true
2 +android.useAndroidX=true
...\ No newline at end of file ...\ No newline at end of file
1 +#!/usr/bin/env sh
2 +
3 +#
4 +# Copyright 2015 the original author or authors.
5 +#
6 +# Licensed under the Apache License, Version 2.0 (the "License");
7 +# you may not use this file except in compliance with the License.
8 +# You may obtain a copy of the License at
9 +#
10 +# https://www.apache.org/licenses/LICENSE-2.0
11 +#
12 +# Unless required by applicable law or agreed to in writing, software
13 +# distributed under the License is distributed on an "AS IS" BASIS,
14 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 +# See the License for the specific language governing permissions and
16 +# limitations under the License.
17 +#
18 +
19 +##############################################################################
20 +##
21 +## Gradle start up script for UN*X
22 +##
23 +##############################################################################
24 +
25 +# Attempt to set APP_HOME
26 +# Resolve links: $0 may be a link
27 +PRG="$0"
28 +# Need this for relative symlinks.
29 +while [ -h "$PRG" ] ; do
30 + ls=`ls -ld "$PRG"`
31 + link=`expr "$ls" : '.*-> \(.*\)$'`
32 + if expr "$link" : '/.*' > /dev/null; then
33 + PRG="$link"
34 + else
35 + PRG=`dirname "$PRG"`"/$link"
36 + fi
37 +done
38 +SAVED="`pwd`"
39 +cd "`dirname \"$PRG\"`/" >/dev/null
40 +APP_HOME="`pwd -P`"
41 +cd "$SAVED" >/dev/null
42 +
43 +APP_NAME="Gradle"
44 +APP_BASE_NAME=`basename "$0"`
45 +
46 +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 +
49 +# Use the maximum available, or set MAX_FD != -1 to use that value.
50 +MAX_FD="maximum"
51 +
52 +warn () {
53 + echo "$*"
54 +}
55 +
56 +die () {
57 + echo
58 + echo "$*"
59 + echo
60 + exit 1
61 +}
62 +
63 +# OS specific support (must be 'true' or 'false').
64 +cygwin=false
65 +msys=false
66 +darwin=false
67 +nonstop=false
68 +case "`uname`" in
69 + CYGWIN* )
70 + cygwin=true
71 + ;;
72 + Darwin* )
73 + darwin=true
74 + ;;
75 + MINGW* )
76 + msys=true
77 + ;;
78 + NONSTOP* )
79 + nonstop=true
80 + ;;
81 +esac
82 +
83 +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 +
85 +
86 +# Determine the Java command to use to start the JVM.
87 +if [ -n "$JAVA_HOME" ] ; then
88 + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 + # IBM's JDK on AIX uses strange locations for the executables
90 + JAVACMD="$JAVA_HOME/jre/sh/java"
91 + else
92 + JAVACMD="$JAVA_HOME/bin/java"
93 + fi
94 + if [ ! -x "$JAVACMD" ] ; then
95 + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 +
97 +Please set the JAVA_HOME variable in your environment to match the
98 +location of your Java installation."
99 + fi
100 +else
101 + JAVACMD="java"
102 + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 +
104 +Please set the JAVA_HOME variable in your environment to match the
105 +location of your Java installation."
106 +fi
107 +
108 +# Increase the maximum file descriptors if we can.
109 +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 + MAX_FD_LIMIT=`ulimit -H -n`
111 + if [ $? -eq 0 ] ; then
112 + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 + MAX_FD="$MAX_FD_LIMIT"
114 + fi
115 + ulimit -n $MAX_FD
116 + if [ $? -ne 0 ] ; then
117 + warn "Could not set maximum file descriptor limit: $MAX_FD"
118 + fi
119 + else
120 + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 + fi
122 +fi
123 +
124 +# For Darwin, add options to specify how the application appears in the dock
125 +if $darwin; then
126 + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 +fi
128 +
129 +# For Cygwin or MSYS, switch paths to Windows format before running java
130 +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 + APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 +
134 + JAVACMD=`cygpath --unix "$JAVACMD"`
135 +
136 + # We build the pattern for arguments to be converted via cygpath
137 + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 + SEP=""
139 + for dir in $ROOTDIRSRAW ; do
140 + ROOTDIRS="$ROOTDIRS$SEP$dir"
141 + SEP="|"
142 + done
143 + OURCYGPATTERN="(^($ROOTDIRS))"
144 + # Add a user-defined pattern to the cygpath arguments
145 + if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 + fi
148 + # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 + i=0
150 + for arg in "$@" ; do
151 + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 +
154 + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 + else
157 + eval `echo args$i`="\"$arg\""
158 + fi
159 + i=`expr $i + 1`
160 + done
161 + case $i in
162 + 0) set -- ;;
163 + 1) set -- "$args0" ;;
164 + 2) set -- "$args0" "$args1" ;;
165 + 3) set -- "$args0" "$args1" "$args2" ;;
166 + 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 + esac
173 +fi
174 +
175 +# Escape application args
176 +save () {
177 + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 + echo " "
179 +}
180 +APP_ARGS=`save "$@"`
181 +
182 +# Collect all arguments for the java command, following the shell quoting and substitution rules
183 +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 +
185 +exec "$JAVACMD" "$@"
1 +@rem
2 +@rem Copyright 2015 the original author or authors.
3 +@rem
4 +@rem Licensed under the Apache License, Version 2.0 (the "License");
5 +@rem you may not use this file except in compliance with the License.
6 +@rem You may obtain a copy of the License at
7 +@rem
8 +@rem https://www.apache.org/licenses/LICENSE-2.0
9 +@rem
10 +@rem Unless required by applicable law or agreed to in writing, software
11 +@rem distributed under the License is distributed on an "AS IS" BASIS,
12 +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +@rem See the License for the specific language governing permissions and
14 +@rem limitations under the License.
15 +@rem
16 +
17 +@if "%DEBUG%" == "" @echo off
18 +@rem ##########################################################################
19 +@rem
20 +@rem Gradle startup script for Windows
21 +@rem
22 +@rem ##########################################################################
23 +
24 +@rem Set local scope for the variables with windows NT shell
25 +if "%OS%"=="Windows_NT" setlocal
26 +
27 +set DIRNAME=%~dp0
28 +if "%DIRNAME%" == "" set DIRNAME=.
29 +set APP_BASE_NAME=%~n0
30 +set APP_HOME=%DIRNAME%
31 +
32 +@rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 +
35 +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 +
38 +@rem Find java.exe
39 +if defined JAVA_HOME goto findJavaFromJavaHome
40 +
41 +set JAVA_EXE=java.exe
42 +%JAVA_EXE% -version >NUL 2>&1
43 +if "%ERRORLEVEL%" == "0" goto init
44 +
45 +echo.
46 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 +echo.
48 +echo Please set the JAVA_HOME variable in your environment to match the
49 +echo location of your Java installation.
50 +
51 +goto fail
52 +
53 +:findJavaFromJavaHome
54 +set JAVA_HOME=%JAVA_HOME:"=%
55 +set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 +
57 +if exist "%JAVA_EXE%" goto init
58 +
59 +echo.
60 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 +echo.
62 +echo Please set the JAVA_HOME variable in your environment to match the
63 +echo location of your Java installation.
64 +
65 +goto fail
66 +
67 +:init
68 +@rem Get command-line arguments, handling Windows variants
69 +
70 +if not "%OS%" == "Windows_NT" goto win9xME_args
71 +
72 +:win9xME_args
73 +@rem Slurp the command line arguments.
74 +set CMD_LINE_ARGS=
75 +set _SKIP=2
76 +
77 +:win9xME_args_slurp
78 +if "x%~1" == "x" goto execute
79 +
80 +set CMD_LINE_ARGS=%*
81 +
82 +:execute
83 +@rem Setup the command line
84 +
85 +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
86 +
87 +
88 +@rem Execute Gradle
89 +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
90 +
91 +:end
92 +@rem End local scope for the variables with windows NT shell
93 +if "%ERRORLEVEL%"=="0" goto mainEnd
94 +
95 +:fail
96 +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
97 +rem the _cmd.exe /c_ return code!
98 +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
99 +exit /b 1
100 +
101 +:mainEnd
102 +if "%OS%"=="Windows_NT" endlocal
103 +
104 +:omega
No preview for this file type
1 +apply plugin: 'com.android.library'
2 +
3 +android {
4 +
5 + compileSdkVersion 31
6 + buildToolsVersion "31.0.0"
7 +
8 + defaultConfig {
9 + minSdkVersion 23
10 + targetSdkVersion 31
11 + consumerProguardFiles 'proguard-rules.pro'
12 + }
13 + lintOptions {
14 + abortOnError false
15 + }
16 +
17 + buildTypes {
18 + release {
19 + minifyEnabled false
20 + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 + }
22 + }
23 +
24 + useLibrary 'org.apache.http.legacy'
25 +}
26 +
27 +dependencies {
28 + //------------------------------ Support -----------------------------//
29 + api 'androidx.appcompat:appcompat:1.4.1'
30 + api 'androidx.recyclerview:recyclerview:1.2.1'
31 + api 'androidx.cardview:cardview:1.0.0'
32 +
33 + api 'org.altbeacon:android-beacon-library:2.19.3'
34 + api 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
35 + api "commons-logging:commons-logging:1.2"
36 +
37 + //------------------------------ Firebase -----------------------------//
38 + api platform('com.google.firebase:firebase-bom:29.0.3')
39 + api 'com.google.firebase:firebase-messaging'
40 +
41 + //------------------------------ GMS -----------------------------//
42 + api 'com.google.android.gms:play-services-base:18.0.1'
43 +
44 + //------------------------------ Work Manager -----------------------------//
45 + api 'androidx.work:work-runtime:2.7.1'
46 +
47 + //------------------------------ Glide -----------------------------//
48 + api 'com.github.bumptech.glide:glide:4.12.0'
49 + annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
50 +
51 + //------------------------------ Huawei -----------------------------//
52 + api 'com.huawei.agconnect:agconnect-core:1.6.2.300'
53 + api 'com.huawei.hms:base:6.2.0.300'
54 + api 'com.huawei.hms:push:6.1.0.300'
55 + api 'com.huawei.hms:ads-identifier:3.4.39.302'
56 +
57 + //------------------------------ SQLCipher -----------------------------//
58 + api "net.zetetic:android-database-sqlcipher:4.5.0"
59 + api "androidx.sqlite:sqlite:2.2.0"
60 +}
61 +
62 +// In every export please update the version number
63 +task deleteJarLibrary(type: Delete) {
64 + delete 'jar/warply_android_sdk_v4.5.0.jar'
65 +}
66 +
67 +//from('build/intermediates/compile_library_classes/release/')
68 +
69 +//Old version
70 +// Gradle Tasks -> warply_android_sdk -> Tasks -> other -> createJarLibrary
71 +//task createJarLibrary(type: Copy) {
72 +// from fileTree('build/intermediates/bundles/release/')
73 +// into('jar/')
74 +// include('classes.jar')
75 +// rename('classes.jar', 'warply_android_sdk_v4.4.2.jar')
76 +//}
77 +
78 +// New version
79 +// Gradle -> warplyDemo -> libraries -> warply_android_sdk -> Run Configurations -> assembleRelease
80 +// When finished it copies the .jar into
81 +// warply_android_sdk -> build -> intermediates -> full_jar -> release/debug -> full.jar
82 +
83 +// 24 - Jan - 2022
84 +// Gradle -> warplyDemo -> libraries -> warply_android_sdk -> Tasks -> build -> build
85 +// When finished it copies the .aar into
86 +// warply_android_sdk -> build -> outputs -> aar -> warply_android_sdk-release.aar
87 +
88 +task createJarLibrary(type: Jar, dependsOn: 'assembleRelease') {
89 + from fileTree('build/intermediates/bundles/release/')
90 +}
91 +
92 +createJarLibrary.dependsOn(deleteJarLibrary, build)
1 +# Add project specific ProGuard rules here.
2 +# By default, the flags in this file are appended to flags specified
3 +# in C:\Users\philimon\AppData\Local\Android\sdk1/tools/proguard/proguard-android.txt
4 +# You can edit the include path and order by changing the proguardFiles
5 +# directive in build.gradle.
6 +#
7 +# For more details, see
8 +# http://developer.android.com/guide/developing/tools/proguard.html
9 +
10 +# Add any project specific keep options here:
11 +
12 +# If your project uses WebView with JS, uncomment the following
13 +# and specify the fully qualified class name to the JavaScript interface
14 +# class:
15 +#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 +# public *;
17 +#}
18 +#-keep,includedescriptorclasses class com.google.android.gms.** { *; }
19 +#-keep,includedescriptorclasses class com.google.android.gms.internal.** { *; }
20 +#-keep class com.google.android.gms.internal.** {com.google.android.gms.internal.** initialize(android.content.Context);}
21 +-ignorewarnings
22 +-keepattributes *Annotation*
23 +-keepattributes Exceptions
24 +-keepattributes InnerClasses
25 +-keepattributes Signature
26 +-keepattributes SourceFile,LineNumberTable
27 +-keep class com.huawei.hianalytics.**{*;}
28 +-keep class com.huawei.updatesdk.**{*;}
29 +-keep class com.huawei.hms.**{*;}
30 +-keep,includedescriptorclasses class net.sqlcipher.** { *; }
31 +-keep,includedescriptorclasses interface net.sqlcipher.** { *; }
...\ No newline at end of file ...\ No newline at end of file
1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2 + package="ly.warp.sdk">
3 +
4 + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
5 + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
6 + <uses-permission android:name="android.permission.READ_PHONE_STATE" />
7 + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
8 + <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
9 + <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
10 + <uses-permission android:name="android.permission.BLUETOOTH" />
11 + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
12 + <uses-permission android:name="com.google.android.c2dm.permission.SEND" />
13 +
14 + <application>
15 + <!-- For Huawei Push -->
16 + <meta-data
17 + android:name="push_kit_auto_init_enabled"
18 + android:value="true" />
19 +
20 + <meta-data
21 + android:name="com.huawei.hms.client.channel.androidMarket"
22 + android:value="false" />
23 +
24 + <activity
25 + android:name="ly.warp.sdk.activities.WarpViewActivity"
26 + android:exported="false"
27 + android:screenOrientation="portrait" />
28 +
29 + <activity
30 + android:name="ly.warp.sdk.dexter.PermissionsActivity"
31 + android:exported="false"
32 + android:launchMode="singleInstance"
33 + android:screenOrientation="portrait"
34 + android:theme="@android:style/Theme.Light.NoTitleBar" />
35 +
36 + <!-- Service used for updating user's location. -->
37 + <service
38 + android:name="ly.warp.sdk.services.UpdateUserLocationService"
39 + android:exported="false"
40 + android:permission="android.permission.BIND_JOB_SERVICE" />
41 +
42 + <service
43 + android:name="ly.warp.sdk.services.WarplyBeaconsRangingService"
44 + android:exported="false" />
45 +
46 + <!-- Service used for in app notification. -->
47 + <service
48 + android:name="ly.warp.sdk.services.WarpInAppNotificationService"
49 + android:exported="false" />
50 +
51 + <!-- FCM Service for push notifications -->
52 + <service
53 + android:name="ly.warp.sdk.services.FCMBaseMessagingService"
54 + android:exported="false">
55 + <intent-filter>
56 + <action android:name="com.google.firebase.MESSAGING_EVENT" />
57 + </intent-filter>
58 + </service>
59 +
60 + <!-- Service used for handling Huawei Push Notifications, comment if we are in Google build -->
61 + <service
62 + android:name="ly.warp.sdk.services.HMSBaseMessagingService"
63 + android:exported="false">
64 + <intent-filter>
65 + <action android:name="com.huawei.push.action.MESSAGING_EVENT" />
66 + </intent-filter>
67 + </service>
68 +
69 + <receiver
70 + android:name="ly.warp.sdk.receivers.LocationChangedReceiver"
71 + android:exported="false" />
72 +
73 + <receiver
74 + android:name="ly.warp.sdk.receivers.ConnectivityChangedReceiver"
75 + android:exported="false">
76 + <intent-filter>
77 + <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
78 + <category android:name="${applicationId}" />
79 + </intent-filter>
80 + </receiver>
81 +
82 + <receiver
83 + android:name="ly.warp.sdk.receivers.BluetoothStateChangeReceiver"
84 + android:exported="false">
85 + <intent-filter>
86 + <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
87 + </intent-filter>
88 + </receiver>
89 +
90 + <receiver
91 + android:name="ly.warp.sdk.receivers.WarplyInAppNotificationReceiver"
92 + android:exported="false" />
93 + </application>
94 +</manifest>
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright (C) 2012 Apptentive, Inc.
3 + *
4 + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
5 + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
6 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
7 + * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8 + *
9 + * The above copyright notice and this permission notice shall be included in all copies or substantial portions
10 + * of the Software.
11 + *
12 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13 + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
14 + * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
15 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 + */
17 +
18 +package ly.warp.sdk.activities;
19 +
20 +import java.util.List;
21 +
22 +import android.app.Activity;
23 +import android.app.ActivityManager;
24 +import android.content.ComponentName;
25 +import android.content.Context;
26 +import android.content.SharedPreferences;
27 +import android.content.pm.ActivityInfo;
28 +import android.content.pm.PackageInfo;
29 +import android.content.pm.PackageManager;
30 +import android.os.Bundle;
31 +import android.util.Log;
32 +
33 +public abstract class ApplicationSessionActivity extends Activity {
34 +
35 + private static final String TAG = "AppSessionActivity";
36 + private static final String KEY_APP_IN_BACKGROUND = "AppInBackground";
37 + private static final String KEY_APP_SESSION_ACTIVE = "AppSessionActive";
38 + private static final String KEY_MAIN_ACTIVITY_NAME = "MainActivityName";
39 +
40 + private SharedPreferences prefs;
41 +
42 + private static SessionStartedListener sessionStartedListener;
43 + private static SessionStoppedListener sessionStoppedListener;
44 +
45 +
46 + /**
47 + * Used to listen for Session starts.
48 + */
49 + public interface SessionStartedListener {
50 + public void onSessionStarted();
51 + }
52 +
53 + /**
54 + * Used to listen for Session stops.
55 + */
56 + public interface SessionStoppedListener {
57 + public void onSessionStopped();
58 + }
59 +
60 + /**
61 + * Sets the SessionStartedListener for this Activity.
62 + */
63 + protected static void setOnSessionStartedListener(SessionStartedListener sessionStartedListener) {
64 + ApplicationSessionActivity.sessionStartedListener = sessionStartedListener;
65 + }
66 +
67 + /**
68 + * Sets the SessionStoppedListener for this Activity.
69 + */
70 + protected static void setOnSessionStoppedListener(SessionStoppedListener sessionStoppedListener) {
71 + ApplicationSessionActivity.sessionStoppedListener = sessionStoppedListener;
72 + }
73 +
74 + @Override
75 + public void onCreate(Bundle savedInstanceState) {
76 + super.onCreate(savedInstanceState);
77 +
78 + prefs = getSharedPreferences(TAG, MODE_PRIVATE);
79 +
80 + // Pretend we came from background so a new session will start.
81 + if(isCurrentActivityMainActivity(this)) {
82 + prefs.edit().putBoolean(KEY_APP_IN_BACKGROUND, true).commit();
83 + }
84 + }
85 +
86 + @Override
87 + protected void onStart() {
88 + super.onStart();
89 + startSession();
90 + }
91 +
92 + @Override
93 + protected void onStop() {
94 + super.onStop();
95 + // Stopping because the Application was backgrounded because the HOME key was pressed, or another application was
96 + // switched to.
97 + if(isApplicationBroughtToBackground(this)) {
98 + prefs.edit().putBoolean(KEY_APP_IN_BACKGROUND, true).commit();
99 + endSession();
100 + }
101 + }
102 +
103 + @Override
104 + protected void onDestroy() {
105 + super.onDestroy();
106 + // Stopping because the BACK key was pressed from just the home Activity.
107 + if(isCurrentActivityMainActivity(this)) {
108 + endSession();
109 + sessionStartedListener = null;
110 + sessionStoppedListener = null;
111 + }
112 + }
113 +
114 + private void startSession() {
115 + boolean comingFromBackground = prefs.getBoolean(KEY_APP_IN_BACKGROUND, true);
116 +
117 + if(comingFromBackground) {
118 + boolean activeSession = prefs.getBoolean(KEY_APP_SESSION_ACTIVE, false);
119 + if(!activeSession) {
120 + if(sessionStartedListener != null) {
121 + sessionStartedListener.onSessionStarted();
122 + }
123 + } else {
124 + Log.e(TAG, "Error: Starting session, but a session is already active.");
125 + }
126 + prefs.edit().putBoolean(KEY_APP_SESSION_ACTIVE, true).putBoolean(KEY_APP_IN_BACKGROUND, false).commit();
127 + }
128 + }
129 +
130 + private void endSession() {
131 + boolean activeSession = prefs.getBoolean(KEY_APP_SESSION_ACTIVE, false);
132 + if(activeSession) {
133 + if(sessionStoppedListener != null) {
134 + sessionStoppedListener.onSessionStopped();
135 + }
136 + } else {
137 + Log.e(TAG, "Error: Ending session, but no session is active.");
138 + }
139 + prefs.edit().putBoolean(KEY_APP_SESSION_ACTIVE, false).commit();
140 + }
141 +
142 +
143 + /**
144 + * Call this in the onStop() method of an Activity. Tells you if the Activity is stopping
145 + * because the Application is going to the background, or because of some other reason. Other reasons include the app
146 + * exiting, or a new Activity in the same Application starting.
147 + * @param activity The Activity from which this method is called.
148 + * @return <p>true - if the Application is stopping to go to the background.</p>
149 + * <p>false - for any other reason the app is stopping.</p>
150 + */
151 + private static boolean isApplicationBroughtToBackground(final Activity activity) {
152 + ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
153 + List<ActivityManager.RunningTaskInfo> tasks;
154 + try {
155 + tasks = activityManager.getRunningTasks(1);
156 + } catch (SecurityException e) {
157 + Log.e(TAG, "Missing required permission: \"android.permission.GET_TASKS\".", e);
158 + return false;
159 + }
160 + if (tasks != null && !tasks.isEmpty()) {
161 + ComponentName topActivity = tasks.get(0).topActivity;
162 + try {
163 + PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
164 + for (ActivityInfo activityInfo : pi.activities) {
165 + if(topActivity.getClassName().equals(activityInfo.name)) {
166 + return false;
167 + }
168 + }
169 + } catch( PackageManager.NameNotFoundException e) {
170 + Log.e(TAG, "Package name not found: " + activity.getPackageName());
171 + return false; // Never happens.
172 + }
173 + }
174 + return true;
175 + }
176 +
177 + /**
178 + * Tells you whether the currentActivity is the main Activity of the app. In order for this to work, it must be called
179 + * from the main Activity first. One way to enforce this rule is to call it in the main Activity's onCreate().
180 + * @param currentActivity The Activity from which this method is called.
181 + * @return true iff currentActivity is the Application's main Activity.
182 + */
183 + private boolean isCurrentActivityMainActivity(Activity currentActivity) {
184 + String currentActivityName = currentActivity.getComponentName().getClassName();
185 + String mainActivityName = prefs.getString(KEY_MAIN_ACTIVITY_NAME, null);
186 + // The first time this runs, it will be from the main Activity, guaranteed.
187 + if(mainActivityName == null) {
188 + mainActivityName = currentActivityName;
189 + prefs.edit().putString(KEY_MAIN_ACTIVITY_NAME, mainActivityName).commit();
190 + }
191 + return currentActivityName != null && currentActivityName.equals(mainActivityName);
192 + }
193 +}
1 +/*
2 + * Copyright (C) 2012 Apptentive, Inc.
3 + *
4 + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
5 + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
6 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
7 + * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8 + *
9 + * The above copyright notice and this permission notice shall be included in all copies or substantial portions
10 + * of the Software.
11 + *
12 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13 + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
14 + * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
15 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 + */
17 +
18 +package ly.warp.sdk.activities;
19 +
20 +import java.util.List;
21 +
22 +import android.app.Activity;
23 +import android.app.ActivityManager;
24 +import android.app.ListActivity;
25 +import android.content.ComponentName;
26 +import android.content.Context;
27 +import android.content.SharedPreferences;
28 +import android.content.pm.ActivityInfo;
29 +import android.content.pm.PackageInfo;
30 +import android.content.pm.PackageManager;
31 +import android.os.Bundle;
32 +import android.util.Log;
33 +
34 +public abstract class ApplicationSessionListActivity extends ListActivity {
35 +
36 + private static final String TAG = "AppSessionActivity";
37 + private static final String KEY_APP_IN_BACKGROUND = "AppInBackground";
38 + private static final String KEY_APP_SESSION_ACTIVE = "AppSessionActive";
39 + private static final String KEY_MAIN_ACTIVITY_NAME = "MainActivityName";
40 +
41 + private SharedPreferences prefs;
42 +
43 + private static SessionStartedListener sessionStartedListener;
44 + private static SessionStoppedListener sessionStoppedListener;
45 +
46 +
47 + /**
48 + * Used to listen for Session starts.
49 + */
50 + public interface SessionStartedListener {
51 + public void onSessionStarted();
52 + }
53 +
54 + /**
55 + * Used to listen for Session stops.
56 + */
57 + public interface SessionStoppedListener {
58 + public void onSessionStopped();
59 + }
60 +
61 + /**
62 + * Sets the SessionStartedListener for this Activity.
63 + */
64 + protected static void setOnSessionStartedListener(SessionStartedListener sessionStartedListener) {
65 + ApplicationSessionListActivity.sessionStartedListener = sessionStartedListener;
66 + }
67 +
68 + /**
69 + * Sets the SessionStoppedListener for this Activity.
70 + */
71 + protected static void setOnSessionStoppedListener(SessionStoppedListener sessionStoppedListener) {
72 + ApplicationSessionListActivity.sessionStoppedListener = sessionStoppedListener;
73 + }
74 +
75 + @Override
76 + public void onCreate(Bundle savedInstanceState) {
77 + super.onCreate(savedInstanceState);
78 +
79 + prefs = getSharedPreferences(TAG, MODE_PRIVATE);
80 +
81 + // Pretend we came from background so a new session will start.
82 + if(isCurrentActivityMainActivity(this)) {
83 + prefs.edit().putBoolean(KEY_APP_IN_BACKGROUND, true).commit();
84 + }
85 + }
86 +
87 + @Override
88 + protected void onStart() {
89 + super.onStart();
90 + startSession();
91 + }
92 +
93 + @Override
94 + protected void onStop() {
95 + super.onStop();
96 + // Stopping because the Application was backgrounded because the HOME key was pressed, or another application was
97 + // switched to.
98 + if(isApplicationBroughtToBackground(this)) {
99 + prefs.edit().putBoolean(KEY_APP_IN_BACKGROUND, true).commit();
100 + endSession();
101 + }
102 + }
103 +
104 + @Override
105 + protected void onDestroy() {
106 + super.onDestroy();
107 + // Stopping because the BACK key was pressed from just the home Activity.
108 + if(isCurrentActivityMainActivity(this)) {
109 + endSession();
110 + sessionStartedListener = null;
111 + sessionStoppedListener = null;
112 + }
113 + }
114 +
115 + private void startSession() {
116 + boolean comingFromBackground = prefs.getBoolean(KEY_APP_IN_BACKGROUND, true);
117 +
118 + if(comingFromBackground) {
119 + boolean activeSession = prefs.getBoolean(KEY_APP_SESSION_ACTIVE, false);
120 + if(!activeSession) {
121 + if(sessionStartedListener != null) {
122 + sessionStartedListener.onSessionStarted();
123 + }
124 + } else {
125 + Log.e(TAG, "Error: Starting session, but a session is already active.");
126 + }
127 + prefs.edit().putBoolean(KEY_APP_SESSION_ACTIVE, true).putBoolean(KEY_APP_IN_BACKGROUND, false).commit();
128 + }
129 + }
130 +
131 + private void endSession() {
132 + boolean activeSession = prefs.getBoolean(KEY_APP_SESSION_ACTIVE, false);
133 + if(activeSession) {
134 + if(sessionStoppedListener != null) {
135 + sessionStoppedListener.onSessionStopped();
136 + }
137 + } else {
138 + Log.e(TAG, "Error: Ending session, but no session is active.");
139 + }
140 + prefs.edit().putBoolean(KEY_APP_SESSION_ACTIVE, false).commit();
141 + }
142 +
143 +
144 + /**
145 + * Call this in the onStop() method of an Activity. Tells you if the Activity is stopping
146 + * because the Application is going to the background, or because of some other reason. Other reasons include the app
147 + * exiting, or a new Activity in the same Application starting.
148 + * @param activity The Activity from which this method is called.
149 + * @return <p>true - if the Application is stopping to go to the background.</p>
150 + * <p>false - for any other reason the app is stopping.</p>
151 + */
152 + private static boolean isApplicationBroughtToBackground(final Activity activity) {
153 + ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
154 + List<ActivityManager.RunningTaskInfo> tasks = null;
155 + try {
156 + tasks = activityManager.getRunningTasks(1);
157 + } catch (SecurityException e) {
158 + Log.e(TAG, "Missing required permission: \"android.permission.GET_TASKS\".", e);
159 + return false;
160 + }
161 + if (tasks != null && !tasks.isEmpty()) {
162 + ComponentName topActivity = tasks.get(0).topActivity;
163 + try {
164 + PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
165 + for (ActivityInfo activityInfo : pi.activities) {
166 + if(topActivity.getClassName().equals(activityInfo.name)) {
167 + return false;
168 + }
169 + }
170 + } catch( PackageManager.NameNotFoundException e) {
171 + Log.e(TAG, "Package name not found: " + activity.getPackageName());
172 + return false; // Never happens.
173 + }
174 + }
175 + return true;
176 + }
177 +
178 + /**
179 + * Tells you whether the currentActivity is the main Activity of the app. In order for this to work, it must be called
180 + * from the main Activity first. One way to enforce this rule is to call it in the main Activity's onCreate().
181 + * @param currentActivity The Activity from which this method is called.
182 + * @return true iff currentActivity is the Application's main Activity.
183 + */
184 + private boolean isCurrentActivityMainActivity(Activity currentActivity) {
185 + String currentActivityName = currentActivity.getComponentName().getClassName();
186 + String mainActivityName = prefs.getString(KEY_MAIN_ACTIVITY_NAME, null);
187 + // The first time this runs, it will be from the main Activity, guaranteed.
188 + if(mainActivityName == null) {
189 + mainActivityName = currentActivityName;
190 + prefs.edit().putString(KEY_MAIN_ACTIVITY_NAME, mainActivityName).commit();
191 + }
192 + return currentActivityName != null && currentActivityName.equals(mainActivityName);
193 + }
194 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.activities;
27 +
28 +import android.app.Activity;
29 +
30 +import ly.warp.sdk.utils.managers.WarplyAnalyticsManager;
31 +
32 +public class WarpBaseActivity extends Activity {
33 +
34 + @Override
35 + protected void onPause() {
36 + super.onPause();
37 + WarplyAnalyticsManager.logEvent(getClass().getSimpleName(), "paused", null);
38 + }
39 +
40 + @Override
41 + protected void onResume() {
42 + super.onResume();
43 + WarplyAnalyticsManager.logEvent(getClass().getSimpleName(), "resumed", null);
44 + }
45 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.activities;
27 +
28 +import android.content.Context;
29 +import android.content.Intent;
30 +import android.graphics.Color;
31 +import android.os.Build;
32 +import android.os.Bundle;
33 +import androidx.annotation.NonNull;
34 +import android.text.TextUtils;
35 +import android.view.KeyEvent;
36 +import android.view.View;
37 +import android.webkit.WebView;
38 +import android.widget.ImageView;
39 +import android.widget.ProgressBar;
40 +import android.widget.RelativeLayout;
41 +
42 +import java.util.Random;
43 +import java.util.concurrent.ThreadLocalRandom;
44 +import java.util.concurrent.TimeUnit;
45 +
46 +import androidx.work.Constraints;
47 +import androidx.work.NetworkType;
48 +import androidx.work.OneTimeWorkRequest;
49 +import androidx.work.WorkManager;
50 +import ly.warp.sdk.Warply;
51 +import ly.warp.sdk.services.PushEventsClickedWorkerService;
52 +import ly.warp.sdk.utils.WarpJSONParser;
53 +import ly.warp.sdk.utils.WarpUtils;
54 +import ly.warp.sdk.utils.WarplyPreferences;
55 +import ly.warp.sdk.utils.WarplyProperty;
56 +import ly.warp.sdk.utils.managers.WarplyAnalyticsManager;
57 +import ly.warp.sdk.utils.managers.WarplySessionManager;
58 +import ly.warp.sdk.views.WarpView;
59 +
60 +import static ly.warp.sdk.utils.constants.WarpConstants.RANDOM_MAX;
61 +import static ly.warp.sdk.utils.constants.WarpConstants.RANDOM_MIN;
62 +
63 +public class WarpViewActivity extends WarpBaseActivity {
64 +
65 + // ===========================================================
66 + // Fields
67 + // ===========================================================
68 +
69 + private WarpView mWarpView;
70 +
71 + // ===========================================================
72 + // Methods for/from SuperClass/Interfaces
73 + // ===========================================================
74 +
75 + @Override
76 + public void onCreate(Bundle savedInstanceState) {
77 + super.onCreate(savedInstanceState);
78 + initViews();
79 + Warply.getInitializer(this).init();
80 + setPageAccordingToIntent();
81 + }
82 +
83 + @Override
84 + protected void onNewIntent(Intent intent) {
85 + super.onNewIntent(intent);
86 + setIntent(intent);
87 + setPageAccordingToIntent();
88 + }
89 +
90 + @Override
91 + protected void onStart() {
92 + super.onStart();
93 + WarplySessionManager.onStartActivity(this);
94 + }
95 +
96 + @Override
97 + protected void onStop() {
98 + super.onStop();
99 + WarplySessionManager.onStopActivity(this);
100 + }
101 +
102 + @Override
103 + public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
104 + if (keyCode == KeyEvent.KEYCODE_BACK) {
105 + if (mWarpView.canGoBack()) {
106 + mWarpView.goBack();
107 + return true;
108 + }
109 + }
110 +
111 + return super.onKeyDown(keyCode, event);
112 + }
113 +
114 + // ===========================================================
115 + // Methods
116 + // ===========================================================
117 +
118 + private void initViews() {
119 +
120 + RelativeLayout root = new RelativeLayout(this);
121 + root.setBackgroundColor(Color.WHITE);
122 +
123 + final ImageView ivLogo = new ImageView(this);
124 + RelativeLayout.LayoutParams ivLogoParams = new RelativeLayout.LayoutParams(
125 + RelativeLayout.LayoutParams.WRAP_CONTENT,
126 + RelativeLayout.LayoutParams.WRAP_CONTENT);
127 + ivLogoParams.addRule(RelativeLayout.CENTER_IN_PARENT);
128 + root.addView(ivLogo, ivLogoParams);
129 +
130 + ivLogo.setImageDrawable(WarplyProperty.getProgressDrawable(this));
131 + ivLogo.startAnimation(WarpUtils.getPulseAnimation());
132 +
133 + mWarpView = new WarpView(this);
134 + RelativeLayout.LayoutParams warpViewParams = new RelativeLayout.LayoutParams(
135 + RelativeLayout.LayoutParams.MATCH_PARENT,
136 + RelativeLayout.LayoutParams.MATCH_PARENT);
137 + root.addView(mWarpView, warpViewParams);
138 +
139 +
140 + int progressHeightDp = 7;
141 + final ProgressBar progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal);
142 + progressBar.setProgressDrawable(WarpUtils.getHorizontalProgressDrawable(WarplyProperty.getProgressColor(this)));
143 + RelativeLayout.LayoutParams progressBarParams = new RelativeLayout.LayoutParams(
144 + RelativeLayout.LayoutParams.MATCH_PARENT, (int)
145 + (progressHeightDp * getResources().getDisplayMetrics().density + 0.5f));
146 + mWarpView.setProgressChangeListener(new WarpView.ProgressChangeListener() {
147 + @Override
148 + public void onProgressChanged(WebView view, int newProgress) {
149 +
150 + progressBar.setProgress(newProgress);
151 + if (progressBar.getProgress() == 100) {
152 + WarpUtils.animateVisibility(ivLogo, View.INVISIBLE);
153 + WarpUtils.animateVisibility(progressBar, View.INVISIBLE);
154 + } else {
155 + WarpUtils.animateVisibility(ivLogo, View.VISIBLE);
156 + WarpUtils.animateVisibility(progressBar, View.VISIBLE);
157 + }
158 + }
159 + });
160 + root.addView(progressBar, progressBarParams);
161 + setContentView(root);
162 + }
163 +
164 + private void setPageAccordingToIntent() {
165 +
166 + Intent intent = getIntent();
167 + String sessionUUID = intent.getStringExtra("sessionUUID");
168 +
169 + // user viewed campaign through notification
170 + if (intent.hasExtra("source") && intent.getStringExtra("source").
171 + equalsIgnoreCase("from_notification_status")) {
172 + setUpPushEvents(sessionUUID);
173 + }
174 +
175 + // ensure update campaigns and count if was used cache
176 + if (Warply.INSTANCE.getLastReceivedCampaigns() != null &&
177 + Warply.INSTANCE.getLastReceivedCampaigns().containsUuid(sessionUUID)) {
178 + new WarplyPreferences(this).clearInboxLastCachedTimeStamps();
179 + }
180 +
181 + if (!TextUtils.isEmpty(sessionUUID)) {
182 + mWarpView.loadWarpSessionUUID(sessionUUID);
183 + } else {
184 + mWarpView.loadWarpUrl(getIntent().getStringExtra("sessionUrl"));
185 + }
186 + }
187 +
188 + private void setUpPushEvents(String sessionUUID) {
189 + WarplyAnalyticsManager.logUserEngagedPush(WarpJSONParser.createJSONObjectFromString("session_uuid", sessionUUID));
190 +
191 +// if (WorkManager.getInstance().getWorkInfosByTag(PushEventsWorkerService.TAG).isDone() || WorkManager.getInstance().getWorkInfosByTag(PushEventsWorkerService.TAG).isCancelled()) {
192 + Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
193 + OneTimeWorkRequest sendEvent = new OneTimeWorkRequest.Builder(PushEventsClickedWorkerService.class)
194 + .setConstraints(constraints)
195 + .setInitialDelay(defineRandomStart(), TimeUnit.MINUTES)
196 + .build();
197 +
198 + WorkManager.getInstance().enqueue(sendEvent);
199 +// }
200 + }
201 +
202 + private int defineRandomStart() {
203 + if (Build.VERSION.SDK_INT >= 21) {
204 + return ThreadLocalRandom.current().nextInt(RANDOM_MIN, RANDOM_MAX + 1);
205 + } else {
206 + Random rand = new Random();
207 + return rand.nextInt((RANDOM_MAX - RANDOM_MIN) + 1) + RANDOM_MIN;
208 + }
209 + }
210 +
211 + public static Intent createIntentFromSessionUUID(Context context, String sessionUUID, String source) {
212 +
213 + Intent intent = new Intent(context, WarpViewActivity.class);
214 + intent.putExtra("sessionUUID", sessionUUID);
215 + if (!TextUtils.isEmpty(source)) {
216 + intent.putExtra("source", source);
217 + }
218 + return intent;
219 + }
220 +
221 + public static Intent createIntentFromSessionUUID(Context context, String sessionUUID) {
222 + return createIntentFromSessionUUID(context, sessionUUID, null);
223 + }
224 +
225 + public static Intent createIntentFromURL(Context context, String url) {
226 + return new Intent(context, WarpViewActivity.class).putExtra("sessionUrl", url);
227 + }
228 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.activities;
27 +
28 +import android.os.Bundle;
29 +import android.util.Log;
30 +
31 +import ly.warp.sdk.Warply;
32 +
33 +public class WarplyActivity extends ApplicationSessionActivity {
34 +
35 + @Override
36 + public void onCreate(Bundle savedInstanceState) {
37 +
38 + // Pass a listener in so we can be notified of session starts.
39 + setOnSessionStartedListener(new SessionStartedListener() {
40 + public void onSessionStarted() {
41 + Log.e("SessionExample", "Starting session.");
42 + Warply.onApplicationEnterForeground();
43 +
44 + }
45 + });
46 +
47 + // Pass a listener in so we can be notified of session stops.
48 + setOnSessionStoppedListener(new SessionStoppedListener() {
49 + public void onSessionStopped() {
50 + Log.e("SessionExample", "Stopping session.");
51 + Warply.onApplicationEnterBackground();
52 + }
53 + });
54 +
55 + super.onCreate(savedInstanceState);
56 + }
57 +
58 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.activities;
27 +
28 +import android.os.Bundle;
29 +import android.util.Log;
30 +
31 +import ly.warp.sdk.Warply;
32 +
33 +public class WarplyListActivity extends ApplicationSessionListActivity {
34 +
35 + @Override
36 + public void onCreate(Bundle savedInstanceState) {
37 +
38 + // Pass a listener in so we can be notified of session starts.
39 + setOnSessionStartedListener(new SessionStartedListener() {
40 + public void onSessionStarted() {
41 +
42 + Log.e("SessionExample ", "Starting session.");
43 +
44 + Warply.onApplicationEnterForeground();
45 +
46 + }
47 + });
48 +
49 + // Pass a listener in so we can be notified of session stops.
50 + setOnSessionStoppedListener(new SessionStoppedListener() {
51 + public void onSessionStopped() {
52 + Log.e("SessionExample ", "Stopping session.");
53 +
54 + Warply.onApplicationEnterBackground();
55 +
56 + }
57 + });
58 +
59 + super.onCreate(savedInstanceState);
60 + }
61 +
62 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +import android.app.Activity;
20 +import android.content.Context;
21 +import androidx.annotation.NonNull;
22 +import androidx.annotation.Nullable;
23 +import androidx.core.app.ActivityCompat;
24 +import androidx.core.content.ContextCompat;
25 +
26 +/**
27 + * Wrapper class for all the static calls to the Android permission system
28 + */
29 +class AndroidPermissionService {
30 +
31 + /**
32 + * @see ContextCompat#checkSelfPermission
33 + */
34 + int checkSelfPermission(@NonNull Context context, @NonNull String permission) {
35 + return ContextCompat.checkSelfPermission(context, permission);
36 + }
37 +
38 + /**
39 + * @see ActivityCompat#requestPermissions
40 + */
41 + void requestPermissions(@Nullable Activity activity, @NonNull String[] permissions,
42 + int requestCode) {
43 + if (activity == null) {
44 + return;
45 + }
46 +
47 + ActivityCompat.requestPermissions(activity, permissions, requestCode);
48 + }
49 +
50 + /**
51 + * @see ActivityCompat#shouldShowRequestPermissionRationale
52 + */
53 + boolean shouldShowRequestPermissionRationale(@Nullable Activity activity,
54 + @NonNull String permission) {
55 + if (activity == null) {
56 + return false;
57 + }
58 +
59 + return ActivityCompat.shouldShowRequestPermissionRationale(activity, permission);
60 + }
61 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +import android.app.Activity;
20 +import android.content.Context;
21 +
22 +import java.util.ArrayList;
23 +import java.util.Arrays;
24 +import java.util.Collection;
25 +import java.util.Collections;
26 +
27 +import ly.warp.sdk.dexter.listener.EmptyPermissionRequestErrorListener;
28 +import ly.warp.sdk.dexter.listener.PermissionRequestErrorListener;
29 +import ly.warp.sdk.dexter.listener.multi.BaseMultiplePermissionsListener;
30 +import ly.warp.sdk.dexter.listener.multi.MultiplePermissionsListener;
31 +import ly.warp.sdk.dexter.listener.single.PermissionListener;
32 +
33 +/**
34 + * Class to simplify the management of Android runtime permissions
35 + * You can use this class directly using the provided fluent API like:
36 + * <p>
37 + * Dexter.withContext(activity)
38 + * .withPermission(permission)
39 + * .withListener(listener)
40 + * .onSameThread()
41 + * .check()
42 + */
43 +public final class Dexter
44 + implements DexterBuilder, DexterBuilder.Permission, DexterBuilder.SinglePermissionListener,
45 + DexterBuilder.MultiPermissionListener {
46 +
47 + private static DexterInstance instance;
48 +
49 + private Collection<String> permissions;
50 + private MultiplePermissionsListener listener = new BaseMultiplePermissionsListener();
51 + private PermissionRequestErrorListener errorListener = new EmptyPermissionRequestErrorListener();
52 + private boolean shouldExecuteOnSameThread = false;
53 +
54 + private Dexter(Context activity) {
55 + initialize(activity);
56 + }
57 +
58 + public static DexterBuilder.Permission withContext(Context activity) {
59 + return new Dexter(activity);
60 + }
61 +
62 + @Override
63 + public DexterBuilder.SinglePermissionListener withPermission(String permission) {
64 + permissions = Collections.singletonList(permission);
65 + return this;
66 + }
67 +
68 + @Override
69 + public DexterBuilder.MultiPermissionListener withPermissions(String... permissions) {
70 + this.permissions = Arrays.asList(permissions);
71 + return this;
72 + }
73 +
74 + @Override
75 + public DexterBuilder.MultiPermissionListener withPermissions(Collection<String> permissions) {
76 + this.permissions = new ArrayList<>(permissions);
77 + return this;
78 + }
79 +
80 + @Override
81 + public DexterBuilder withListener(PermissionListener listener) {
82 + this.listener = new MultiplePermissionsListenerToPermissionListenerAdapter(listener);
83 + return this;
84 + }
85 +
86 + @Override
87 + public DexterBuilder withListener(MultiplePermissionsListener listener) {
88 + this.listener = listener;
89 + return this;
90 + }
91 +
92 + @Override
93 + public DexterBuilder onSameThread() {
94 + shouldExecuteOnSameThread = true;
95 + return this;
96 + }
97 +
98 + @Override
99 + public DexterBuilder withErrorListener(PermissionRequestErrorListener errorListener) {
100 + this.errorListener = errorListener;
101 + return this;
102 + }
103 +
104 + @Override
105 + public void check() {
106 + try {
107 + Thread thread = getThread();
108 + instance.checkPermissions(listener, permissions, thread);
109 + } catch (DexterException e) {
110 + errorListener.onError(e.error);
111 + }
112 + }
113 +
114 + private Thread getThread() {
115 + Thread thread;
116 +
117 + if (shouldExecuteOnSameThread) {
118 + thread = ThreadFactory.makeSameThread();
119 + } else {
120 + thread = ThreadFactory.makeMainThread();
121 + }
122 +
123 + return thread;
124 + }
125 +
126 + private static void initialize(Context context) {
127 + if (instance == null) {
128 + AndroidPermissionService androidPermissionService = new AndroidPermissionService();
129 + IntentProvider intentProvider = new IntentProvider();
130 + instance = new DexterInstance(context, androidPermissionService, intentProvider);
131 + } else {
132 + instance.setContext(context);
133 + }
134 + }
135 +
136 + /**
137 + * Method called whenever the PermissionsActivity has been created or recreated and is ready to be
138 + * used.
139 + */
140 + static void onActivityReady(Activity activity) {
141 + /* Check against null values because sometimes the PermissionsActivity can call these internal
142 + methods when the DexterInstance has been cleaned up.
143 + Refer to this commit message for a more detailed explanation of the issue.
144 + */
145 + if (instance != null) {
146 + instance.onActivityReady(activity);
147 + }
148 + }
149 +
150 + /**
151 + * Method called whenever the PermissionsActivity has been destroyed.
152 + */
153 + static void onActivityDestroyed() {
154 + if (instance != null) {
155 + instance.onActivityDestroyed();
156 + }
157 + }
158 +
159 + /**
160 + * Method called when all the permissions has been requested to the user
161 + *
162 + * @param grantedPermissions Collection with all the permissions the user has granted. Contains
163 + * values from {@link android.Manifest.permission}
164 + * @param deniedPermissions Collection with all the permissions the user has denied. Contains
165 + * values from {@link android.Manifest.permission}
166 + */
167 + static void onPermissionsRequested(Collection<String> grantedPermissions,
168 + Collection<String> deniedPermissions) {
169 + /* Check against null values because sometimes the PermissionsActivity can call these internal
170 + methods when the DexterInstance has been cleaned up.
171 + Refer to this commit message for a more detailed explanation of the issue.
172 + */
173 + if (instance != null) {
174 + instance.onPermissionRequestGranted(grantedPermissions);
175 + instance.onPermissionRequestDenied(deniedPermissions);
176 + }
177 + }
178 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright (C) 2016 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +
20 +import java.util.Collection;
21 +
22 +import ly.warp.sdk.dexter.listener.PermissionRequestErrorListener;
23 +import ly.warp.sdk.dexter.listener.multi.MultiplePermissionsListener;
24 +import ly.warp.sdk.dexter.listener.single.PermissionListener;
25 +
26 +public interface DexterBuilder {
27 +
28 + DexterBuilder onSameThread();
29 +
30 + DexterBuilder withErrorListener(PermissionRequestErrorListener errorListener);
31 +
32 + void check();
33 +
34 + interface Permission {
35 + DexterBuilder.SinglePermissionListener withPermission(String permission);
36 +
37 + DexterBuilder.MultiPermissionListener withPermissions(String... permissions);
38 +
39 + DexterBuilder.MultiPermissionListener withPermissions(Collection<String> permissions);
40 + }
41 +
42 + interface SinglePermissionListener {
43 + DexterBuilder withListener(PermissionListener listener);
44 + }
45 +
46 + interface MultiPermissionListener {
47 + DexterBuilder withListener(MultiplePermissionsListener listener);
48 + }
49 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright (C) 2016 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +
20 +import ly.warp.sdk.dexter.listener.DexterError;
21 +
22 +final class DexterException extends IllegalStateException {
23 +
24 + public final DexterError error;
25 +
26 + public DexterException(String detailMessage, DexterError error) {
27 + super(detailMessage);
28 + this.error = error;
29 + }
30 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +import android.content.Context;
20 +import android.content.Intent;
21 +
22 +class IntentProvider {
23 + public Intent get(Context context, Class<?> clazz) {
24 + return new Intent(context, clazz);
25 + }
26 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +import android.os.Handler;
20 +import android.os.Looper;
21 +
22 +/**
23 + * A thread to execute passed runnable objects in the main thread
24 + */
25 +final class MainThread implements Thread {
26 +
27 + MainThread() {
28 + }
29 +
30 + @Override public void execute(Runnable runnable) {
31 + if (runningMainThread()) {
32 + runnable.run();
33 + } else {
34 + new Handler(Looper.getMainLooper()).post(runnable);
35 + }
36 + }
37 +
38 + @Override public void loop() {
39 + }
40 +
41 + private static boolean runningMainThread() {
42 + return Looper.getMainLooper() == Looper.myLooper();
43 + }
44 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +
20 +import java.util.List;
21 +
22 +import ly.warp.sdk.dexter.listener.PermissionRequest;
23 +import ly.warp.sdk.dexter.listener.multi.MultiplePermissionsListener;
24 +
25 +/**
26 + * Decorator to execute the permission updates on a given thread
27 + */
28 +final class MultiplePermissionListenerThreadDecorator implements MultiplePermissionsListener {
29 +
30 + private final MultiplePermissionsListener listener;
31 + private final Thread thread;
32 +
33 + MultiplePermissionListenerThreadDecorator(MultiplePermissionsListener listener,
34 + Thread thread) {
35 + this.thread = thread;
36 + this.listener = listener;
37 + }
38 +
39 + /**
40 + * Decorates de permission listener execution with a given thread
41 + *
42 + * @param report In detail report with all the permissions that has been denied and granted
43 + */
44 + @Override public void onPermissionsChecked(final MultiplePermissionsReport report) {
45 + thread.execute(new Runnable() {
46 + @Override public void run() {
47 + listener.onPermissionsChecked(report);
48 + }
49 + });
50 + }
51 +
52 + /**
53 + * Decorates de permission listener execution with a given thread
54 + *
55 + * @param permissions The permissions that has been requested. Collections of values found in
56 + * {@link android.Manifest.permission}
57 + * @param token Token used to continue or cancel the permission request process. The permission
58 + * request process will remain blocked until one of the token methods is called
59 + */
60 + @Override public void onPermissionRationaleShouldBeShown(
61 + final List<PermissionRequest> permissions, final PermissionToken token) {
62 + thread.execute(new Runnable() {
63 + @Override public void run() {
64 + listener.onPermissionRationaleShouldBeShown(permissions, token);
65 + }
66 + });
67 + }
68 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +
20 +import java.util.List;
21 +
22 +import ly.warp.sdk.dexter.listener.PermissionDeniedResponse;
23 +import ly.warp.sdk.dexter.listener.PermissionGrantedResponse;
24 +import ly.warp.sdk.dexter.listener.PermissionRequest;
25 +import ly.warp.sdk.dexter.listener.multi.MultiplePermissionsListener;
26 +import ly.warp.sdk.dexter.listener.single.PermissionListener;
27 +
28 +/**
29 + * Adapter to translate calls to a {@link MultiplePermissionsListener} into @{PermissionListener}
30 + * methods
31 + */
32 +final class MultiplePermissionsListenerToPermissionListenerAdapter
33 + implements MultiplePermissionsListener {
34 +
35 + private final PermissionListener listener;
36 +
37 + public MultiplePermissionsListenerToPermissionListenerAdapter(PermissionListener listener) {
38 + this.listener = listener;
39 + }
40 +
41 + @Override public void onPermissionsChecked(MultiplePermissionsReport report) {
42 + List<PermissionDeniedResponse> deniedResponses = report.getDeniedPermissionResponses();
43 + List<PermissionGrantedResponse> grantedResponses = report.getGrantedPermissionResponses();
44 +
45 + if (!deniedResponses.isEmpty()) {
46 + PermissionDeniedResponse response = deniedResponses.get(0);
47 + listener.onPermissionDenied(response);
48 + } else {
49 + PermissionGrantedResponse response = grantedResponses.get(0);
50 + listener.onPermissionGranted(response);
51 + }
52 + }
53 +
54 + @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> requests,
55 + PermissionToken token) {
56 + PermissionRequest firstRequest = requests.get(0);
57 + listener.onPermissionRationaleShouldBeShown(firstRequest, token);
58 + }
59 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +
20 +import java.util.LinkedList;
21 +import java.util.List;
22 +
23 +import ly.warp.sdk.dexter.listener.PermissionDeniedResponse;
24 +import ly.warp.sdk.dexter.listener.PermissionGrantedResponse;
25 +
26 +/**
27 + * An in detail report of the request permission process
28 + */
29 +public final class MultiplePermissionsReport {
30 +
31 + private final List<PermissionGrantedResponse> grantedPermissionResponses;
32 + private final List<PermissionDeniedResponse> deniedPermissionResponses;
33 +
34 + MultiplePermissionsReport() {
35 + grantedPermissionResponses = new LinkedList<>();
36 + deniedPermissionResponses = new LinkedList<>();
37 + }
38 +
39 + /**
40 + * Returns a collection with all the permissions that has been granted
41 + */
42 + public List<PermissionGrantedResponse> getGrantedPermissionResponses() {
43 + return grantedPermissionResponses;
44 + }
45 +
46 + /**
47 + * Returns a collection with all the permissions that has been denied
48 + */
49 + public List<PermissionDeniedResponse> getDeniedPermissionResponses() {
50 + return deniedPermissionResponses;
51 + }
52 +
53 + /**
54 + * Returns whether the user has granted all the requested permission
55 + */
56 + public boolean areAllPermissionsGranted() {
57 + return deniedPermissionResponses.isEmpty();
58 + }
59 +
60 + /**
61 + * Returns whether the user has permanently denied any of the requested permissions
62 + */
63 + public boolean isAnyPermissionPermanentlyDenied() {
64 + boolean hasPermanentlyDeniedAnyPermission = false;
65 +
66 + for (PermissionDeniedResponse deniedResponse : deniedPermissionResponses) {
67 + if (deniedResponse.isPermanentlyDenied()) {
68 + hasPermanentlyDeniedAnyPermission = true;
69 + break;
70 + }
71 + }
72 +
73 + return hasPermanentlyDeniedAnyPermission;
74 + }
75 +
76 + boolean addGrantedPermissionResponse(PermissionGrantedResponse response) {
77 + return grantedPermissionResponses.add(response);
78 + }
79 +
80 + boolean addDeniedPermissionResponse(PermissionDeniedResponse response) {
81 + return deniedPermissionResponses.add(response);
82 + }
83 +
84 + void clear() {
85 + grantedPermissionResponses.clear();
86 + deniedPermissionResponses.clear();
87 + }
88 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +final class PermissionRationaleToken implements PermissionToken {
20 +
21 + private final DexterInstance dexterInstance;
22 + private boolean isTokenResolved = false;
23 +
24 + public PermissionRationaleToken(DexterInstance dexterInstance) {
25 + this.dexterInstance = dexterInstance;
26 + }
27 +
28 + @Override public void continuePermissionRequest() {
29 + if (!isTokenResolved) {
30 + dexterInstance.onContinuePermissionRequest();
31 + isTokenResolved = true;
32 + }
33 + }
34 +
35 + @Override public void cancelPermissionRequest() {
36 + if (!isTokenResolved) {
37 + dexterInstance.onCancelPermissionRequest();
38 + isTokenResolved = true;
39 + }
40 + }
41 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +/**
20 + * Utility class to let clients show the user how is the permission going to be used
21 + * Clients of this class must call one of the two methods and only once
22 + */
23 +public interface PermissionToken {
24 +
25 + /**
26 + * Continues with the permission request process
27 + */
28 + void continuePermissionRequest();
29 +
30 + /**
31 + * Cancels the permission request process
32 + */
33 + void cancelPermissionRequest();
34 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +import android.app.Activity;
20 +import android.content.Intent;
21 +import android.content.pm.PackageManager;
22 +import android.os.Bundle;
23 +import androidx.annotation.NonNull;
24 +import android.view.WindowManager;
25 +
26 +import java.util.Collection;
27 +import java.util.LinkedList;
28 +
29 +public final class PermissionsActivity extends Activity {
30 +
31 + @Override protected void onCreate(Bundle savedInstanceState) {
32 + super.onCreate(savedInstanceState);
33 + Dexter.onActivityReady(this);
34 +
35 + //Style
36 + getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
37 + getWindow().setBackgroundDrawableResource(android.R.color.transparent);
38 +
39 + }
40 +
41 + @Override protected void onDestroy() {
42 + super.onDestroy();
43 + Dexter.onActivityDestroyed();
44 + }
45 +
46 + @Override protected void onNewIntent(Intent intent) {
47 + super.onNewIntent(intent);
48 + Dexter.onActivityReady(this);
49 + }
50 +
51 + @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
52 + Collection<String> grantedPermissions = new LinkedList<>();
53 + Collection<String> deniedPermissions = new LinkedList<>();
54 +
55 + for (int i = 0; i < permissions.length; i++) {
56 + String permission = permissions[i];
57 + if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
58 + deniedPermissions.add(permission);
59 + } else {
60 + grantedPermissions.add(permission);
61 + }
62 + }
63 +
64 + Dexter.onPermissionsRequested(grantedPermissions, deniedPermissions);
65 + }
66 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +/**
20 + * Abstraction around threads to execute passed runnable objects in a certain thread
21 + */
22 +interface Thread {
23 + void execute(Runnable runnable);
24 +
25 + void loop();
26 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +import android.os.Looper;
20 +
21 +/**
22 + * Factory to create the different thread implementations
23 + */
24 +final class ThreadFactory {
25 +
26 + /**
27 + * Create a thread to execute on the main thread
28 + */
29 + public static Thread makeMainThread() {
30 + return new MainThread();
31 + }
32 +
33 + /**
34 + * Create a thread to execute on the same thread that this method is executed on
35 + */
36 + public static Thread makeSameThread() {
37 + if (runningMainThread()) {
38 + return new MainThread();
39 + } else {
40 + return new WorkerThread();
41 + }
42 + }
43 +
44 + private static boolean runningMainThread() {
45 + return Looper.getMainLooper().getThread() == java.lang.Thread.currentThread();
46 + }
47 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter;
18 +
19 +import android.os.Handler;
20 +import android.os.Looper;
21 +
22 +/**
23 + * A thread to execute passed runnable objects on a worker thread
24 + */
25 +final class WorkerThread implements Thread {
26 +
27 + private final Handler handler;
28 +
29 + WorkerThread() {
30 + if (Looper.myLooper() == null) {
31 + Looper.prepare();
32 + }
33 + handler = new Handler();
34 + }
35 +
36 + @Override public void execute(final Runnable runnable) {
37 + handler.post(runnable);
38 + }
39 +
40 + @Override public void loop() {
41 + Looper.loop();
42 + }
43 +}
1 +/*
2 + * Copyright (C) 2016 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener;
18 +
19 +public enum DexterError {
20 + /**
21 + * Error code used when the user tries to request permissions before all previous
22 + * requests has finished.
23 + */
24 + REQUEST_ONGOING,
25 +
26 + /**
27 + * Error code used when Dexter is called with no permissions.
28 + */
29 + NO_PERMISSIONS_REQUESTED
30 +}
1 +/*
2 + * Copyright (C) 2016 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener;
18 +
19 +public class EmptyPermissionRequestErrorListener implements PermissionRequestErrorListener {
20 + @Override public void onError(DexterError error) {
21 + }
22 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener;
18 +
19 +import androidx.annotation.NonNull;
20 +
21 +/**
22 + * If a permission was denied, an instance of this class will be returned
23 + * in the callback.
24 + */
25 +public final class PermissionDeniedResponse {
26 +
27 + private final PermissionRequest requestedPermission;
28 + private final boolean permanentlyDenied;
29 +
30 + public PermissionDeniedResponse(@NonNull PermissionRequest requestedPermission,
31 + boolean permanentlyDenied) {
32 + this.requestedPermission = requestedPermission;
33 + this.permanentlyDenied = permanentlyDenied;
34 + }
35 +
36 + /**
37 + * Builds a new instance of PermissionDeniedResponse from a given permission string
38 + * and a permanently-denied boolean flag
39 + */
40 + public static PermissionDeniedResponse from(@NonNull String permission,
41 + boolean permanentlyDenied) {
42 + return new PermissionDeniedResponse(new PermissionRequest(permission), permanentlyDenied);
43 + }
44 +
45 + public PermissionRequest getRequestedPermission() {
46 + return requestedPermission;
47 + }
48 +
49 + public String getPermissionName() {
50 + return requestedPermission.getName();
51 + }
52 +
53 + public boolean isPermanentlyDenied() {
54 + return permanentlyDenied;
55 + }
56 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener;
18 +
19 +import androidx.annotation.NonNull;
20 +
21 +/**
22 + * If a permission was granted, an instance of this class will be returned
23 + * in the callback.
24 + */
25 +public final class PermissionGrantedResponse {
26 +
27 + private final PermissionRequest requestedPermission;
28 +
29 + public PermissionGrantedResponse(@NonNull PermissionRequest requestedPermission) {
30 + this.requestedPermission = requestedPermission;
31 + }
32 +
33 + /**
34 + * Builds a new instance of PermissionGrantedResponse from a given permission string
35 + */
36 + public static PermissionGrantedResponse from(@NonNull String permission) {
37 + return new PermissionGrantedResponse(new PermissionRequest(permission));
38 + }
39 +
40 + public PermissionRequest getRequestedPermission() {
41 + return requestedPermission;
42 + }
43 +
44 + public String getPermissionName() {
45 + return requestedPermission.getName();
46 + }
47 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener;
18 +
19 +import androidx.annotation.NonNull;
20 +
21 +/**
22 + * Wrapper class for a permission request
23 + */
24 +public final class PermissionRequest {
25 +
26 + private final String name;
27 +
28 + public PermissionRequest(@NonNull String name) {
29 + this.name = name;
30 + }
31 +
32 + /**
33 + * One of the values found in {@link android.Manifest.permission}
34 + */
35 + public String getName() {
36 + return name;
37 + }
38 +
39 + @Override public String toString() {
40 + return "Permission name: " + name;
41 + }
42 +}
1 +/*
2 + * Copyright (C) 2016 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener;
18 +
19 +/**
20 + * Listener to be notified when a Dexter error occurs.
21 + */
22 +public interface PermissionRequestErrorListener {
23 + /**
24 + * Method called whenever Dexter fails.
25 + */
26 + void onError(DexterError error);
27 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener.multi;
18 +
19 +
20 +import java.util.List;
21 +
22 +import ly.warp.sdk.dexter.MultiplePermissionsReport;
23 +import ly.warp.sdk.dexter.PermissionToken;
24 +import ly.warp.sdk.dexter.listener.PermissionRequest;
25 +
26 +/**
27 + * Base implementation of {@link MultiplePermissionsListener} to allow extensions to implement
28 + * only the required methods
29 + */
30 +public class BaseMultiplePermissionsListener implements MultiplePermissionsListener {
31 +
32 + @Override public void onPermissionsChecked(MultiplePermissionsReport report) {
33 +
34 + }
35 +
36 + @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions,
37 + PermissionToken token) {
38 + token.continuePermissionRequest();
39 + }
40 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener.multi;
18 +
19 +
20 +import java.util.Arrays;
21 +import java.util.Collection;
22 +import java.util.List;
23 +
24 +import ly.warp.sdk.dexter.MultiplePermissionsReport;
25 +import ly.warp.sdk.dexter.PermissionToken;
26 +import ly.warp.sdk.dexter.listener.PermissionRequest;
27 +
28 +/**
29 + * Listener that composes multiple listeners into one
30 + * All inner listeners will be called for a given event unless one of them throws an exception or
31 + * is blocked
32 + */
33 +public class CompositeMultiplePermissionsListener implements MultiplePermissionsListener {
34 +
35 + private final Collection<MultiplePermissionsListener> listeners;
36 +
37 + /**
38 + * Creates a {@link CompositeMultiplePermissionsListener} containing all the provided listeners.
39 + * This constructor does not guaranty any calling order on inner listeners.
40 + */
41 + public CompositeMultiplePermissionsListener(MultiplePermissionsListener... listeners) {
42 + this(Arrays.asList(listeners));
43 + }
44 +
45 + /**
46 + * Creates a {@link CompositeMultiplePermissionsListener} containing all the provided listeners.
47 + * This constructor will guaranty that inner listeners are called following the iterator order
48 + * of the collection.
49 + */
50 + public CompositeMultiplePermissionsListener(Collection<MultiplePermissionsListener> listeners) {
51 + this.listeners = listeners;
52 + }
53 +
54 + @Override public void onPermissionsChecked(MultiplePermissionsReport report) {
55 + for (MultiplePermissionsListener listener : listeners) {
56 + listener.onPermissionsChecked(report);
57 + }
58 + }
59 +
60 + @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions,
61 + PermissionToken token) {
62 + for (MultiplePermissionsListener listener : listeners) {
63 + listener.onPermissionRationaleShouldBeShown(permissions, token);
64 + }
65 + }
66 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener.multi;
18 +
19 +import android.app.AlertDialog;
20 +import android.app.Dialog;
21 +import android.content.Context;
22 +import android.content.DialogInterface;
23 +import android.graphics.drawable.Drawable;
24 +import androidx.annotation.DrawableRes;
25 +import androidx.annotation.StringRes;
26 +
27 +import ly.warp.sdk.dexter.MultiplePermissionsReport;
28 +
29 +
30 +/**
31 + * Utility listener that shows a {@link Dialog} with a minimum configuration when the user rejects
32 + * any of the requested permissions
33 + */
34 +public class DialogOnAnyDeniedMultiplePermissionsListener extends BaseMultiplePermissionsListener {
35 +
36 + private final Context context;
37 + private final String title;
38 + private final String message;
39 + private final String positiveButtonText;
40 + private final Drawable icon;
41 +
42 + private DialogOnAnyDeniedMultiplePermissionsListener(Context context, String title,
43 + String message, String positiveButtonText, Drawable icon) {
44 + this.context = context;
45 + this.title = title;
46 + this.message = message;
47 + this.positiveButtonText = positiveButtonText;
48 + this.icon = icon;
49 + }
50 +
51 + @Override public void onPermissionsChecked(MultiplePermissionsReport report) {
52 + super.onPermissionsChecked(report);
53 +
54 + if (!report.areAllPermissionsGranted()) {
55 + showDialog();
56 + }
57 + }
58 +
59 + private void showDialog() {
60 + new AlertDialog.Builder(context)
61 + .setTitle(title)
62 + .setMessage(message)
63 + .setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() {
64 + @Override public void onClick(DialogInterface dialog, int which) {
65 + dialog.dismiss();
66 + }
67 + })
68 + .setIcon(icon)
69 + .show();
70 + }
71 +
72 + /**
73 + * Builder class to configure the displayed dialog.
74 + * Non set fields will be initialized to an empty string.
75 + */
76 + public static class Builder {
77 + private final Context context;
78 + private String title;
79 + private String message;
80 + private String buttonText;
81 + private Drawable icon;
82 +
83 + private Builder(Context context) {
84 + this.context = context;
85 + }
86 +
87 + public static Builder withContext(Context context) {
88 + return new Builder(context);
89 + }
90 +
91 + public Builder withTitle(String title) {
92 + this.title = title;
93 + return this;
94 + }
95 +
96 + public Builder withTitle(@StringRes int resId) {
97 + this.title = context.getString(resId);
98 + return this;
99 + }
100 +
101 + public Builder withMessage(String message) {
102 + this.message = message;
103 + return this;
104 + }
105 +
106 + public Builder withMessage(@StringRes int resId) {
107 + this.message = context.getString(resId);
108 + return this;
109 + }
110 +
111 + public Builder withButtonText(String buttonText) {
112 + this.buttonText = buttonText;
113 + return this;
114 + }
115 +
116 + public Builder withButtonText(@StringRes int resId) {
117 + this.buttonText = context.getString(resId);
118 + return this;
119 + }
120 +
121 + public Builder withIcon(Drawable icon) {
122 + this.icon = icon;
123 + return this;
124 + }
125 +
126 + public Builder withIcon(@DrawableRes int resId) {
127 + this.icon = context.getResources().getDrawable(resId);
128 + return this;
129 + }
130 +
131 + public DialogOnAnyDeniedMultiplePermissionsListener build() {
132 + String title = this.title == null ? "" : this.title;
133 + String message = this.message == null ? "" : this.message;
134 + String buttonText = this.buttonText == null ? "" : this.buttonText;
135 + return new DialogOnAnyDeniedMultiplePermissionsListener(context, title, message, buttonText, icon);
136 + }
137 + }
138 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener.multi;
18 +
19 +
20 +import java.util.List;
21 +
22 +import ly.warp.sdk.dexter.MultiplePermissionsReport;
23 +import ly.warp.sdk.dexter.PermissionToken;
24 +import ly.warp.sdk.dexter.listener.PermissionRequest;
25 +
26 +/**
27 + * Interface that listens to updates to the permission requests
28 + */
29 +public interface MultiplePermissionsListener {
30 +
31 + /**
32 + * Method called when all permissions has been completely checked
33 + *
34 + * @param report In detail report with all the permissions that has been denied and granted
35 + */
36 + void onPermissionsChecked(MultiplePermissionsReport report);
37 +
38 + /**
39 + * Method called whenever Android asks the application to inform the user of the need for the
40 + * requested permissions. The request process won't continue until the token is properly used
41 + *
42 + * @param permissions The permissions that has been requested. Collections of values found in
43 + * {@link android.Manifest.permission}
44 + * @param token Token used to continue or cancel the permission request process. The permission
45 + * request process will remain blocked until one of the token methods is called
46 + */
47 + void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions,
48 + PermissionToken token);
49 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener.single;
18 +
19 +
20 +import ly.warp.sdk.dexter.PermissionToken;
21 +import ly.warp.sdk.dexter.listener.PermissionDeniedResponse;
22 +import ly.warp.sdk.dexter.listener.PermissionGrantedResponse;
23 +import ly.warp.sdk.dexter.listener.PermissionRequest;
24 +
25 +/**
26 + * Base implementation of {@link PermissionListener} to allow extensions to implement only the
27 + * required methods
28 + */
29 +public class BasePermissionListener implements PermissionListener {
30 +
31 + @Override public void onPermissionGranted(PermissionGrantedResponse response) {
32 +
33 + }
34 +
35 + @Override public void onPermissionDenied(PermissionDeniedResponse response) {
36 +
37 + }
38 +
39 + @Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission,
40 + PermissionToken token) {
41 + token.continuePermissionRequest();
42 + }
43 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener.single;
18 +
19 +
20 +import java.util.Arrays;
21 +import java.util.Collection;
22 +
23 +import ly.warp.sdk.dexter.PermissionToken;
24 +import ly.warp.sdk.dexter.listener.PermissionDeniedResponse;
25 +import ly.warp.sdk.dexter.listener.PermissionGrantedResponse;
26 +import ly.warp.sdk.dexter.listener.PermissionRequest;
27 +
28 +/**
29 + * Listener that composes multiple listeners into one
30 + * All inner listeners will be called for a given event unless one of them throws an exception or
31 + * is blocked
32 + */
33 +public class CompositePermissionListener implements PermissionListener {
34 +
35 + private final Collection<PermissionListener> listeners;
36 +
37 + /**
38 + * Creates a {@link CompositePermissionListener} containing all the provided listeners.
39 + * This constructor does not guaranty any calling order on inner listeners.
40 + */
41 + public CompositePermissionListener(PermissionListener... listeners) {
42 + this(Arrays.asList(listeners));
43 + }
44 +
45 + /**
46 + * Creates a {@link CompositePermissionListener} containing all the provided listeners.
47 + * This constructor will guaranty that inner listeners are called following the iterator order
48 + * of the collection.
49 + */
50 + public CompositePermissionListener(Collection<PermissionListener> listeners) {
51 + this.listeners = listeners;
52 + }
53 +
54 + @Override public void onPermissionGranted(PermissionGrantedResponse response) {
55 + for (PermissionListener listener : listeners) {
56 + listener.onPermissionGranted(response);
57 + }
58 + }
59 +
60 + @Override public void onPermissionDenied(PermissionDeniedResponse response) {
61 + for (PermissionListener listener : listeners) {
62 + listener.onPermissionDenied(response);
63 + }
64 + }
65 +
66 + @Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission,
67 + PermissionToken token) {
68 + for (PermissionListener listener : listeners) {
69 + listener.onPermissionRationaleShouldBeShown(permission, token);
70 + }
71 + }
72 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener.single;
18 +
19 +import android.app.AlertDialog;
20 +import android.content.Context;
21 +import android.content.DialogInterface;
22 +import android.graphics.drawable.Drawable;
23 +import androidx.annotation.DrawableRes;
24 +import androidx.annotation.StringRes;
25 +
26 +import ly.warp.sdk.dexter.listener.PermissionDeniedResponse;
27 +
28 +
29 +/**
30 + * Utility listener that shows a {@link android.app.Dialog} with a minimum configuration when the
31 + * user rejects some permission
32 + */
33 +public class DialogOnDeniedPermissionListener extends BasePermissionListener {
34 +
35 + private final Context context;
36 + private final String title;
37 + private final String message;
38 + private final String positiveButtonText;
39 + private final Drawable icon;
40 +
41 + private DialogOnDeniedPermissionListener(Context context, String title, String message,
42 + String positiveButtonText, Drawable icon) {
43 + this.context = context;
44 + this.title = title;
45 + this.message = message;
46 + this.positiveButtonText = positiveButtonText;
47 + this.icon = icon;
48 + }
49 +
50 + @Override public void onPermissionDenied(PermissionDeniedResponse response) {
51 + super.onPermissionDenied(response);
52 +
53 + new AlertDialog.Builder(context)
54 + .setTitle(title)
55 + .setMessage(message)
56 + .setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() {
57 + @Override public void onClick(DialogInterface dialog, int which) {
58 + dialog.dismiss();
59 + }
60 + })
61 + .setIcon(icon)
62 + .show();
63 + }
64 +
65 + /**
66 + * Builder class to configure the displayed dialog.
67 + * Non set fields will be initialized to an empty string.
68 + */
69 + public static class Builder {
70 + private final Context context;
71 + private String title;
72 + private String message;
73 + private String buttonText;
74 + private Drawable icon;
75 +
76 + private Builder(Context context) {
77 + this.context = context;
78 + }
79 +
80 + public static Builder withContext(Context context) {
81 + return new Builder(context);
82 + }
83 +
84 + public Builder withTitle(String title) {
85 + this.title = title;
86 + return this;
87 + }
88 +
89 + public Builder withTitle(@StringRes int resId) {
90 + this.title = context.getString(resId);
91 + return this;
92 + }
93 +
94 + public Builder withMessage(String message) {
95 + this.message = message;
96 + return this;
97 + }
98 +
99 + public Builder withMessage(@StringRes int resId) {
100 + this.message = context.getString(resId);
101 + return this;
102 + }
103 +
104 + public Builder withButtonText(String buttonText) {
105 + this.buttonText = buttonText;
106 + return this;
107 + }
108 +
109 + public Builder withButtonText(@StringRes int resId) {
110 + this.buttonText = context.getString(resId);
111 + return this;
112 + }
113 +
114 + public Builder withIcon(Drawable icon) {
115 + this.icon = icon;
116 + return this;
117 + }
118 +
119 + public Builder withIcon(@DrawableRes int resId) {
120 + this.icon = context.getResources().getDrawable(resId);
121 + return this;
122 + }
123 +
124 + public DialogOnDeniedPermissionListener build() {
125 + String title = this.title == null ? "" : this.title;
126 + String message = this.message == null ? "" : this.message;
127 + String buttonText = this.buttonText == null ? "" : this.buttonText;
128 + return new DialogOnDeniedPermissionListener(context, title, message, buttonText, icon);
129 + }
130 + }
131 +}
1 +/*
2 + * Copyright (C) 2015 Karumi.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package ly.warp.sdk.dexter.listener.single;
18 +
19 +
20 +import ly.warp.sdk.dexter.PermissionToken;
21 +import ly.warp.sdk.dexter.listener.PermissionDeniedResponse;
22 +import ly.warp.sdk.dexter.listener.PermissionGrantedResponse;
23 +import ly.warp.sdk.dexter.listener.PermissionRequest;
24 +
25 +/**
26 + * Interface that listens to updates to the permission requests
27 + */
28 +public interface PermissionListener {
29 +
30 + /**
31 + * Method called whenever a requested permission has been granted
32 + *
33 + * @param response A response object that contains the permission that has been requested and
34 + * any additional flags relevant to this response
35 + */
36 + void onPermissionGranted(PermissionGrantedResponse response);
37 +
38 + /**
39 + * Method called whenever a requested permission has been denied
40 + *
41 + * @param response A response object that contains the permission that has been requested and
42 + * any additional flags relevant to this response
43 + */
44 + void onPermissionDenied(PermissionDeniedResponse response);
45 +
46 + /**
47 + * Method called whenever Android asks the application to inform the user of the need for the
48 + * requested permission. The request process won't continue until the token is properly used
49 + *
50 + * @param permission The permission that has been requested
51 + * @param token Token used to continue or cancel the permission request process. The permission
52 + * request process will remain blocked until one of the token methods is called
53 + */
54 + void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token);
55 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +import org.json.JSONArray;
29 +import org.json.JSONObject;
30 +
31 +import ly.warp.sdk.io.models.AddressList;
32 +
33 +/**
34 + * Created by Panagiotis Triantafyllou on 18-Jan-22.
35 + */
36 +
37 +public class AddressHook implements CallbackReceiver<JSONObject> {
38 +
39 + private final CallbackReceiver<AddressList> mListener;
40 + private final String mRequestSignature;
41 +
42 + public AddressHook(CallbackReceiver<AddressList> listener, String requestSignature) {
43 + this.mListener = listener;
44 + this.mRequestSignature = requestSignature;
45 + }
46 +
47 + @Override
48 + public void onSuccess(JSONObject result) {
49 + if (mListener != null) {
50 + int status = result.optInt("status", 2);
51 + if (status == 1) {
52 + JSONArray jArrayResult = result.optJSONArray("result");
53 + if (jArrayResult == null) {
54 + mListener.onFailure(2);
55 + return;
56 + }
57 + mListener.onSuccess(new AddressList(result, mRequestSignature));
58 + } else
59 + mListener.onFailure(status);
60 + }
61 +
62 + }
63 +
64 + @Override
65 + public void onFailure(int errorCode) {
66 + if (mListener != null)
67 + mListener.onFailure(errorCode);
68 + }
69 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +public interface BaseCallbackReceiver {
29 +
30 + void onSuccess(int result);
31 +
32 + void onFailure(int errorCode);
33 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +public interface CallbackReceiver<T> {
29 +
30 + void onSuccess(T result);
31 +
32 + void onFailure(int errorCode);
33 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +import org.json.JSONObject;
29 +
30 +import ly.warp.sdk.io.models.CampaignList;
31 +import ly.warp.sdk.io.request.WarplyInboxRequest;
32 +
33 +public class CampaignsHook implements CallbackReceiver<JSONObject> {
34 +
35 + private final CallbackReceiver<CampaignList> mListener;
36 + private final String mRequestSignature;
37 +
38 + public CampaignsHook(CallbackReceiver<CampaignList> listener, String requestSignature) {
39 + this.mListener = listener;
40 + this.mRequestSignature = requestSignature;
41 + }
42 +
43 + @Override
44 + public void onSuccess(JSONObject result) {
45 +
46 + if (mListener != null) {
47 + mListener.onSuccess(new CampaignList(result, mRequestSignature));
48 + }
49 +
50 + }
51 +
52 + @Override
53 + public void onFailure(int errorCode) {
54 + if (mListener != null)
55 + mListener.onFailure(errorCode);
56 + }
57 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +import org.json.JSONArray;
29 +import org.json.JSONObject;
30 +
31 +import ly.warp.sdk.io.models.CardList;
32 +
33 +/**
34 + * Created by Panagiotis Triantafyllou on 11-Jan-22.
35 + */
36 +
37 +public class CardsHook implements CallbackReceiver<JSONObject> {
38 +
39 + private final CallbackReceiver<CardList> mListener;
40 + private final String mRequestSignature;
41 +
42 + public CardsHook(CallbackReceiver<CardList> listener, String requestSignature) {
43 + this.mListener = listener;
44 + this.mRequestSignature = requestSignature;
45 + }
46 +
47 + @Override
48 + public void onSuccess(JSONObject result) {
49 + if (mListener != null) {
50 + int status = result.optInt("status", 2);
51 + if (status == 1) {
52 + JSONArray jArrayResult = result.optJSONArray("result");
53 + if (jArrayResult == null) {
54 + mListener.onFailure(2);
55 + return;
56 + }
57 + mListener.onSuccess(new CardList(result, mRequestSignature));
58 + } else
59 + mListener.onFailure(status);
60 + }
61 +
62 + }
63 +
64 + @Override
65 + public void onFailure(int errorCode) {
66 + if (mListener != null)
67 + mListener.onFailure(errorCode);
68 + }
69 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +import org.json.JSONObject;
29 +
30 +/**
31 + * Created by Panagiotis Triantafyllou on 07-Dec-21.
32 + */
33 +
34 +public class ContactHook implements CallbackReceiver<JSONObject> {
35 +
36 + private final CallbackReceiver<JSONObject> mListener;
37 + private final String mRequestSignature;
38 +
39 + public ContactHook(CallbackReceiver<JSONObject> listener, String requestSignature) {
40 + this.mListener = listener;
41 + this.mRequestSignature = requestSignature;
42 + }
43 +
44 + @Override
45 + public void onSuccess(JSONObject result) {
46 + if (mListener != null) {
47 + mListener.onSuccess(result);
48 + }
49 +
50 + }
51 +
52 + @Override
53 + public void onFailure(int errorCode) {
54 + if (mListener != null)
55 + mListener.onFailure(errorCode);
56 + }
57 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +import org.json.JSONObject;
29 +
30 +import ly.warp.sdk.io.models.ContentList;
31 +
32 +/**
33 + * Created by Panagiotis Triantafyllou on 07-Dec-21.
34 + */
35 +
36 +public class ContentHook implements CallbackReceiver<JSONObject> {
37 +
38 + private final CallbackReceiver<ContentList> mListener;
39 + private final String mRequestSignature;
40 +
41 + public ContentHook(CallbackReceiver<ContentList> listener, String requestSignature) {
42 + this.mListener = listener;
43 + this.mRequestSignature = requestSignature;
44 + }
45 +
46 + @Override
47 + public void onSuccess(JSONObject result) {
48 + if (mListener != null) {
49 + mListener.onSuccess(new ContentList(result, mRequestSignature));
50 + }
51 +
52 + }
53 +
54 + @Override
55 + public void onFailure(int errorCode) {
56 + if (mListener != null)
57 + mListener.onFailure(errorCode);
58 + }
59 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +import org.json.JSONArray;
29 +import org.json.JSONObject;
30 +
31 +import ly.warp.sdk.io.models.CardList;
32 +import ly.warp.sdk.io.models.CouponList;
33 +
34 +/**
35 + * Created by Panagiotis Triantafyllou on 14-Jan-22.
36 + */
37 +
38 +public class CouponsHook implements CallbackReceiver<JSONObject> {
39 +
40 + private final CallbackReceiver<CouponList> mListener;
41 + private final String mRequestSignature;
42 +
43 + public CouponsHook(CallbackReceiver<CouponList> listener, String requestSignature) {
44 + this.mListener = listener;
45 + this.mRequestSignature = requestSignature;
46 + }
47 +
48 + @Override
49 + public void onSuccess(JSONObject result) {
50 + if (mListener != null) {
51 + int status = result.optInt("status", 2);
52 + if (status == 1) {
53 + JSONArray jArrayResult = result.optJSONArray("result");
54 + if (jArrayResult == null) {
55 + mListener.onFailure(2);
56 + return;
57 + }
58 + mListener.onSuccess(new CouponList(result, mRequestSignature));
59 + } else
60 + mListener.onFailure(status);
61 + }
62 +
63 + }
64 +
65 + @Override
66 + public void onFailure(int errorCode) {
67 + if (mListener != null)
68 + mListener.onFailure(errorCode);
69 + }
70 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +import org.json.JSONObject;
29 +
30 +import ly.warp.sdk.io.models.InboxStats;
31 +
32 +public class InboxStatsHook implements CallbackReceiver<JSONObject> {
33 +
34 + public InboxStatsHook(CallbackReceiver<InboxStats> receiver) {
35 + mReceiver = receiver;
36 + }
37 +
38 + private final CallbackReceiver<InboxStats> mReceiver;
39 +
40 + @Override
41 + public void onSuccess(JSONObject result) {
42 + mReceiver.onSuccess(new InboxStats(result));
43 + }
44 +
45 + @Override
46 + public void onFailure(int errorCode) {
47 + mReceiver.onFailure(errorCode);
48 + }
49 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +import org.json.JSONObject;
29 +
30 +import ly.warp.sdk.io.models.MerchantCategoriesList;
31 +
32 +/**
33 + * Created by Panagiotis Triantafyllou on 07-Dec-21.
34 + */
35 +
36 +public class MerchantCategoriesHook implements CallbackReceiver<JSONObject> {
37 +
38 + private final CallbackReceiver<MerchantCategoriesList> mListener;
39 + private final String mRequestSignature;
40 +
41 + public MerchantCategoriesHook(CallbackReceiver<MerchantCategoriesList> listener, String requestSignature) {
42 + this.mListener = listener;
43 + this.mRequestSignature = requestSignature;
44 + }
45 +
46 + @Override
47 + public void onSuccess(JSONObject result) {
48 + if (mListener != null) {
49 + mListener.onSuccess(new MerchantCategoriesList(result, mRequestSignature));
50 + }
51 +
52 + }
53 +
54 + @Override
55 + public void onFailure(int errorCode) {
56 + if (mListener != null)
57 + mListener.onFailure(errorCode);
58 + }
59 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +import org.json.JSONObject;
29 +
30 +import ly.warp.sdk.io.models.MerchantList;
31 +
32 +/**
33 + * Created by Panagiotis Triantafyllou on 07-Dec-21.
34 + */
35 +
36 +public class MerchantsHook implements CallbackReceiver<JSONObject> {
37 +
38 + private final CallbackReceiver<MerchantList> mListener;
39 + private final String mRequestSignature;
40 +
41 + public MerchantsHook(CallbackReceiver<MerchantList> listener, String requestSignature) {
42 + this.mListener = listener;
43 + this.mRequestSignature = requestSignature;
44 + }
45 +
46 + @Override
47 + public void onSuccess(JSONObject result) {
48 + if (mListener != null) {
49 + mListener.onSuccess(new MerchantList(result, mRequestSignature));
50 + }
51 +
52 + }
53 +
54 + @Override
55 + public void onFailure(int errorCode) {
56 + if (mListener != null)
57 + mListener.onFailure(errorCode);
58 + }
59 +}
1 +/*
2 + * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 + *
4 + * Redistribution and use in source and binary forms, without modification, are
5 + * permitted provided that the following conditions are met:
6 + *
7 + * 1. Redistributions of source code must retain the above copyright notice,
8 + * this list of conditions and the following disclaimer.
9 + *
10 + * 2. Redistributions in binary form must reproduce the above copyright notice,
11 + * this list of conditions and the following disclaimer in the documentation
12 + * and/or other materials provided with the distribution.
13 + *
14 + * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 + * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 + */
25 +
26 +package ly.warp.sdk.io.callbacks;
27 +
28 +import org.json.JSONArray;
29 +import org.json.JSONObject;
30 +
31 +import ly.warp.sdk.io.models.PointsList;
32 +
33 +/**
34 + * Created by Panagiotis Triantafyllou on 17-Jan-22.
35 + */
36 +
37 +public class PointsHook implements CallbackReceiver<JSONObject> {
38 +
39 + private final CallbackReceiver<PointsList> mListener;
40 + private final String mRequestSignature;
41 +
42 + public PointsHook(CallbackReceiver<PointsList> listener, String requestSignature) {
43 + this.mListener = listener;
44 + this.mRequestSignature = requestSignature;
45 + }
46 +
47 + @Override
48 + public void onSuccess(JSONObject result) {
49 + if (mListener != null) {
50 + int status = result.optInt("status", 2);
51 + if (status == 1) {
52 + JSONArray jArrayResult = result.optJSONArray("result");
53 + if (jArrayResult == null) {
54 + mListener.onFailure(2);
55 + return;
56 + }
57 + mListener.onSuccess(new PointsList(result, mRequestSignature));
58 + } else
59 + mListener.onFailure(status);
60 + }
61 +
62 + }
63 +
64 + @Override
65 + public void onFailure(int errorCode) {
66 + if (mListener != null)
67 + mListener.onFailure(errorCode);
68 + }
69 +}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.