Panagiotis Triantafyllou

android target api 35, changed sdk version in constants

...@@ -3,13 +3,14 @@ apply plugin: 'com.google.gms.google-services' ...@@ -3,13 +3,14 @@ apply plugin: 'com.google.gms.google-services'
3 apply plugin: 'com.huawei.agconnect' 3 apply plugin: 'com.huawei.agconnect'
4 4
5 android { 5 android {
6 - compileSdkVersion 34 6 + compileSdkVersion 35
7 - buildToolsVersion "34.0.0" 7 + buildToolsVersion "35.0.0"
8 8
9 + namespace "warp.ly.android_sdk"
9 defaultConfig { 10 defaultConfig {
10 applicationId "warp.ly.android_sdk" 11 applicationId "warp.ly.android_sdk"
11 minSdkVersion 31 12 minSdkVersion 31
12 - targetSdkVersion 34 13 + targetSdkVersion 35
13 versionCode 100 14 versionCode 100
14 versionName "1.0.0" 15 versionName "1.0.0"
15 } 16 }
......
...@@ -8,9 +8,9 @@ buildscript { ...@@ -8,9 +8,9 @@ buildscript {
8 maven { url 'https://plugins.gradle.org/m2/' } 8 maven { url 'https://plugins.gradle.org/m2/' }
9 } 9 }
10 dependencies { 10 dependencies {
11 - classpath 'com.android.tools.build:gradle:8.8.0' 11 + classpath 'com.android.tools.build:gradle:8.7.3'
12 - classpath 'com.google.gms:google-services:4.4.2' 12 + classpath 'com.google.gms:google-services:4.4.3'
13 - classpath 'com.huawei.agconnect:agcp:1.9.1.300' 13 + classpath 'com.huawei.agconnect:agcp:1.9.1.301'
14 classpath 'io.github.gradle-nexus:publish-plugin:1.1.0' 14 classpath 'io.github.gradle-nexus:publish-plugin:1.1.0'
15 15
16 // NOTE: Do not place your application dependencies here; they belong 16 // NOTE: Do not place your application dependencies here; they belong
...@@ -18,6 +18,10 @@ buildscript { ...@@ -18,6 +18,10 @@ buildscript {
18 } 18 }
19 } 19 }
20 20
21 +plugins {
22 + id 'maven-publish'
23 +}
24 +
21 allprojects { 25 allprojects {
22 repositories { 26 repositories {
23 mavenCentral() 27 mavenCentral()
...@@ -27,5 +31,4 @@ allprojects { ...@@ -27,5 +31,4 @@ allprojects {
27 } 31 }
28 } 32 }
29 33
30 -apply plugin: 'io.github.gradle-nexus.publish-plugin'
31 apply from: "${rootDir}/scripts/publish-root.gradle" 34 apply from: "${rootDir}/scripts/publish-root.gradle"
...\ No newline at end of file ...\ No newline at end of file
......
1 #Fri Jul 26 17:08:44 EEST 2024 1 #Fri Jul 26 17:08:44 EEST 2024
2 distributionBase=GRADLE_USER_HOME 2 distributionBase=GRADLE_USER_HOME
3 distributionPath=wrapper/dists 3 distributionPath=wrapper/dists
4 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
5 zipStoreBase=GRADLE_USER_HOME 5 zipStoreBase=GRADLE_USER_HOME
6 zipStorePath=wrapper/dists 6 zipStorePath=wrapper/dists
......
This diff is collapsed. Click to expand it.
1 // Create variables with empty default values 1 // Create variables with empty default values
2 2
3 +// Central Portal credentials
4 +ext["centralPortalUsername"] = ''
5 +ext["centralPortalPassword"] = ''
6 +
3 // keyId is the last 8 characters of the GPG key 7 // keyId is the last 8 characters of the GPG key
4 ext["signing.keyId"] = '' 8 ext["signing.keyId"] = ''
5 // password is the passphrase of the GPG key 9 // password is the passphrase of the GPG key
6 ext["signing.password"] = '' 10 ext["signing.password"] = ''
7 // key is the base64 private GPG key 11 // key is the base64 private GPG key
8 ext["signing.key"] = '' 12 ext["signing.key"] = ''
9 -// osshrUsername and ossrhPassword are the account details for MavenCentral
10 -// which we’ve chosen at the Jira registration step (Sonatype site))
11 -ext["ossrhUsername"] = ''
12 -ext["ossrhPassword"] = ''
13 -ext["sonatypeStagingProfileId"] = ''
14 13
15 File secretPropsFile = project.rootProject.file('local.properties') 14 File secretPropsFile = project.rootProject.file('local.properties')
16 if (secretPropsFile.exists()) { 15 if (secretPropsFile.exists()) {
...@@ -19,24 +18,11 @@ if (secretPropsFile.exists()) { ...@@ -19,24 +18,11 @@ if (secretPropsFile.exists()) {
19 new FileInputStream(secretPropsFile).withCloseable { is -> p.load(is) } 18 new FileInputStream(secretPropsFile).withCloseable { is -> p.load(is) }
20 p.each { name, value -> ext[name] = value } 19 p.each { name, value -> ext[name] = value }
21 } else { 20 } else {
22 - // Use system environment variables 21 + // Use system environment variables for signing
23 - ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME')
24 - ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD')
25 - ext["sonatypeStagingProfileId"] = System.getenv('SONATYPE_STAGING_PROFILE_ID')
26 ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID') 22 ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID')
27 ext["signing.password"] = System.getenv('SIGNING_PASSWORD') 23 ext["signing.password"] = System.getenv('SIGNING_PASSWORD')
28 ext["signing.key"] = System.getenv('SIGNING_KEY') 24 ext["signing.key"] = System.getenv('SIGNING_KEY')
29 -} 25 + // Central Portal credentials can also come from environment
30 - 26 + ext["centralPortalUsername"] = System.getenv('CENTRAL_PORTAL_USERNAME')
31 -// Set up Sonatype repository 27 + ext["centralPortalPassword"] = System.getenv('CENTRAL_PORTAL_PASSWORD')
32 -nexusPublishing {
33 - repositories {
34 - sonatype {
35 - stagingProfileId = sonatypeStagingProfileId
36 - username = ossrhUsername
37 - password = ossrhPassword
38 - nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
39 - snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
40 - }
41 - }
42 } 28 }
......
...@@ -5,15 +5,15 @@ android.buildFeatures.buildConfig = true ...@@ -5,15 +5,15 @@ android.buildFeatures.buildConfig = true
5 5
6 ext { 6 ext {
7 PUBLISH_GROUP_ID = 'ly.warp' 7 PUBLISH_GROUP_ID = 'ly.warp'
8 - PUBLISH_VERSION = '4.5.5.4deh2' 8 + PUBLISH_VERSION = '4.5.5.4deh3'
9 PUBLISH_ARTIFACT_ID = 'warply-android-sdk' 9 PUBLISH_ARTIFACT_ID = 'warply-android-sdk'
10 } 10 }
11 11
12 apply from: "${rootProject.projectDir}/scripts/publish-module.gradle" 12 apply from: "${rootProject.projectDir}/scripts/publish-module.gradle"
13 13
14 android { 14 android {
15 - compileSdkVersion 34 15 + compileSdkVersion 35
16 - buildToolsVersion "34.0.0" 16 + buildToolsVersion "35.0.0"
17 17
18 useLibrary 'org.apache.http.legacy' 18 useLibrary 'org.apache.http.legacy'
19 19
...@@ -27,7 +27,7 @@ android { ...@@ -27,7 +27,7 @@ android {
27 27
28 defaultConfig { 28 defaultConfig {
29 minSdkVersion 31 29 minSdkVersion 31
30 - targetSdkVersion 34 30 + targetSdkVersion 35
31 consumerProguardFiles 'proguard-rules.pro' 31 consumerProguardFiles 'proguard-rules.pro'
32 vectorDrawables.useSupportLibrary = true 32 vectorDrawables.useSupportLibrary = true
33 } 33 }
...@@ -61,45 +61,42 @@ android { ...@@ -61,45 +61,42 @@ android {
61 61
62 dependencies { 62 dependencies {
63 //------------------------------ Support -----------------------------// 63 //------------------------------ Support -----------------------------//
64 - implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' 64 + implementation 'androidx.appcompat:appcompat:1.7.1'
65 - implementation 'androidx.appcompat:appcompat:1.4.1' 65 + implementation "androidx.security:security-crypto:1.1.0"
66 - api "androidx.security:security-crypto:1.1.0-alpha03"
67 // For minSDK 23 use 1.0.0, for minSDK 21 use 1.1.0 that is currently in alpha 66 // For minSDK 23 use 1.0.0, for minSDK 21 use 1.1.0 that is currently in alpha
68 - api 'org.altbeacon:android-beacon-library:2.19.3' 67 + implementation 'org.altbeacon:android-beacon-library:2.19.3'
69 - api 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2' 68 + implementation 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
70 - api 'io.reactivex.rxjava3:rxjava:3.1.8' 69 + implementation 'io.reactivex.rxjava3:rxjava:3.1.8'
71 - api 'io.reactivex.rxjava3:rxandroid:3.0.2' 70 + implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'
72 - implementation 'com.google.android.material:material:1.5.0' 71 + implementation 'com.google.android.material:material:1.12.0'
73 implementation 'org.greenrobot:eventbus:3.3.1' 72 implementation 'org.greenrobot:eventbus:3.3.1'
74 - api 'com.google.guava:guava:30.1-android' 73 + implementation 'com.google.guava:guava:33.0.0-android'
75 74
76 //------------------------------ Firebase -----------------------------// 75 //------------------------------ Firebase -----------------------------//
77 - api platform('com.google.firebase:firebase-bom:29.0.3') 76 + implementation platform('com.google.firebase:firebase-bom:34.2.0')
78 implementation('com.google.firebase:firebase-messaging') { 77 implementation('com.google.firebase:firebase-messaging') {
79 exclude group: 'com.google.android.gms', module: 'play-services-location' 78 exclude group: 'com.google.android.gms', module: 'play-services-location'
80 } 79 }
81 80
82 //------------------------------ GMS -----------------------------// 81 //------------------------------ GMS -----------------------------//
83 - api 'com.google.android.gms:play-services-base:18.1.0' 82 + implementation 'com.google.android.gms:play-services-base:18.7.2'
84 - implementation 'com.google.android.gms:play-services-location:19.0.1' 83 + implementation 'com.google.android.gms:play-services-location:21.3.0'
85 84
86 //------------------------------ Work Manager -----------------------------// 85 //------------------------------ Work Manager -----------------------------//
87 - api 'androidx.work:work-runtime:2.7.1' 86 + implementation 'androidx.work:work-runtime:2.10.3'
88 87
89 //------------------------------ Glide -----------------------------// 88 //------------------------------ Glide -----------------------------//
90 - implementation 'com.github.bumptech.glide:glide:4.12.0' 89 + implementation 'com.github.bumptech.glide:glide:4.16.0'
91 - annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' 90 + annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
92 91
93 //------------------------------ Huawei -----------------------------// 92 //------------------------------ Huawei -----------------------------//
94 - implementation 'com.huawei.agconnect:agconnect-core:1.7.2.300' 93 + implementation 'com.huawei.agconnect:agconnect-core:1.9.3.301'
95 - implementation 'com.huawei.hms:base:6.6.0.300' 94 + implementation 'com.huawei.hms:base:6.13.0.303'
96 - implementation 'com.huawei.hms:push:6.7.0.300' 95 + implementation 'com.huawei.hms:push:6.10.0.300'
97 - implementation 'com.huawei.hms:ads-identifier:3.4.56.300' 96 + implementation 'com.huawei.hms:ads-identifier:3.4.62.300'
98 - 97 +
99 - //------------------------------ SQLCipher -----------------------------// 98 + //------------------------------ SQLite (Standard Android) -----------------------------//
100 - api "net.zetetic:android-database-sqlcipher:4.5.2" 99 + implementation 'androidx.sqlite:sqlite:2.5.2'
101 - api "androidx.sqlite:sqlite:2.2.0"
102 - api 'com.getkeepsafe.relinker:relinker:1.4.4'
103 100
104 //------------------------------ Retrofit -----------------------------// 101 //------------------------------ Retrofit -----------------------------//
105 implementation 'com.squareup.retrofit2:retrofit:2.9.0' 102 implementation 'com.squareup.retrofit2:retrofit:2.9.0'
......
...@@ -52,7 +52,6 @@ public class BaseFragmentActivity extends FragmentActivity implements Navigation ...@@ -52,7 +52,6 @@ public class BaseFragmentActivity extends FragmentActivity implements Navigation
52 mBottomNavigationView = findViewById(R.id.bt_tabs); 52 mBottomNavigationView = findViewById(R.id.bt_tabs);
53 53
54 if (WarplyDBHelper.getInstance(this).isTableNotEmpty("auth")) { 54 if (WarplyDBHelper.getInstance(this).isTableNotEmpty("auth")) {
55 - WarplyManager.getSupermarketCampaign(mCampaignsCallback);
56 WarplyManager.getRedeemedSMHistory(mSMHistoryReceiver); 55 WarplyManager.getRedeemedSMHistory(mSMHistoryReceiver);
57 } 56 }
58 57
...@@ -138,18 +137,6 @@ public class BaseFragmentActivity extends FragmentActivity implements Navigation ...@@ -138,18 +137,6 @@ public class BaseFragmentActivity extends FragmentActivity implements Navigation
138 // Inner and Anonymous Classes 137 // Inner and Anonymous Classes
139 // =========================================================== 138 // ===========================================================
140 139
141 - private final CallbackReceiver<ArrayList<Campaign>> mCampaignsCallback = new CallbackReceiver<ArrayList<Campaign>>() {
142 - @Override
143 - public void onSuccess(ArrayList<Campaign> result) {
144 - Toast.makeText(BaseFragmentActivity.this, "Campaigns Success " + String.valueOf(result.size()), Toast.LENGTH_SHORT).show();
145 - }
146 -
147 - @Override
148 - public void onFailure(int errorCode) {
149 - Toast.makeText(BaseFragmentActivity.this, "Campaigns Error", Toast.LENGTH_SHORT).show();
150 - }
151 - };
152 -
153 private final CallbackReceiver<RedeemedSMHistoryModel> mSMHistoryReceiver = new CallbackReceiver<RedeemedSMHistoryModel>() { 140 private final CallbackReceiver<RedeemedSMHistoryModel> mSMHistoryReceiver = new CallbackReceiver<RedeemedSMHistoryModel>() {
154 @Override 141 @Override
155 public void onSuccess(RedeemedSMHistoryModel result) { 142 public void onSuccess(RedeemedSMHistoryModel result) {
......
...@@ -14,26 +14,19 @@ import android.widget.Toast; ...@@ -14,26 +14,19 @@ import android.widget.Toast;
14 14
15 import androidx.annotation.NonNull; 15 import androidx.annotation.NonNull;
16 import androidx.fragment.app.Fragment; 16 import androidx.fragment.app.Fragment;
17 -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
18 17
19 import org.json.JSONObject; 18 import org.json.JSONObject;
20 19
21 -import java.util.ArrayList;
22 -
23 import ly.warp.sdk.R; 20 import ly.warp.sdk.R;
24 import ly.warp.sdk.activities.HomeActivity; 21 import ly.warp.sdk.activities.HomeActivity;
25 import ly.warp.sdk.db.WarplyDBHelper; 22 import ly.warp.sdk.db.WarplyDBHelper;
26 import ly.warp.sdk.io.callbacks.CallbackReceiver; 23 import ly.warp.sdk.io.callbacks.CallbackReceiver;
27 -import ly.warp.sdk.io.models.Campaign;
28 -import ly.warp.sdk.io.models.RedeemedSMHistoryModel;
29 import ly.warp.sdk.utils.WarplyManagerHelper; 24 import ly.warp.sdk.utils.WarplyManagerHelper;
30 import ly.warp.sdk.utils.managers.WarplyManager; 25 import ly.warp.sdk.utils.managers.WarplyManager;
31 26
32 -public class HomeFragment extends Fragment implements View.OnClickListener, SwipeRefreshLayout.OnRefreshListener { 27 +public class HomeFragment extends Fragment implements View.OnClickListener {
33 -
34 private RelativeLayout mOptionOne, mOptionTwo, mOptionThree, mPbLoading; 28 private RelativeLayout mOptionOne, mOptionTwo, mOptionThree, mPbLoading;
35 private TextView mTvUsername, mTvUser; 29 private TextView mTvUsername, mTvUser;
36 - private SwipeRefreshLayout mSwipeRefresh;
37 private EditText mEtGuid; 30 private EditText mEtGuid;
38 private LinearLayout mLlAuthLogin, mLlAuthLogout, mRlSmFlow, mRlSmMap; 31 private LinearLayout mLlAuthLogin, mLlAuthLogout, mRlSmFlow, mRlSmMap;
39 32
...@@ -45,8 +38,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip ...@@ -45,8 +38,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip
45 public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { 38 public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
46 super.onViewCreated(view, savedInstanceState); 39 super.onViewCreated(view, savedInstanceState);
47 40
48 - mSwipeRefresh = view.findViewById(R.id.sw_refresh);
49 - mSwipeRefresh.setOnRefreshListener(this);
50 mOptionOne = view.findViewById(R.id.info_button); 41 mOptionOne = view.findViewById(R.id.info_button);
51 TextView mOptionOneText = mOptionOne.findViewById(R.id.option_text); 42 TextView mOptionOneText = mOptionOne.findViewById(R.id.option_text);
52 ImageView mOptionOneImage = mOptionOne.findViewById(R.id.option_icon); 43 ImageView mOptionOneImage = mOptionOne.findViewById(R.id.option_icon);
...@@ -100,17 +91,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip ...@@ -100,17 +91,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip
100 } 91 }
101 92
102 @Override 93 @Override
103 - public void onRefresh() {
104 - if (WarplyDBHelper.getInstance(getActivity()).isTableNotEmpty("auth")) {
105 - WarplyManager.getSupermarketCampaign(mCampaignsCallback);
106 - WarplyManager.getRedeemedSMHistory(mSMHistoryReceiver);
107 - mSwipeRefresh.setRefreshing(false);
108 - } else {
109 - mSwipeRefresh.setRefreshing(false);
110 - }
111 - }
112 -
113 - @Override
114 public void onClick(View view) { 94 public void onClick(View view) {
115 if (view.getId() == R.id.ll_auth_login) { 95 if (view.getId() == R.id.ll_auth_login) {
116 //6012049321, 6012049322, 6012049323, 7000000831 history, 7000000826, 7000000831 shared coupons 96 //6012049321, 6012049322, 6012049323, 7000000831 history, 7000000826, 7000000831 shared coupons
...@@ -141,18 +121,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip ...@@ -141,18 +121,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip
141 return homeFragment; 121 return homeFragment;
142 } 122 }
143 123
144 - private final CallbackReceiver<ArrayList<Campaign>> mCampaignsCallback = new CallbackReceiver<ArrayList<Campaign>>() {
145 - @Override
146 - public void onSuccess(ArrayList<Campaign> result) {
147 - Toast.makeText(getActivity(), "Campaigns Success", Toast.LENGTH_SHORT).show();
148 - }
149 -
150 - @Override
151 - public void onFailure(int errorCode) {
152 - Toast.makeText(getActivity(), "Campaigns Error", Toast.LENGTH_SHORT).show();
153 - }
154 - };
155 -
156 private final CallbackReceiver<JSONObject> mLogoutReceiver = new CallbackReceiver<JSONObject>() { 124 private final CallbackReceiver<JSONObject> mLogoutReceiver = new CallbackReceiver<JSONObject>() {
157 @Override 125 @Override
158 public void onSuccess(JSONObject result) { 126 public void onSuccess(JSONObject result) {
...@@ -180,16 +148,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip ...@@ -180,16 +148,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip
180 mLlAuthLogout.setVisibility(View.VISIBLE); 148 mLlAuthLogout.setVisibility(View.VISIBLE);
181 mTvUser.setVisibility(View.VISIBLE); 149 mTvUser.setVisibility(View.VISIBLE);
182 mTvUser.setText(mEtGuid.getText().toString()); 150 mTvUser.setText(mEtGuid.getText().toString());
183 -// if (WarplyManagerHelper.getConsumerInternal() != null) {
184 -// JSONObject profMetadata = WarpJSONParser.getJSONFromString(WarplyManagerHelper.getConsumerInternal().getProfileMetadata());
185 -// if (profMetadata != null && profMetadata.has("guid")) {
186 -// String userGuid = profMetadata.optString("guid", "");
187 -// mTvUser.setText(userGuid);
188 -// }
189 -// }
190 -
191 - WarplyManager.getSupermarketCampaign(mCampaignsCallback);
192 - WarplyManager.getRedeemedSMHistory(mSMHistoryReceiver);
193 } 151 }
194 152
195 @Override 153 @Override
...@@ -198,16 +156,4 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip ...@@ -198,16 +156,4 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip
198 Toast.makeText(getActivity(), "LOGIN ERROR", Toast.LENGTH_SHORT).show(); 156 Toast.makeText(getActivity(), "LOGIN ERROR", Toast.LENGTH_SHORT).show();
199 } 157 }
200 }; 158 };
201 -
202 - private final CallbackReceiver<RedeemedSMHistoryModel> mSMHistoryReceiver = new CallbackReceiver<RedeemedSMHistoryModel>() {
203 - @Override
204 - public void onSuccess(RedeemedSMHistoryModel result) {
205 - Toast.makeText(getActivity(), "SM HISTORY SUCCESS", Toast.LENGTH_SHORT).show();
206 - }
207 -
208 - @Override
209 - public void onFailure(int errorCode) {
210 - Toast.makeText(getActivity(), "SM HISTORY ERROR", Toast.LENGTH_SHORT).show();
211 - }
212 - };
213 } 159 }
...\ No newline at end of file ...\ No newline at end of file
......
1 -/*
2 - * Copyright 2010-2013 Warply Ltd. All rights reserved.
3 - *
4 - * Redistribution and use in source and binary forms, without modification, are
5 - * permitted provided that the following conditions are met:
6 - *
7 - * 1. Redistributions of source code must retain the above copyright notice,
8 - * this list of conditions and the following disclaimer.
9 - *
10 - * 2. Redistributions in binary form must reproduce the above copyright notice,
11 - * this list of conditions and the following disclaimer in the documentation
12 - * and/or other materials provided with the distribution.
13 - *
14 - * THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
15 - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 - * EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20 - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 - */
25 -
26 -package ly.warp.sdk.io.models;
27 -
28 -import org.json.JSONArray;
29 -import org.json.JSONException;
30 -import org.json.JSONObject;
31 -
32 -import java.util.ArrayList;
33 -
34 -import ly.warp.sdk.utils.WarpUtils;
35 -import ly.warp.sdk.utils.constants.WarpConstants;
36 -
37 -/**
38 - * Created by Panagiotis Triantafyllou on 20-Jan-25.
39 - */
40 -
41 -public class MarketPassDetailsModel {
42 - private static final String BARCODE = "barcode";
43 - private static final String SUPERMARKETS = "supermarkets";
44 - private static final String TOTAL_DISCOUNT = "total_available_discount";
45 - private static final String NEW_OFFERS = "new_offers";
46 -
47 - private ArrayList<Supermarkets> supermarkets = new ArrayList<Supermarkets>();
48 - private String barcode = "";
49 - private double totalDiscount = 0.0d;
50 - private int newOffers = 0;
51 -
52 - public MarketPassDetailsModel() {
53 - this.supermarkets = new ArrayList<Supermarkets>();
54 - this.barcode = "";
55 - this.totalDiscount = 0.0d;
56 - this.newOffers = 0;
57 - }
58 -
59 - /**
60 - * Basic constructor used to create an object from a String, representing a
61 - * JSON Object
62 - *
63 - * @param json The String, representing the JSON Object
64 - * @throws JSONException Thrown if the String cannot be converted to JSON
65 - */
66 - public MarketPassDetailsModel(String json) throws JSONException {
67 - this(new JSONObject(json));
68 - }
69 -
70 - /**
71 - * Constructor used to create an Object from a given JSON Object
72 - *
73 - * @param json JSON Object used to create the Campaign
74 - */
75 - public MarketPassDetailsModel(JSONObject json) {
76 - if (json != null) {
77 - if (json.optJSONArray(SUPERMARKETS) != null) {
78 - JSONArray tempSupermarkets = json.optJSONArray(SUPERMARKETS);
79 - if (tempSupermarkets != null && tempSupermarkets.length() > 0) {
80 - for (int i = 0, lim = tempSupermarkets.length(); i < lim; ++i) {
81 - this.supermarkets.add(new Supermarkets(tempSupermarkets.optJSONObject(i)));
82 - }
83 - }
84 - }
85 - this.barcode = json.isNull(BARCODE) ? "" : json.optString(BARCODE);
86 - this.totalDiscount = json.optDouble(TOTAL_DISCOUNT);
87 - this.newOffers = json.optInt(NEW_OFFERS);
88 - }
89 - }
90 -
91 - /**
92 - * Converts the Campaign into a JSON Object
93 - *
94 - * @return The JSON Object created from this campaign
95 - */
96 - public JSONObject toJSONObject() {
97 - JSONObject jObj = new JSONObject();
98 - try {
99 - jObj.putOpt(BARCODE, this.barcode);
100 - jObj.putOpt(TOTAL_DISCOUNT, this.totalDiscount);
101 - jObj.putOpt(SUPERMARKETS, this.supermarkets);
102 - jObj.putOpt(NEW_OFFERS, this.newOffers);
103 - } catch (JSONException e) {
104 - if (WarpConstants.DEBUG) {
105 - e.printStackTrace();
106 - }
107 - }
108 - return jObj;
109 - }
110 -
111 - /**
112 - * String representation of the Campaign, as a JSON object
113 - *
114 - * @return A String representation of JSON object
115 - */
116 - public String toString() {
117 - if (toJSONObject() != null)
118 - return toJSONObject().toString();
119 - return null;
120 - }
121 -
122 - /**
123 - * String representation of the Campaign, as a human readable JSON object
124 - *
125 - * @return A human readable String representation of JSON object
126 - */
127 - public String toHumanReadableString() {
128 - String humanReadableString = null;
129 - try {
130 - humanReadableString = toJSONObject().toString(2);
131 - } catch (JSONException e) {
132 - WarpUtils.warn("Failed converting Campaign JSON object to String",
133 - e);
134 - }
135 - return humanReadableString;
136 - }
137 -
138 - public class Supermarkets {
139 - private static final String LOGO = "logo";
140 - private static final String NAME = "name";
141 - private static final String UUID = "uuid";
142 -
143 -
144 - private String logo = "";
145 - private String name = "";
146 - private String uuid = "";
147 -
148 - public Supermarkets() {
149 - this.logo = "";
150 - this.name = "";
151 - this.uuid = "";
152 - }
153 -
154 - public Supermarkets(JSONObject json) {
155 - if (json != null) {
156 - this.logo = json.isNull(LOGO) ? "" : json.optString(LOGO);
157 - this.name = json.isNull(NAME) ? "" : json.optString(NAME);
158 - this.uuid = json.isNull(UUID) ? "" : json.optString(UUID);
159 - }
160 - }
161 -
162 - public String getLogo() {
163 - return logo;
164 - }
165 -
166 - public void setLogo(String logo) {
167 - this.logo = logo;
168 - }
169 -
170 - public String getName() {
171 - return name;
172 - }
173 -
174 - public void setName(String name) {
175 - this.name = name;
176 - }
177 -
178 - public String getUuid() {
179 - return uuid;
180 - }
181 -
182 - public void setUuid(String uuid) {
183 - this.uuid = uuid;
184 - }
185 - }
186 -
187 - // ================================================================================
188 - // Getters
189 - // ================================================================================
190 -
191 -
192 - public ArrayList<Supermarkets> getSupermarkets() {
193 - return supermarkets;
194 - }
195 -
196 - public void setSupermarkets(ArrayList<Supermarkets> supermarkets) {
197 - this.supermarkets = supermarkets;
198 - }
199 -
200 - public String getBarcode() {
201 - return barcode;
202 - }
203 -
204 - public void setBarcode(String barcode) {
205 - this.barcode = barcode;
206 - }
207 -
208 - public double getTotalDiscount() {
209 - return totalDiscount;
210 - }
211 -
212 - public void setTotalDiscount(double totalDiscount) {
213 - this.totalDiscount = totalDiscount;
214 - }
215 -
216 - public int getNewOffers() {
217 - return newOffers;
218 - }
219 -
220 - public void setNewOffers(int newOffers) {
221 - this.newOffers = newOffers;
222 - }
223 -}
1 +package ly.warp.sdk.utils;
2 +
3 +import android.security.keystore.KeyGenParameterSpec;
4 +import android.security.keystore.KeyProperties;
5 +import android.util.Base64;
6 +import android.util.Log;
7 +
8 +import java.security.KeyStore;
9 +
10 +import javax.crypto.Cipher;
11 +import javax.crypto.KeyGenerator;
12 +import javax.crypto.SecretKey;
13 +import javax.crypto.spec.GCMParameterSpec;
14 +
15 +/**
16 + * Utility class for encrypting and decrypting sensitive data using Android Keystore
17 + */
18 +public class CryptoUtils {
19 +
20 + private static final String TAG = "CryptoUtils";
21 + private static final String TRANSFORMATION = "AES/GCM/NoPadding";
22 + private static final String ANDROID_KEYSTORE = "AndroidKeyStore";
23 + private static final String KEY_ALIAS = "tn#mpOl3v3Dy1pr@W";
24 + private static final int GCM_IV_LENGTH = 12;
25 + private static final int GCM_TAG_LENGTH = 16;
26 +
27 + /**
28 + * Encrypt a plain text string
29 + *
30 + * @param plainText The text to encrypt
31 + * @return Base64 encoded encrypted string, or original text if encryption fails
32 + */
33 + public static String encrypt(String plainText) {
34 + if (plainText == null || plainText.isEmpty()) {
35 + return plainText;
36 + }
37 +
38 + try {
39 + SecretKey secretKey = getOrCreateSecretKey();
40 + Cipher cipher = Cipher.getInstance(TRANSFORMATION);
41 + cipher.init(Cipher.ENCRYPT_MODE, secretKey);
42 +
43 + byte[] iv = cipher.getIV();
44 + byte[] encryptedData = cipher.doFinal(plainText.getBytes("UTF-8"));
45 +
46 + // Combine IV + encrypted data
47 + byte[] combined = new byte[iv.length + encryptedData.length];
48 + System.arraycopy(iv, 0, combined, 0, iv.length);
49 + System.arraycopy(encryptedData, 0, combined, iv.length, encryptedData.length);
50 +
51 + return Base64.encodeToString(combined, Base64.DEFAULT);
52 + } catch (Exception e) {
53 + Log.e(TAG, "Encryption failed, returning original text", e);
54 + // Return original text if encryption fails - graceful degradation
55 + return plainText;
56 + }
57 + }
58 +
59 + /**
60 + * Decrypt an encrypted string
61 + *
62 + * @param encryptedText The Base64 encoded encrypted text
63 + * @return Decrypted plain text, or original text if decryption fails
64 + */
65 + public static String decrypt(String encryptedText) {
66 + if (encryptedText == null || encryptedText.isEmpty()) {
67 + return encryptedText;
68 + }
69 +
70 + try {
71 + SecretKey secretKey = getOrCreateSecretKey();
72 + byte[] combined = Base64.decode(encryptedText, Base64.DEFAULT);
73 +
74 + // Extract IV and encrypted data
75 + byte[] iv = new byte[GCM_IV_LENGTH];
76 + byte[] encryptedData = new byte[combined.length - GCM_IV_LENGTH];
77 + System.arraycopy(combined, 0, iv, 0, GCM_IV_LENGTH);
78 + System.arraycopy(combined, GCM_IV_LENGTH, encryptedData, 0, encryptedData.length);
79 +
80 + Cipher cipher = Cipher.getInstance(TRANSFORMATION);
81 + GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
82 + cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);
83 +
84 + byte[] decryptedData = cipher.doFinal(encryptedData);
85 + return new String(decryptedData, "UTF-8");
86 + } catch (Exception e) {
87 + Log.e(TAG, "Decryption failed, returning original text", e);
88 + // Return original text if decryption fails - might be unencrypted legacy data
89 + return encryptedText;
90 + }
91 + }
92 +
93 + /**
94 + * Get or create the secret key in Android Keystore
95 + */
96 + private static SecretKey getOrCreateSecretKey() throws Exception {
97 + KeyStore keyStore = KeyStore.getInstance(ANDROID_KEYSTORE);
98 + keyStore.load(null);
99 +
100 + if (!keyStore.containsAlias(KEY_ALIAS)) {
101 + KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEYSTORE);
102 + KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(KEY_ALIAS,
103 + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
104 + .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
105 + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
106 + .setRandomizedEncryptionRequired(true)
107 + .build();
108 + keyGenerator.init(keyGenParameterSpec);
109 + keyGenerator.generateKey();
110 + }
111 +
112 + return ((KeyStore.SecretKeyEntry) keyStore.getEntry(KEY_ALIAS, null)).getSecretKey();
113 + }
114 +
115 + /**
116 + * Check if a string appears to be encrypted (Base64 format)
117 + *
118 + * @param text The text to check
119 + * @return true if text appears to be encrypted
120 + */
121 + public static boolean isEncrypted(String text) {
122 + if (text == null || text.isEmpty()) {
123 + return false;
124 + }
125 +
126 + try {
127 + byte[] decoded = Base64.decode(text, Base64.DEFAULT);
128 + // Check if decoded length is reasonable for encrypted data (IV + data + tag)
129 + return decoded.length > GCM_IV_LENGTH + GCM_TAG_LENGTH;
130 + } catch (Exception e) {
131 + return false;
132 + }
133 + }
134 +}
...@@ -30,7 +30,7 @@ public class WarpConstants { ...@@ -30,7 +30,7 @@ public class WarpConstants {
30 /** 30 /**
31 * The version of the SDK installed in the device 31 * The version of the SDK installed in the device
32 */ 32 */
33 - public static final String SDK_VERSION = "4.5.5.4"; 33 + public static final String SDK_VERSION = "4.5.5.5";
34 34
35 /** 35 /**
36 * The URL of the server where it should ping 36 * The URL of the server where it should ping
......
...@@ -568,8 +568,8 @@ public class WarpView extends WebView implements DefaultLifecycleObserver { ...@@ -568,8 +568,8 @@ public class WarpView extends WebView implements DefaultLifecycleObserver {
568 public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) { 568 public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
569 if (WarpActivity != null && !WarpActivity.isFinishing()) { 569 if (WarpActivity != null && !WarpActivity.isFinishing()) {
570 AlertDialog.Builder builder = new AlertDialog.Builder(WarpActivity); 570 AlertDialog.Builder builder = new AlertDialog.Builder(WarpActivity);
571 - builder.setTitle(getContext().getString(R.string.lbl_cosmote_webview_permission_title)); 571 + builder.setTitle(getContext().getString(R.string.webview_permission_title));
572 - builder.setMessage(getContext().getString(R.string.lbl_cosmote_webview_permission_message)) 572 + builder.setMessage(getContext().getString(R.string.webview_permission_message))
573 .setCancelable(false) 573 .setCancelable(false)
574 .setPositiveButton(getContext().getString(R.string.lbl_take_photo_accept), (dialog, id) -> checkForPermissions(origin, callback)) 574 .setPositiveButton(getContext().getString(R.string.lbl_take_photo_accept), (dialog, id) -> checkForPermissions(origin, callback))
575 .setNegativeButton(getContext().getString(R.string.lbl_take_photo_decline), (dialog, id) -> callback.invoke(origin, false, false)); 575 .setNegativeButton(getContext().getString(R.string.lbl_take_photo_decline), (dialog, id) -> callback.invoke(origin, false, false));
......
1 <?xml version="1.0" encoding="utf-8"?> 1 <?xml version="1.0" encoding="utf-8"?>
2 - 2 +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
3 -<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
4 xmlns:app="http://schemas.android.com/apk/res-auto" 3 xmlns:app="http://schemas.android.com/apk/res-auto"
5 xmlns:tools="http://schemas.android.com/tools" 4 xmlns:tools="http://schemas.android.com/tools"
6 - android:id="@+id/sw_refresh"
7 - android:layout_width="match_parent"
8 - android:layout_height="match_parent"
9 - android:background="@color/cos_skyblue2">
10 -
11 - <ScrollView
12 android:layout_width="match_parent" 5 android:layout_width="match_parent"
13 android:layout_height="match_parent" 6 android:layout_height="match_parent"
14 android:background="@color/cos_skyblue2"> 7 android:background="@color/cos_skyblue2">
...@@ -261,5 +254,4 @@ ...@@ -261,5 +254,4 @@
261 </RelativeLayout> 254 </RelativeLayout>
262 255
263 </RelativeLayout> 256 </RelativeLayout>
264 - </ScrollView> 257 +</ScrollView>
265 -</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
......
1 <resources> 1 <resources>
2 - <string name="lbl_cosmote_webview_permission_title">Demo App</string> 2 + <string name="webview_permission_title">Demo App</string>
3 - <string name="lbl_cosmote_webview_permission_message">Το Demo App ζητάει πρόσβαση στην τοποθεσία σας.</string> 3 + <string name="webview_permission_message">Το Demo App ζητάει πρόσβαση στην τοποθεσία σας.</string>
4 <string name="lbl_take_photo_accept">Οκ</string> 4 <string name="lbl_take_photo_accept">Οκ</string>
5 <string name="lbl_take_photo_decline">Άκυρο</string> 5 <string name="lbl_take_photo_decline">Άκυρο</string>
6 <string name="welcome_user">Γεια σου %1$s !</string> 6 <string name="welcome_user">Γεια σου %1$s !</string>
......