Get location realtime shipper app

This commit is contained in:
Nezumi
2023-04-07 21:18:37 +07:00
parent 068b8bf98c
commit c91b8b6c73
8 changed files with 229 additions and 116 deletions
+6 -1
View File
@@ -8,10 +8,10 @@
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
@@ -28,6 +28,11 @@
</intent-filter>
</receiver>
<service android:name=".LocationService"
android:enabled="true"
android:exported="false"
/>
<activity
android:name=".Activity.AccountAndProfileActivity"
android:exported="false" />
@@ -45,6 +45,7 @@ public class MainActivity extends AppCompatActivity {
bottomNavigation();
checkLocationPermission();
checkBackgroundLocationPermission();
}
private void bottomNavigation() {
viewPagerAdapter = new ViewPagerAdapter(this);
@@ -92,24 +93,39 @@ public class MainActivity extends AppCompatActivity {
requestForPermission();
}
}
private void checkBackgroundLocationPermission(){
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Vui lòng cho phép ứng dụng truy cập vị mọi lúc để hoạt động tốt nhất!")
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
openSettings();
finishAffinity();
System.exit(0);
}
})
.setNegativeButton("Thoát", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
finishAffinity();
System.exit(0);
}
});
AlertDialog alertDialog = builder.create();
alertDialog.setTitle("Thông báo!");
alertDialog.show();
}
}
private void requestForPermission() {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == LOCATION_REQUEST_CODE){
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "Đã cấp quyền thành công!", Toast.LENGTH_SHORT).show();
} else {
showDialogPermission();
}
}
}
private void showDialogPermission() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
@@ -1,8 +1,18 @@
package com.capstone.foodify.shipper.Activity;
import static com.capstone.foodify.shipper.Common.ACTION_START_LOCATION_SERVICE;
import static com.capstone.foodify.shipper.Common.ACTION_STOP_LOCATION_SERVICE;
import static com.capstone.foodify.shipper.Common.FASTEST_UPDATE_IN_MILLISECONDS;
import static com.capstone.foodify.shipper.Common.LOCATION_REQUEST_CODE;
import static com.capstone.foodify.shipper.Common.MAX_WAIT_TIME_IN_MILLISECONDS;
import static com.capstone.foodify.shipper.Common.REQUEST_CHECK_SETTINGS;
import static com.capstone.foodify.shipper.Common.UPDATE_INTERVAL_IN_MILLISECONDS;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
@@ -35,6 +45,7 @@ import com.capstone.foodify.shipper.Adapter.OrderDetailAdapter;
import com.capstone.foodify.shipper.BuildConfig;
import com.capstone.foodify.shipper.Common;
import com.capstone.foodify.shipper.GoogleMap.GeofenceHelper;
import com.capstone.foodify.shipper.LocationService;
import com.capstone.foodify.shipper.Model.CustomResponse;
import com.capstone.foodify.shipper.Model.GoogleMap.GoogleMapResponse;
import com.capstone.foodify.shipper.Model.Order;
@@ -88,11 +99,6 @@ public class OrderDetailActivity extends AppCompatActivity {
private float GEOFENCE_RADIUS = 150;
private String GEOFENCE_ID = "SOME_GEOFENCE_ID";
//Location
private static final int REQUEST_CHECK_SETTINGS = 100;
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
private static final long FASTEST_UPDATE_IN_MILLISECONDS = 3000;
private static final long MAX_WAIT_TIME_IN_MILLISECONDS = 1000;
private static final int LOCATION_REQUEST_CODE = 100;
private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingClient;
private LocationRequest mLocationRequest;
@@ -126,9 +132,6 @@ public class OrderDetailActivity extends AppCompatActivity {
initData();
progressLayout.setVisibility(View.GONE);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
rcv_list_order.setLayoutManager(linearLayoutManager);
@@ -151,6 +154,8 @@ public class OrderDetailActivity extends AppCompatActivity {
Common.CURRENT_ORDER = order;
startLocationService();
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("google.navigation:q=" + order.getLat() + "," + order.getLng() + "&mode=l"));
intent.setPackage("com.google.android.apps.maps");
@@ -171,6 +176,7 @@ public class OrderDetailActivity extends AppCompatActivity {
@Override
public void onClick(View view) {
changeOrderStatus(COMPLETE_STATUS);
stopLocationService();
}
});
@@ -338,10 +344,9 @@ public class OrderDetailActivity extends AppCompatActivity {
* Math.sin(dLon / 2);
double c = 2 * Math.asin(Math.sqrt(a));
double valueResult = Radius * c;
double km = valueResult / 1;
DecimalFormat newFormat = new DecimalFormat("####");
return Integer.valueOf(newFormat.format(km));
return Integer.parseInt(newFormat.format(valueResult));
}
/** calculates the distance between two locations in MILES */
@@ -367,6 +372,39 @@ public class OrderDetailActivity extends AppCompatActivity {
//Location
@SuppressWarnings("deprecation")
private boolean isLocationServiceRunning(){
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
if(activityManager != null){
for(ActivityManager.RunningServiceInfo service:
activityManager.getRunningServices(Integer.MAX_VALUE)){
if(LocationService.class.getName().equals(service.service.getClassName())){
if(service.foreground){
return true;
}
}
}
return false;
}
return false;
}
private void startLocationService(){
if(!isLocationServiceRunning()){
Intent intent = new Intent(getApplicationContext(), LocationService.class);
intent.setAction(ACTION_START_LOCATION_SERVICE);
startService(intent);
}
}
private void stopLocationService(){
if(isLocationServiceRunning()){
Intent intent = new Intent(getApplicationContext(), LocationService.class);
intent.setAction(ACTION_STOP_LOCATION_SERVICE);
startService(intent);
}
}
private void getLocation() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mSettingClient = LocationServices.getSettingsClient(this);
@@ -376,31 +414,21 @@ public class OrderDetailActivity extends AppCompatActivity {
public void onLocationResult(@NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
stopLocationUpdates();
mCurrentLocation = locationResult.getLastLocation();
Common.CURRENT_LOCATION = mCurrentLocation;
getDistanceAndCalculateShipCost(order.getAddress());
double lat1 = mCurrentLocation.getLatitude();
double lng1 = mCurrentLocation.getLongitude();
double lat2 = order.getLat();
double lng2 = order.getLng();
if(distance(lat1, lng1, lat2, lng2) < 0.2){
btn_shipping.setVisibility(View.GONE);
layoutConfirmOrder.setVisibility(View.VISIBLE);
} else {
btn_shipping.setVisibility(View.VISIBLE);
layoutConfirmOrder.setVisibility(View.GONE);
}
changeLayoutButton(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
progressLayout.setVisibility(View.GONE);
}
};
mLocationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, UPDATE_INTERVAL_IN_MILLISECONDS)
mLocationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 4000)
.setWaitForAccurateLocation(false)
.setMinUpdateDistanceMeters(FASTEST_UPDATE_IN_MILLISECONDS)
.setMinUpdateIntervalMillis(2000)
.setMaxUpdateDelayMillis(MAX_WAIT_TIME_IN_MILLISECONDS)
.build();
@@ -408,71 +436,19 @@ public class OrderDetailActivity extends AppCompatActivity {
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.build();
checkLocationPermission();
startLocationUpdates();
}
private void checkLocationPermission(){
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){
requestForPermission();
}else {
//Get location
mRequestingLocationUpdates = true;
startLocationUpdates();
private void changeLayoutButton(double lat1, double lng1) {
if(distance(lat1, lng1, order.getLat(), order.getLng()) < 0.2){
btn_shipping.setVisibility(View.GONE);
layoutConfirmOrder.setVisibility(View.VISIBLE);
} else {
btn_shipping.setVisibility(View.VISIBLE);
layoutConfirmOrder.setVisibility(View.GONE);
}
}
private void requestForPermission() {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == LOCATION_REQUEST_CODE){
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "Đã cấp quyền thành công!", Toast.LENGTH_SHORT).show();
} else {
showDialogPermission();
}
}
}
private void showDialogPermission() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Hãy cho ứng dụng truy cập vào vị trí của bạn để trải nghiệm tốt hơn!")
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
openSettings();
dialog.cancel();
}
})
.setNegativeButton("Để sau", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.setTitle("Thông báo!");
alertDialog.show();
}
private void openSettings(){
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
private void startLocationUpdates(){
mSettingClient.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@@ -511,25 +487,12 @@ public class OrderDetailActivity extends AppCompatActivity {
mFusedLocationClient.removeLocationUpdates(mLocationCallBack).addOnCompleteListener(this, task -> Log.d(TAG, "Location stop update!"));
}
private boolean checkPermissions(){
int permissionState = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
@Override
protected void onResume() {
super.onResume();
progressLayout.setVisibility(View.VISIBLE);
if(mRequestingLocationUpdates && checkPermissions()){
startLocationUpdates();
}
}
@Override
protected void onPause() {
super.onPause();
if(mRequestingLocationUpdates){
stopLocationUpdates();
if(Common.CURRENT_LOCATION != null){
changeLayoutButton(Common.CURRENT_LOCATION.getLatitude(), Common.CURRENT_LOCATION.getLongitude());
}
}
}
@@ -35,7 +35,14 @@ public class Common {
public static final String ERROR_CONNECT_SERVER = "Đã có lỗi kết nối đến hệ thống!";
public static final List<Order> LIST_ORDER = new ArrayList<>();
public static final String SHIPPING_COMPLETED = "1";
public static final int REQUEST_CHECK_SETTINGS = 100;
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
public static final long FASTEST_UPDATE_IN_MILLISECONDS = 3000;
public static final long MAX_WAIT_TIME_IN_MILLISECONDS = 1000;
public static final int LOCATION_REQUEST_CODE = 100;
public static final int LOCATION_SERVICE_ID = 175;
public static final String ACTION_START_LOCATION_SERVICE = "startLocationService";
public static final String ACTION_STOP_LOCATION_SERVICE = "stopLocationService";
public static Typeface setFontBebas(AssetManager assetManager){
return Typeface.createFromAsset(assetManager, "font/bebas.ttf");
}
@@ -56,6 +56,7 @@ public class CompletedOrder extends Fragment {
orderAdapter = new OrderAdapter(getActivity());
CURRENT_PAGE = 0;
getListOrder();
@@ -56,6 +56,7 @@ public class ShippingOrder extends Fragment {
orderAdapter = new OrderAdapter(getActivity());
CURRENT_PAGE = 0;
getListOrder();
@@ -5,6 +5,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.net.Uri;
import android.util.Log;
import android.widget.Toast;
@@ -14,13 +15,14 @@ import com.capstone.foodify.shipper.Common;
import com.capstone.foodify.shipper.Model.Order;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingEvent;
import com.google.android.gms.location.LocationResult;
import java.util.List;
public class GeofenceBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "GeofenceBroadcastReceive";
public static final String ACTION_PROCESS_UPDATE = "com.capstone.foodify.shipper.GoogleMap.UPDATE_LOCATION";
@Override
public void onReceive(Context context, Intent intent) {
@@ -0,0 +1,118 @@
package com.capstone.foodify.shipper;
import static com.capstone.foodify.shipper.Common.ACTION_START_LOCATION_SERVICE;
import static com.capstone.foodify.shipper.Common.ACTION_STOP_LOCATION_SERVICE;
import static com.capstone.foodify.shipper.Common.FASTEST_UPDATE_IN_MILLISECONDS;
import static com.capstone.foodify.shipper.Common.LOCATION_SERVICE_ID;
import static com.capstone.foodify.shipper.Common.MAX_WAIT_TIME_IN_MILLISECONDS;
import static com.capstone.foodify.shipper.Common.UPDATE_INTERVAL_IN_MILLISECONDS;
import android.Manifest;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.Priority;
public class LocationService extends Service {
private static final String TAG = "LocationService";
private final LocationCallback locationCallback = new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
if(locationResult.getLastLocation() != null){
double lat = locationResult.getLastLocation().getLatitude();
double lng = locationResult.getLastLocation().getLongitude();
Log.d(TAG, lat + ", " + lng);
Common.CURRENT_LOCATION = locationResult.getLastLocation();
}
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void startLocationService() {
String channelId = "location_notification_channel";
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent resultIntent = new Intent();
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), channelId);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("Foodify Shipper");
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
builder.setContentText("Ứng dụng đang lấy vị trí của bạn!");
builder.setContentIntent(pendingIntent);
builder.setAutoCancel(false);
builder.setPriority(NotificationCompat.PRIORITY_MAX);
if (notificationManager != null && notificationManager.getNotificationChannel(channelId) == null) {
NotificationChannel notificationChannel = new NotificationChannel(
channelId,
"Location Service",
NotificationManager.IMPORTANCE_HIGH
);
notificationChannel.setDescription("This channel is used by location service");
notificationManager.createNotificationChannel(notificationChannel);
}
LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 4000)
.setWaitForAccurateLocation(false)
.setMinUpdateIntervalMillis(5000)
.setMaxUpdateDelayMillis(MAX_WAIT_TIME_IN_MILLISECONDS)
.build();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.getFusedLocationProviderClient(this)
.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
startForeground(LOCATION_SERVICE_ID, builder.build());
}
private void stopLocationService(){
LocationServices.getFusedLocationProviderClient(this)
.removeLocationUpdates(locationCallback);
stopForeground(true);
stopSelf();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent != null){
String action = intent.getAction();
if(action != null){
if(action.equals(ACTION_START_LOCATION_SERVICE)){
startLocationService();
} else if(action.equals(ACTION_STOP_LOCATION_SERVICE)){
stopLocationService();
}
}
}
return super.onStartCommand(intent, flags, startId);
}
}