Complete shipper app

This commit is contained in:
Nezumi
2023-04-07 11:18:57 +07:00
parent 07aa4da787
commit 068b8bf98c
9 changed files with 107 additions and 181 deletions
@@ -50,9 +50,10 @@ public interface FoodApiToken {
@PUT("users/{userId}")
Call<User> updateUser(@Path("userId") int userId, @Body User user);
@GET("shippers/{shipperId}/orders")
Call<Orders> getListOrder(@Path("shipperId") int shipperId, @Query("pageNo") int pageNo, @Query("pageSize") int pageSize, @Query("sortBy") String sortBy, @Query("sortDir") String sortDir);
@GET("shippers/{shipperId}/orders/status")
Call<Orders> getListOrder(@Path("shipperId") int shipperId, @Query("status") String status ,@Query("pageNo") int pageNo, @Query("pageSize") int pageSize, @Query("sortBy") String sortBy, @Query("sortDir") String sortDir);
@PUT("users/{userId}/orders/{orderId}/status")
Call<CustomResponse> changeStatusOrder(@Path("userId") int userId, @Path("orderId") int orderId, @Query("status") String status);
}
@@ -1,50 +1,27 @@
package com.capstone.foodify.shipper.Activity;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.splashscreen.SplashScreen;
import androidx.viewpager2.widget.ViewPager2;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.viewpager2.widget.ViewPager2;
import com.capstone.foodify.shipper.BuildConfig;
import com.capstone.foodify.shipper.Common;
import com.capstone.foodify.shipper.R;
import com.capstone.foodify.shipper.ViewPagerAdapter;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
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.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.Priority;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;
@@ -55,22 +32,7 @@ public class MainActivity extends AppCompatActivity {
BottomNavigationView bottomNavigationView;
//Location
private static final int REQUEST_CHECK_SETTINGS = 100;
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
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 static final String TAG = MainActivity.class.getSimpleName();
private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingsClient;
private LocationRequest mLocationRequest;
private LocationSettingsRequest mLocationSettingsRequest;
private LocationCallback mLocationCallBack;
private Location mCurrentLocation;
private boolean mRequestingLocationUpdates = false;
private ConstraintLayout progressLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -80,14 +42,9 @@ public class MainActivity extends AppCompatActivity {
//Init Component
bottomNavigationView = findViewById(R.id.bottom_nav);
viewPager2 = findViewById(R.id.viewPager);
progressLayout = findViewById(R.id.progress_layout);
bottomNavigation();
if (Common.CURRENT_LOCATION == null) {
getLocation();
}
checkLocationPermission();
}
private void bottomNavigation() {
viewPagerAdapter = new ViewPagerAdapter(this);
@@ -128,44 +85,11 @@ public class MainActivity extends AppCompatActivity {
}
//Location
private void getLocation() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mSettingsClient = LocationServices.getSettingsClient(this);
mLocationCallBack = new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
mCurrentLocation = locationResult.getLastLocation();
Common.CURRENT_LOCATION = mCurrentLocation;
stopLocationUpdates();
progressLayout.setVisibility(View.GONE);
}
};
mLocationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, UPDATE_INTERVAL_IN_MILLISECONDS)
.setWaitForAccurateLocation(false)
.setMinUpdateDistanceMeters(FASTEST_UPDATE_IN_MILLISECONDS)
.setMaxUpdateDelayMillis(MAX_WAIT_TIME_IN_MILLISECONDS)
.build();
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.build();
checkLocationPermission();
}
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();
}
}
@@ -189,19 +113,22 @@ public class MainActivity extends AppCompatActivity {
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!")
builder.setMessage("Ứng dụng này cần quyền truy cập vị trí để hoạt động. Xin vui lòng cấp quyền cho ứng dụng!")
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
openSettings();
dialog.cancel();
finishAffinity();
System.exit(0);
}
})
.setNegativeButton("Để sau", new DialogInterface.OnClickListener() {
.setNegativeButton("Thoát", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
finishAffinity();
System.exit(0);
}
});
@@ -218,54 +145,10 @@ public class MainActivity extends AppCompatActivity {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
private void startLocationUpdates() {
mSettingsClient.checkLocationSettings(mLocationSettingsRequest).addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@SuppressLint("MissingPermission")
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallBack, Looper.myLooper());
}
}).addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "Location settings are not satisfied. Attempting to upgrade location settings");
try {
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sie) {
Log.i(TAG, "PendingIntent unable to execute request");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
String errorMessage = "Location settings are inadequate, and cannot be fixed here. Fix in Settings";
Log.e(TAG, errorMessage);
Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
}
}
});
}
private void stopLocationUpdates() {
mFusedLocationClient.removeLocationUpdates(mLocationCallBack).addOnCompleteListener(this, task -> Log.d(TAG, "Location updates stopped!"));
}
private boolean checkPermission() {
public boolean checkPermission() {
int permissionState = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
@Override
protected void onResume() {
super.onResume();
getLocation();
if (mRequestingLocationUpdates && checkPermission()) {
startLocationUpdates();
}
}
}
@@ -15,6 +15,7 @@ import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
@@ -72,9 +73,10 @@ import retrofit2.Response;
public class OrderDetailActivity extends AppCompatActivity {
private static final String TAG = "OrderDetailActivity";
private static final String STATUS = "COMPLETED";
private static final String COMPLETE_STATUS = "COMPLETED";
private static final String CANCEL_STATUS = "REJECT_DELIVERY";
Order order;
Button btn_shipping, btn_call, btn_confirm_ship_completed;
Button btn_shipping, btn_call, btn_confirm_ship_completed, btn_cancel_order;
TextView order_tracking_number, txt_user_name, txt_phone, txt_address, txt_distance, txt_status, txt_total,
txt_order_time;
ConstraintLayout progressLayout;
@@ -98,6 +100,7 @@ public class OrderDetailActivity extends AppCompatActivity {
private LocationCallback mLocationCallBack;
private Location mCurrentLocation;
private boolean mRequestingLocationUpdates = false;
private ImageView back_image;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -123,7 +126,7 @@ public class OrderDetailActivity extends AppCompatActivity {
initData();
getDistanceAndCalculateShipCost(order.getAddress());
progressLayout.setVisibility(View.GONE);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
@@ -132,6 +135,13 @@ public class OrderDetailActivity extends AppCompatActivity {
adapter.setData(order.getOrderDetails());
rcv_list_order.setAdapter(adapter);
back_image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(OrderDetailActivity.this, MainActivity.class));
finish();
}
});
btn_shipping.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -160,7 +170,14 @@ public class OrderDetailActivity extends AppCompatActivity {
btn_confirm_ship_completed.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
changeOrderStatus();
changeOrderStatus(COMPLETE_STATUS);
}
});
btn_cancel_order.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
changeOrderStatus(CANCEL_STATUS);
}
});
@@ -172,8 +189,8 @@ public class OrderDetailActivity extends AppCompatActivity {
getLocation();
}
private void changeOrderStatus(){
FoodApiToken.apiService.changeStatusOrder(order.getUser().getId(), order.getId(), STATUS).enqueue(new Callback<CustomResponse>() {
private void changeOrderStatus(String status){
FoodApiToken.apiService.changeStatusOrder(order.getUser().getId(), order.getId(), status).enqueue(new Callback<CustomResponse>() {
@Override
public void onResponse(Call<CustomResponse> call, Response<CustomResponse> response) {
if(response.code() == 200){
@@ -194,7 +211,7 @@ public class OrderDetailActivity extends AppCompatActivity {
@Override
public void onFailure(Call<CustomResponse> call, Throwable t) {
Toast.makeText(OrderDetailActivity.this, Common.ERROR_CONNECT_SERVER, Toast.LENGTH_SHORT).show();
}
});
}
@@ -204,6 +221,7 @@ public class OrderDetailActivity extends AppCompatActivity {
btn_shipping = findViewById(R.id.btn_shipping);
btn_call = findViewById(R.id.btn_call);
btn_confirm_ship_completed = findViewById(R.id.btn_confirm_ship_complete);
btn_cancel_order = findViewById(R.id.btn_cancel_order);
txt_address = findViewById(R.id.txt_address);
order_tracking_number = findViewById(R.id.order_tracking_number);
@@ -219,6 +237,8 @@ public class OrderDetailActivity extends AppCompatActivity {
layoutConfirmOrder = findViewById(R.id.layout1);
progressLayout = findViewById(R.id.progress_layout);
back_image = findViewById(R.id.back_image);
}
private void initData(){
@@ -358,6 +378,9 @@ public class OrderDetailActivity extends AppCompatActivity {
mCurrentLocation = locationResult.getLastLocation();
Common.CURRENT_LOCATION = mCurrentLocation;
getDistanceAndCalculateShipCost(order.getAddress());
double lat1 = mCurrentLocation.getLatitude();
double lng1 = mCurrentLocation.getLongitude();
double lat2 = order.getLat();
@@ -11,10 +11,15 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.capstone.foodify.shipper.Activity.MainActivity;
import com.capstone.foodify.shipper.Activity.OrderDetailActivity;
import com.capstone.foodify.shipper.Common;
import com.capstone.foodify.shipper.Model.Order;
import com.capstone.foodify.shipper.R;
import com.thecode.aestheticdialogs.AestheticDialog;
import com.thecode.aestheticdialogs.DialogStyle;
import com.thecode.aestheticdialogs.DialogType;
import com.thecode.aestheticdialogs.OnDialogClickListener;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@@ -57,9 +62,26 @@ public class OrderAdapter extends RecyclerView.Adapter<OrderAdapter.OrderViewHol
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(activity, OrderDetailActivity.class);
intent.putExtra("order", order);
activity.startActivity(intent);
if(activity instanceof MainActivity){
if(((MainActivity)activity).checkPermission()){
Intent intent = new Intent(activity, OrderDetailActivity.class);
intent.putExtra("order", order);
activity.startActivity(intent);
} else {
new AestheticDialog.Builder(activity, DialogStyle.TOASTER, DialogType.WARNING)
.setTitle("THÔNG BÁO!")
.setMessage("Bạn cần cấp quyền vị trí cho ứng dụng để có thể tiếp tục!")
.setCancelable(false)
.setOnClickListener(new OnDialogClickListener() {
@Override
public void onClick(@NonNull AestheticDialog.Builder builder) {
builder.dismiss();
}
}).show();
}
}
}
});
}
@@ -80,16 +80,13 @@ public class CompletedOrder extends Fragment {
private void getListOrder(){
if(Common.CURRENT_SHIPPER != null){
FoodApiToken.apiService.getListOrder(Common.CURRENT_SHIPPER.getId(), CURRENT_PAGE++, PAGE_SIZE, SORT_BY, SORT_DIR).enqueue(new Callback<Orders>() {
FoodApiToken.apiService.getListOrder(Common.CURRENT_SHIPPER.getId(), "COMPLETED", CURRENT_PAGE++, PAGE_SIZE, SORT_BY, SORT_DIR).enqueue(new Callback<Orders>() {
@Override
public void onResponse(Call<Orders> call, Response<Orders> response) {
if(response.code() == 200){
for(Order tempOrder: response.body().getOrders()){
if(tempOrder.getStatus().equals("COMPLETED")){
listOrders.add(tempOrder);
}
}
listOrders.addAll(response.body().getOrders());
orderAdapter.setData(listOrders);
LAST_PAGE = response.body().getPage().isLast();
@@ -80,16 +80,13 @@ public class ShippingOrder extends Fragment {
private void getListOrder(){
if(Common.CURRENT_SHIPPER != null){
FoodApiToken.apiService.getListOrder(Common.CURRENT_SHIPPER.getId(), CURRENT_PAGE++, PAGE_SIZE, SORT_BY, SORT_DIR).enqueue(new Callback<Orders>() {
FoodApiToken.apiService.getListOrder(Common.CURRENT_SHIPPER.getId(), "SHIPPING", CURRENT_PAGE++, PAGE_SIZE, SORT_BY, SORT_DIR).enqueue(new Callback<Orders>() {
@Override
public void onResponse(Call<Orders> call, Response<Orders> response) {
if(response.code() == 200){
for(Order tempOrder: response.body().getOrders()){
if(tempOrder.getStatus().equals("SHIPPING")){
listOrders.add(tempOrder);
}
}
listOrders.addAll(response.body().getOrders());
orderAdapter.setData(listOrders);
LAST_PAGE = response.body().getPage().isLast();
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>
</vector>
-21
View File
@@ -32,25 +32,4 @@
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000"
android:id="@+id/progress_layout"
android:visibility="visible"
>
<ProgressBar
android:id="@+id/progressBarLoadData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="@color/primaryColor"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -64,7 +64,7 @@
<TextView
android:id="@+id/textView2"
android:text="Thông tin người giao"
android:text="Thông tin người nhận"
android:layout_marginTop="10dp"
android:layout_marginStart="10dp"
android:fontFamily="@font/bebas"
@@ -258,7 +258,7 @@
<TextView
android:id="@+id/txt_distance"
android:text="10 km"
android:text="- km"
android:fontFamily="@font/opensans"
android:textStyle="bold"
android:layout_marginTop="5dp"
@@ -362,6 +362,7 @@
app:layout_constraintEnd_toEndOf="parent"
android:drawableLeft="@drawable/baseline_local_shipping_24"
android:drawableTint="@color/white"
android:visibility="gone"
/>
<LinearLayout
@@ -373,7 +374,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="20dp"
android:visibility="gone"
android:visibility="visible"
>
@@ -412,6 +413,24 @@
android:drawableLeft="@drawable/baseline_verified_24"
android:drawableTint="@color/white"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_cancel_order"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:backgroundTint="@color/red"
android:layout_marginTop="10dp"
android:layout_gravity="center"
android:fontFamily="@font/opensans"
android:gravity="center"
android:textStyle="bold"
android:text="Không giao được"
android:textAllCaps="false"
android:textColor="@color/white"
app:iconGravity="textStart"
android:drawableLeft="@drawable/baseline_cancel_24"
android:drawableTint="@color/white"/>
</LinearLayout>