Skip to content

Commit

Permalink
Merge pull request #374 from skedgo/feature/18384
Browse files Browse the repository at this point in the history
  • Loading branch information
lenganngoh authored Jan 12, 2023
2 parents dbf0048 + 592709d commit 05b3f63
Show file tree
Hide file tree
Showing 13 changed files with 557 additions and 96 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.skedgo.tripkit.routing

data class Geofence(
val id: String,
val type: String,
val trigger: String,
val center: Coordinate,
val radius: Double,
val messageType: String,
val messageTitle: String,
val messageBody: String
) {
var timeline: Long = -1L

fun computeAndSetTimeline(tripEndDateTimeInMillis: Long): Long {
val currentTimeInMillis = System.currentTimeMillis()
return tripEndDateTimeInMillis - currentTimeInMillis
}
}

data class Coordinate(
val lat: Double,
val lng: Double
)

enum class Trigger(val value: String) {
ENTER("ENTER"), EXIT("EXIT")
}

enum class MessageType {
TRIP_END, ARRIVING_AT_YOUR_STOP, NEXT_STOP_IS_YOURS
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.skedgo.tripkit.routing

import android.content.Context
import android.content.SharedPreferences

object GetOffAlertCache {

private const val PREF_KEY = "KEY_GET_OFF_ALERTS"
private lateinit var sharedPreferences: SharedPreferences

fun init(context: Context) {
sharedPreferences = context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE)
}

fun setTripAlertOnState(tripUuid: String, onState: Boolean) {
if (onState) {
//As per adrian, only one trip can have alerts on, so will need to clear first to make sure no other trips has alerts on
sharedPreferences.edit().apply {
clear()
putBoolean(tripUuid, onState).apply()
}.apply()
//sharedPreferences.edit().putBoolean(tripUuid, onState).apply()
} else {
sharedPreferences.edit().remove(tripUuid).apply()
}
}

fun isTripAlertStateOn(tripUuid: String): Boolean = sharedPreferences.getBoolean(tripUuid, false)

}
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ public class TripSegment implements IRealTimeElement, ITimeRange {
private long mEndTimeInSecs;

private boolean hideExactTimes;
@Nullable
private List<Geofence> geofences;

/**
* This is no longer a part of json returned from server due to Version 6.
Expand Down Expand Up @@ -860,4 +862,11 @@ public boolean isHideExactTimes() {
public void setHideExactTimes(boolean hideExactTimes) {
this.hideExactTimes = hideExactTimes;
}

@Nullable
public List<Geofence> getGeofences() { return geofences; }

public void setGeofences(List<Geofence> geofences) {
this.geofences = geofences;
}
}
5 changes: 5 additions & 0 deletions CommonCoreLegacy/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@
<string name="str_hr">hrs</string>
<string name="str_hrs">hrs</string>
<string name="direction">Direction</string>

<string name="geofence_not_available">Geofence service is not available now</string>
<string name="geofence_too_many_geofences">Your app has registered too many geofences</string>
<string name="geofence_too_many_pending_intents">You have provided too many PendingIntents to the addGeofences() call</string>
<string name="unknown_geofence_error">Unknown error: the Geofence service is not available now</string>
</resources>
6 changes: 6 additions & 0 deletions TripKitAndroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ dependencies {
implementation libs.immutablesGson
implementation libs.networkResponse

implementation libs.playServicesMaps
implementation libs.map_utils
implementation libs.map_utils_ktx
implementation libs.map_extension
implementation libs.location

api project(':CommonCoreLegacy')
api project(':TripKitDomain')
api project(':TripKitDomainLegacy')
Expand Down
56 changes: 37 additions & 19 deletions TripKitAndroid/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
<manifest package="com.skedgo.tripkit"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.skedgo.tripkit">

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

<application>
<receiver
android:name=".routing.TripAlarmBroadcastReceiver"
android:enabled="true"
android:exported="true"></receiver>

<service
android:name=".android.FetchRegionsService"
android:exported="false">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
</intent-filter>
</service>

<receiver
android:name=".routing.GeofenceBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.skedgo.tripkit.routing.GeofenceBroadcastReceiver.ACTION_GEOFENCE_EVENT" />
</intent-filter>
</receiver>
</application>

<application>
<service
android:name="com.skedgo.tripkit.android.FetchRegionsService"
android:exported="false">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
</intent-filter>
</service>
</application>
</manifest>
181 changes: 110 additions & 71 deletions TripKitAndroid/src/main/java/com/skedgo/TripKit.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.skedgo;

import android.app.NotificationChannel;
import android.content.Context;
import android.os.Build;

import androidx.annotation.NonNull;

import com.skedgo.tripkit.Configs;
Expand All @@ -10,101 +13,137 @@
import com.skedgo.tripkit.data.regions.RegionService;
import com.skedgo.tripkit.TripUpdater;
import com.skedgo.tripkit.bookingproviders.BookingResolver;

import io.reactivex.functions.Consumer;

import com.skedgo.tripkit.a2brouting.A2bRoutingDataModule;
import com.skedgo.tripkit.notification.NotificationKt;
import com.skedgo.tripkit.routing.GeoLocation;
import com.skedgo.tripkit.routing.GetOffAlertCache;
import com.skedgo.tripkit.tsp.TspModule;

import javax.inject.Singleton;

import dagger.Component;

import com.skedgo.tripkit.a2brouting.RouteService;
import com.skedgo.tripkit.android.A2bRoutingComponent;
import com.skedgo.tripkit.android.AnalyticsComponent;
import com.skedgo.tripkit.android.DateTimeComponent;
import com.skedgo.tripkit.android.FetchRegionsService;

import net.danlew.android.joda.JodaTimeAndroid;

import java.util.ArrayList;
import java.util.List;

import static com.skedgo.tripkit.routing.TripAlarmBroadcastReceiver.NOTIFICATION_CHANNEL_START_TRIP;
import static com.skedgo.tripkit.routing.TripAlarmBroadcastReceiver.NOTIFICATION_CHANNEL_START_TRIP_ID;

@Singleton
@Component(modules = {
HttpClientModule.class,
A2bRoutingDataModule.class,
TspModule.class,
MainModule.class
HttpClientModule.class,
A2bRoutingDataModule.class,
TspModule.class,
MainModule.class
})
public abstract class TripKit {
private static TripKit instance;
private static TripKit instance;

public static TripKit getInstance() {
synchronized (TripKit.class) {
if (instance == null) {
throw new IllegalStateException("Must initialize TripKit before using getInstance()");
}
public static TripKit getInstance() {
synchronized (TripKit.class) {
if (instance == null) {
throw new IllegalStateException("Must initialize TripKit before using getInstance()");
}

return instance;
return instance;
}
}
}

/**
* This gives a chance to provide a custom {@link TripKit}.
* One idea is that we can create {@link DaggerTripKit}
* w/ some customized modules.
* <p>
* Note that you should only use this
* when you totally understand what you're doing.
* Otherwise, just go with {@link #initialize(Configs)} instead.
*
* @param context A {@link Context} to launch {@link FetchRegionsService}.
* @param tripKit Can be created via {@link DaggerTripKit}.
*/
public static void initialize(@NonNull Context context, @NonNull TripKit tripKit) {
synchronized (TripKit.class) {
if (instance == null) {
instance = tripKit;
}
FetchRegionsService.Companion.scheduleAsync(context)
.subscribe(unused -> {}, instance.getErrorHandler());

/**
* This gives a chance to provide a custom {@link TripKit}.
* One idea is that we can create {@link DaggerTripKit}
* w/ some customized modules.
* <p>
* Note that you should only use this
* when you totally understand what you're doing.
* Otherwise, just go with {@link #initialize(Configs)} instead.
*
* @param context A {@link Context} to launch {@link FetchRegionsService}.
* @param tripKit Can be created via {@link DaggerTripKit}.
*/
public static void initialize(@NonNull Context context, @NonNull TripKit tripKit) {
synchronized (TripKit.class) {
if (instance == null) {
instance = tripKit;
}
FetchRegionsService.Companion.scheduleAsync(context)
.subscribe(unused -> {
}, instance.getErrorHandler());
}
}
}

public static boolean isInitialized() {
return (instance != null);
}

public static void initialize(Configs configs) {
synchronized (TripKit.class) {
if (configs == null) {
throw new IllegalStateException("Must initialize Configs before using initialize()");
}

if (instance == null) {
instance = DaggerTripKit.builder()
.mainModule(new MainModule(configs))
.httpClientModule(new HttpClientModule(
null,
null,
configs,
null
))
.build();
JodaTimeAndroid.init(configs.context());
}

FetchRegionsService.Companion.scheduleAsync(configs.context())
.subscribe(unused -> {}, instance.getErrorHandler());

public static boolean isInitialized() {
return (instance != null);
}
}

public abstract Configs configs();
public abstract RegionService getRegionService();
public abstract RouteService getRouteService();
public abstract okhttp3.OkHttpClient getOkHttpClient3();
public abstract BookingResolver getBookingResolver();
public abstract LocationInfoService getLocationInfoService();
public abstract TripUpdater getTripUpdater();
public static void initialize(Configs configs) {
synchronized (TripKit.class) {
if (configs == null) {
throw new IllegalStateException("Must initialize Configs before using initialize()");
}

if (instance == null) {
instance = DaggerTripKit.builder()
.mainModule(new MainModule(configs))
.httpClientModule(new HttpClientModule(
null,
null,
configs,
null
))
.build();
JodaTimeAndroid.init(configs.context());
GetOffAlertCache.INSTANCE.init(configs.context());
GeoLocation.INSTANCE.init(configs.context());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
List<NotificationChannel> channels = new ArrayList<>();
channels.add(NotificationKt.createChannel(
NOTIFICATION_CHANNEL_START_TRIP_ID,
NOTIFICATION_CHANNEL_START_TRIP)
);
NotificationKt.createNotificationChannels(
configs.context(),
channels
);
}
}

FetchRegionsService.Companion.scheduleAsync(configs.context())
.subscribe(unused -> {
}, instance.getErrorHandler());
}
}

public abstract Configs configs();

public abstract RegionService getRegionService();

public abstract RouteService getRouteService();

public abstract okhttp3.OkHttpClient getOkHttpClient3();

public abstract BookingResolver getBookingResolver();

public abstract LocationInfoService getLocationInfoService();

public abstract TripUpdater getTripUpdater();

public abstract A2bRoutingComponent a2bRoutingComponent();

public abstract AnalyticsComponent analyticsComponent();

public abstract A2bRoutingComponent a2bRoutingComponent();
public abstract AnalyticsComponent analyticsComponent();
public abstract DateTimeComponent dateTimeComponent();
public abstract DateTimeComponent dateTimeComponent();

public abstract Consumer<Throwable> getErrorHandler();
public abstract Consumer<Throwable> getErrorHandler();
}
Loading

0 comments on commit 05b3f63

Please sign in to comment.