Panagiotis Triantafyllou

initial commit

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