diff --git a/.kotlin/sessions/kotlin-compiler-9493137895889385779.salive b/.kotlin/sessions/kotlin-compiler-9493137895889385779.salive new file mode 100644 index 0000000..e69de29 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bc74493..04ff517 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -61,6 +61,11 @@ dependencies { implementation(libs.androidx.swiperefreshlayout) implementation(libs.glide) implementation(libs.play.services.location) + implementation(libs.androidx.camera.core) + implementation(libs.androidx.camera.camera2) + implementation(libs.androidx.camera.lifecycle) + implementation(libs.androidx.camera.view) + implementation(libs.androidx.camera.extensions) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 904b5bb..4c1d833 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -54,6 +54,7 @@ android:exported="true" android:windowSoftInputMode="adjustResize" android:configChanges="orientation|screenSize" + android:launchMode="singleTop" android:screenOrientation="portrait" /> diff --git a/app/src/main/java/com/example/fieldagent/data/apis/WebService.kt b/app/src/main/java/com/example/fieldagent/data/apis/WebService.kt index 0245813..b8c1f46 100644 --- a/app/src/main/java/com/example/fieldagent/data/apis/WebService.kt +++ b/app/src/main/java/com/example/fieldagent/data/apis/WebService.kt @@ -1,5 +1,6 @@ package com.example.fieldagent.data.apis +import TokenModel import com.example.fieldagent.data.models.responses.* import com.example.fieldagent.data.network.responseUtil.ApiResponse @@ -18,6 +19,7 @@ interface WebService { private const val CATEGORY = "categories" private const val SELECT_CATEGORY = "categories" private const val USER = "users" + private const val REFRESH_TOKEN = "auth/refresh-token" @@ -78,4 +80,8 @@ interface WebService { @PUT("$USER/{id}") fun updateProfile(@Path("id") id: String,@FieldMap hashMap: HashMap): Call + + @POST(REFRESH_TOKEN) + fun refreshToken(): Call + } \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/responses/tokenModel.kt b/app/src/main/java/com/example/fieldagent/data/models/responses/tokenModel.kt new file mode 100644 index 0000000..aa66f8f --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/responses/tokenModel.kt @@ -0,0 +1,15 @@ + +data class TokenModel ( + val status: Long? = null, + val success: Boolean? = null, + val message: String? = null, + val data: Data? = null +) + +data class Data ( + val tokens: Tokens? = null +) + +data class Tokens ( + val accessToken: String? = null +) diff --git a/app/src/main/java/com/example/fieldagent/di/NetworkModule.kt b/app/src/main/java/com/example/fieldagent/di/NetworkModule.kt index 4aec1cf..88e5c47 100644 --- a/app/src/main/java/com/example/fieldagent/di/NetworkModule.kt +++ b/app/src/main/java/com/example/fieldagent/di/NetworkModule.kt @@ -4,7 +4,9 @@ import android.util.Log import com.example.fieldagent.data.apis.WebService import com.example.fieldagent.data.models.responses.UserData import com.example.fieldagent.data.network.Config +import com.example.fieldagent.utils.CALL_TOKEN import com.example.fieldagent.utils.PrefsManager +import com.example.fieldagent.utils.REFRESH_TOKEN import com.example.fieldagent.utils.TOKEN import com.example.fieldagent.utils.USER_DATA import com.google.gson.Gson @@ -66,11 +68,18 @@ object NetworkModule { .addHeader("timezone", TimeZone.getDefault().id) + val accessToken = prefsManager.getString(TOKEN,"") + val refreshToken = prefsManager.getString(REFRESH_TOKEN,"") + val callToken = prefsManager.getString(CALL_TOKEN,"") if (!accessToken.isNullOrEmpty()) requestBuilder.addHeader("authorization", "Bearer $accessToken") + if (callToken=="yes") + requestBuilder.addHeader("X-Refresh-Token", "$refreshToken") + + request=requestBuilder.build() chain.proceed(request) diff --git a/app/src/main/java/com/example/fieldagent/ui/addsite/AddSiteFragment.kt b/app/src/main/java/com/example/fieldagent/ui/addsite/AddSiteFragment.kt index 3c5d3ec..523b890 100644 --- a/app/src/main/java/com/example/fieldagent/ui/addsite/AddSiteFragment.kt +++ b/app/src/main/java/com/example/fieldagent/ui/addsite/AddSiteFragment.kt @@ -4,6 +4,7 @@ import android.Manifest import android.annotation.SuppressLint import android.app.Activity.RESULT_OK import android.app.Dialog +import android.content.ContentValues import android.content.Context import android.content.Intent import android.content.IntentSender @@ -18,6 +19,7 @@ import android.net.Uri import android.os.Build import android.os.Bundle import android.os.Environment +import android.provider.MediaStore import android.provider.Settings import android.text.Editable import android.text.TextWatcher @@ -35,6 +37,11 @@ import androidx.activity.result.IntentSenderRequest import androidx.activity.result.PickVisualMediaRequest import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.RequiresPermission +import androidx.camera.core.CameraSelector +import androidx.camera.core.ImageCapture +import androidx.camera.core.ImageCaptureException +import androidx.camera.core.Preview +import androidx.camera.lifecycle.ProcessCameraProvider import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.core.content.FileProvider @@ -118,6 +125,9 @@ class AddSiteFragment : Fragment() { private lateinit var fusedLocationClient: FusedLocationProviderClient private lateinit var locationPermissionLauncher: ActivityResultLauncher> + private var imageCapture: ImageCapture? = null + private lateinit var cameraProvider: ProcessCameraProvider + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -189,15 +199,19 @@ class AddSiteFragment : Fragment() { cameraLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { success -> if (success) { - imageUri?.let { - // Handle image from camerax - binding.llUploadImage.gone() - binding.cardImage.visible() - binding.ivSetImage.setImageURI(imageUri) - binding.ivCloseImage.visible() - fileToUpload=uriToFile(imageUri!!,requireActivity()); + lifecycleScope.launch { + delay(300) // This helps avoid Handler-on-dead-thread on some OEMs + imageUri?.let { + binding.llUploadImage.gone() + binding.cardImage.visible() + binding.ivSetImage.setImageURI(imageUri) + + binding.ivCloseImage.visible() + fileToUpload = uriToFile(imageUri!!, requireActivity()) + } } + } } @@ -246,7 +260,7 @@ class AddSiteFragment : Fragment() { // Permission launcher permissionLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> if (permissions[Manifest.permission.CAMERA] == true) { - openCamera() + } else { Toast.makeText(requireContext(), "Camera permission denied", Toast.LENGTH_SHORT).show() } @@ -481,8 +495,10 @@ class AddSiteFragment : Fragment() { view.tvCamera.setOnClickListener { - permissionLauncher.launch(arrayOf(Manifest.permission.CAMERA)) + // startCameraX(); + // permissionLauncher.launch(arrayOf(Manifest.permission.CAMERA)) + openCamera() dialog.dismiss() } dialog.show() @@ -490,16 +506,28 @@ class AddSiteFragment : Fragment() { private fun openCamera() { - imageUri = FileProvider.getUriForFile( + /* imageUri = FileProvider.getUriForFile( requireContext(), "${requireContext().packageName}.provider", createImageFile() - ) + )*/ + imageUri=createImageUri() cameraLauncher.launch(imageUri!!) } + private fun createImageUri(): Uri? { + val contentValues = ContentValues().apply { + put(MediaStore.Images.Media.DISPLAY_NAME, "IMG_${System.currentTimeMillis()}.jpg") + put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") + put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES) + } + + return requireContext().contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) + } + + private fun createImageFile(): File { diff --git a/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragment.kt b/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragment.kt index 5f50fb9..a2ba428 100644 --- a/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragment.kt +++ b/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragment.kt @@ -226,7 +226,7 @@ class DamageListFragment : Fragment() { // setUpPdf() - val url = DOWNLOAD_URL+hashCode + val url = DOWNLOAD_URL+hashCode+"/" val downloadsFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) val fileName = url.substringAfterLast('/')+".pdf" val destinationFile = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName) @@ -612,7 +612,7 @@ class DamageListFragment : Fragment() { .build() val retrofit = Retrofit.Builder() - .baseUrl("https://example.com/") // Placeholder, overridden by @Url + .baseUrl(fileUrl) // Placeholder, overridden by @Url .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build() diff --git a/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeFragment.kt b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeFragment.kt index c5d4b69..05b1c9f 100644 --- a/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeFragment.kt +++ b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeFragment.kt @@ -43,13 +43,16 @@ import androidx.recyclerview.widget.RecyclerView import com.example.fieldagent.data.models.responses.InspectionData import com.example.fieldagent.data.models.responses.InspectionList import com.example.fieldagent.data.models.responses.UserData +import com.example.fieldagent.data.network.responseUtil.AppError import com.example.fieldagent.databinding.PopLayoutBinding import com.example.fieldagent.utils.AFTER +import com.example.fieldagent.utils.CALL_TOKEN import com.example.fieldagent.utils.LIMIT_TEXT import com.example.fieldagent.utils.PAGE_TEXT import com.example.fieldagent.utils.PER_PAGE import com.example.fieldagent.utils.PER_PAGE_LOAD import com.example.fieldagent.utils.SEARCH +import com.example.fieldagent.utils.TOKEN import com.example.fieldagent.utils.gone import com.example.fieldagent.utils.hideShowView import com.example.fieldagent.utils.isConnectedToInternet @@ -116,7 +119,7 @@ class HomeFragment : Fragment() { private fun initialize(){ prefsManager.save(IS_LOGIN,true) - + prefsManager.saveString(CALL_TOKEN,"no") if (viewModel.inspections.value?.data?.data?.inspections.isNullOrEmpty()) { val hashMap = HashMap() hashMap[LIMIT_TEXT] = PER_PAGE_LOAD @@ -350,8 +353,18 @@ class HomeFragment : Fragment() { adapter.setAllItemsLoaded(true) binding.swipeRefresh.isRefreshing = false - binding.clLoader.root.gone() - ApisRespHandler.handleError(it.error, requireActivity()) + + if (it.error is AppError.ApiUnauthorized) + { + prefsManager.saveString(CALL_TOKEN,"yes") + viewModel.getRefreshToken() + + }else{ + binding.clLoader.root.gone() + ApisRespHandler.handleError(it.error, requireActivity()) + } + + } Status.LOADING -> { Log.e("Checkkkkkkksds==in loading=>","${items.size}") @@ -391,6 +404,33 @@ class HomeFragment : Fragment() { } } }) + + + + viewModel.refreshToken.observe(requireActivity(), Observer { + it ?: return@Observer + when (it.status) { + Status.SUCCESS -> { + // binding.clLoader.root.gone() + + prefsManager.saveString(CALL_TOKEN,"no") + prefsManager.saveString(TOKEN,it.data?.data?.tokens?.accessToken.toString()) + refreshPagination() + val hashMap = HashMap() + hashMap[LIMIT_TEXT] = PER_PAGE_LOAD + hashMap[PAGE_TEXT] = PER_PAGE + viewModel.getInspectionList(hashMap) + + } + Status.ERROR -> { + binding.clLoader.root.gone() + ApisRespHandler.handleError(it.error, requireActivity()) + } + Status.LOADING -> { + binding.clLoader.root.visible() + } + } + }) } diff --git a/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeViewModel.kt b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeViewModel.kt index fc1b047..42c1709 100644 --- a/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeViewModel.kt +++ b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeViewModel.kt @@ -1,5 +1,6 @@ package com.example.fieldagent.ui.homescreen +import TokenModel import androidx.lifecycle.ViewModel import com.example.fieldagent.data.apis.WebService import com.example.fieldagent.data.models.responses.InspectionData @@ -19,6 +20,7 @@ class HomeViewModel @Inject constructor(private val webService: WebService) : Vi val inspections by lazy { SingleLiveEvent>() } val delete by lazy { SingleLiveEvent>() } + val refreshToken by lazy { SingleLiveEvent>() } fun getInspectionList(hashMap: HashMap) { inspections.value = Resource.loading() @@ -47,6 +49,33 @@ class HomeViewModel @Inject constructor(private val webService: WebService) : Vi } + fun getRefreshToken() { + refreshToken.value = Resource.loading() + + webService.refreshToken() + .enqueue(object : Callback { + + override fun onResponse(call: Call, + response: Response + ) { + if (response.isSuccessful) { + refreshToken.value = Resource.success(response.body()) + + } else { + refreshToken.value = Resource.error( + ApiUtils.getError(response.code(), + response.errorBody()?.string())) + } + } + + override fun onFailure(call: Call, throwable: Throwable) { + refreshToken.value = Resource.error(ApiUtils.failure(throwable)) + } + + }) + } + + fun deleteInspection(id:String) { delete.value = Resource.loading() diff --git a/app/src/main/java/com/example/fieldagent/ui/login/LoginActivity.kt b/app/src/main/java/com/example/fieldagent/ui/login/LoginActivity.kt index ed19338..c29c4e7 100644 --- a/app/src/main/java/com/example/fieldagent/ui/login/LoginActivity.kt +++ b/app/src/main/java/com/example/fieldagent/ui/login/LoginActivity.kt @@ -20,6 +20,7 @@ import com.example.fieldagent.databinding.ActivityLoginBinding import com.example.fieldagent.ui.homescreen.HomeActivity import androidx.lifecycle.Observer import com.example.fieldagent.utils.PrefsManager +import com.example.fieldagent.utils.REFRESH_TOKEN import com.example.fieldagent.utils.TOKEN import com.example.fieldagent.utils.USER_DATA import com.example.fieldagent.utils.dialogs.ProgressDialog @@ -107,9 +108,7 @@ class LoginActivity : AppCompatActivity() { prefsManager.saveString(USER_DATA,jsonString) prefsManager.saveString(TOKEN,it.data?.data?.tokens?.accessToken.toString()) - - - + prefsManager.saveString(REFRESH_TOKEN,it.data?.data?.tokens?.refreshToken.toString()) val intent = Intent(this, HomeActivity::class.java) startActivity(intent) diff --git a/app/src/main/java/com/example/fieldagent/utils/AppConstant.kt b/app/src/main/java/com/example/fieldagent/utils/AppConstant.kt index baff96b..ae8c2bb 100644 --- a/app/src/main/java/com/example/fieldagent/utils/AppConstant.kt +++ b/app/src/main/java/com/example/fieldagent/utils/AppConstant.kt @@ -4,6 +4,8 @@ package com.example.fieldagent.utils const val USER_DATA = "userData" const val TOKEN = "token" +const val REFRESH_TOKEN = "refreshToken" +const val CALL_TOKEN = "no" const val IS_LOGIN = "isLogin" const val AFTER = "after" diff --git a/app/src/main/res/layout/fragment_add_site.xml b/app/src/main/res/layout/fragment_add_site.xml index 6361e80..164af35 100644 --- a/app/src/main/res/layout/fragment_add_site.xml +++ b/app/src/main/res/layout/fragment_add_site.xml @@ -12,532 +12,568 @@ android:background="@color/white" tools:context=".ui.addsite.AddSiteFragment"> - - - - - + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_begin="@dimen/dp_16" /> + + + + + + + + + + + + - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:id="@+id/llLocation" + android:layout_width="0dp" + android:layout_height="wrap_content" + app:layout_constraintStart_toEndOf="@id/leftGuide" + app:layout_constraintEnd_toStartOf="@id/rightGuide" + app:layout_constraintTop_toBottomOf="@id/txtLocation" + android:layout_marginTop="@dimen/dp_4" + android:orientation="horizontal" + android:background="@drawable/rounded_edit_text_background" - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -