diff --git a/.idea/misc.xml b/.idea/misc.xml index ec43b7c..7548318 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -17,8 +17,10 @@ + + @@ -35,6 +37,7 @@ + diff --git a/app/build.gradle b/app/build.gradle index daeb041..2002ffc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,12 +12,12 @@ plugins { } android { - compileSdk 32 + compileSdk 33 defaultConfig { applicationId "com.example.teachjr" minSdk 21 - targetSdk 32 + targetSdk 33 versionCode 1 versionName "1.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 158c54a..c94de9d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,10 +3,9 @@ xmlns:tools="http://schemas.android.com/tools" package="com.example.teachjr"> - + - - @@ -24,7 +23,13 @@ android:name="android.permission.ACCESS_COARSE_LOCATION" /> + android:name="android.permission.ACCESS_FINE_LOCATION" + android:maxSdkVersion="32"/> + + + () private val sharedProfViewModel by activityViewModels() private lateinit var viewPagerAdapter: AtdReportViewPagerAdapter private val tabLayoutTitles = arrayListOf("Lectures", "Students") - private lateinit var confirmDialogDownload: AlertDialog - private lateinit var confirmDialogOpenUpload: AlertDialog - - private val permissionRequestLauncher = - registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> - val granted = permissions.entries.all { - it.value == true - } - if(granted) { - openExcelFile() - } else { - Toast.makeText(context, "not GRANTED", Toast.LENGTH_SHORT).show() - } - } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentProfAtdReportBinding.inflate(layoutInflater) - downloadFolderFile = requireContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)!! -// downloadFolderFile = requireContext().filesDir - return binding.root } @@ -86,9 +66,7 @@ class ProfAtdReportFragment : Fragment() { } setupOptionsMenu() - createConfirmDownloadDialog() - createConfirmDialogOpenUpload() - setupObservers() +// setupObservers() viewPagerAdapter = AtdReportViewPagerAdapter(this) @@ -113,9 +91,10 @@ class ProfAtdReportFragment : Fragment() { when(it.itemId) { R.id.action_download_report -> { if(atdReportViewModel.detailsLoaded) { - checkPermissionAndShowDialog() + findNavController().navigate(R.id.action_profAtdReportFragment_to_profExcelSheetFragment) +// checkPermissionAndShowDialog() } else { - Toast.makeText(context, "Data not available", Toast.LENGTH_SHORT).show() + Toast.makeText(context, "Fetching data, please wait...", Toast.LENGTH_SHORT).show() } true } @@ -123,105 +102,4 @@ class ProfAtdReportFragment : Fragment() { } } } - - private fun setupObservers() { - - atdReportViewModel.atdReportSaveStatus.observe(viewLifecycleOwner) { - when(it) { - is Response.Loading -> { showSaving() } - is Response.Error -> { - stopSaving() - Toast.makeText(context, it.errorMessage, Toast.LENGTH_SHORT).show() - } - is Response.Success -> { - stopSaving() - confirmDialogOpenUpload.show() - binding.layoutFileLocation.visibility = View.VISIBLE - binding.tvFileLocation.text = downloadFolderFile.path.toString() - } - } - } - } - - private fun checkPermissionAndShowDialog() { - if(Permissions.hasReadStoragePermissions(activity as Context) - && Permissions.hasWriteStoragePermissions(activity as Context)) { - - confirmDialogDownload.show() - } else { - permissionRequestLauncher.launch(Permissions.getPendingStoragePermissions(activity as Activity)) - } - } - - private fun createConfirmDownloadDialog() { - confirmDialogDownload = AlertDialog.Builder(context) - .setTitle("Convert to excel?") - .setMessage("Attendance report will be saved as excel sheet") - .setPositiveButton(Constants.YES) { _, _ -> - - lifecycleScope.launch(Dispatchers.IO) { - atdReportViewModel.downloadExcelSheet(downloadFolderFile.path.toString()) - } - } - .setNegativeButton(Constants.NO, null) - .create() - } - - private fun createConfirmDialogOpenUpload() { - confirmDialogOpenUpload = AlertDialog.Builder(context) - .setTitle("File Saved") -// .setMessage("Do you want to open it or upload it to google drive?") - .setMessage("Do you want to open it?") - .setPositiveButton("Open") { _, _ -> - - openExcelFile() - } -// .setNegativeButton("Upload") {_,_ -> } -// .setNeutralButton("Cancel", null) - .setNegativeButton("Cancel", null) - .create() - } - - private fun showSaving() { - binding.viewPager.alpha = 0.5F - binding.cvSaving.visibility = View.VISIBLE - } - - private fun stopSaving() { - binding.viewPager.alpha = 1F - binding.cvSaving.visibility = View.GONE - } - - private fun openExcelFile() { - try { - if(atdReportViewModel.sheetName != null) { - val filePath = File(downloadFolderFile, "") - val sheet = File(filePath, atdReportViewModel.sheetName!!) - val contentUri = FileProvider.getUriForFile( - requireContext(), - "com.example.teachjr.fileProvider", - sheet - ) - Log.i(TAG, "TESTING, URI: ${contentUri.toString()}") - - val intent = Intent(Intent.ACTION_VIEW) - if(contentUri.toString().contains(".xls") || contentUri.toString().contains(".xlsx")) { - intent.setDataAndType(contentUri, "application/vnd.ms-excel") - } - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - startActivity(intent) - -// val file = File(atdReportViewModel.filePath) -// OpenExcel.openFile(requireContext(), file) - } - } catch (e: ActivityNotFoundException) { -// binding.tvNoActivityToHandleIntent.text = binding.tvNoActivityToHandleIntent.text.toString() + downloadFolderFile.path.toString() -// binding.tvNoActivityToHandleIntent.visibility = View.VISIBLE - Toast.makeText(context, "You don't have any app that can open an EXCEL file", Toast.LENGTH_LONG).show() - } - catch (e: Exception) { - e.printStackTrace() - Toast.makeText(context, "Something went wrong", Toast.LENGTH_SHORT).show() - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/example/teachjr/ui/professor/profFragments/ProfExcelSheetFragment.kt b/app/src/main/java/com/example/teachjr/ui/professor/profFragments/ProfExcelSheetFragment.kt new file mode 100644 index 0000000..598d326 --- /dev/null +++ b/app/src/main/java/com/example/teachjr/ui/professor/profFragments/ProfExcelSheetFragment.kt @@ -0,0 +1,243 @@ +package com.example.teachjr.ui.professor.profFragments + +import android.content.ActivityNotFoundException +import android.content.Intent +import android.os.Bundle +import android.util.Log +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.FileProvider +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope +import com.example.teachjr.databinding.FragmentProfExcelSheetBinding +import com.example.teachjr.ui.viewmodels.professorViewModels.ProfAtdReportViewModel +import com.example.teachjr.utils.Adapter_ViewModel_Utils +import com.example.teachjr.utils.Constants +import com.example.teachjr.utils.excelReadWrite.WriteExcel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.io.File +import java.io.IOException + +class ProfExcelSheetFragment : Fragment() { + + private val TAG = ProfExcelSheetFragment::class.java.simpleName + private lateinit var binding: FragmentProfExcelSheetBinding + + private val atdReportViewModel by activityViewModels() + +// private val permissionRequestLauncher = +// registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> +// val granted = permissions.entries.all { +// it.value == true +// } +// if(granted) { +// openExcelFile() +// } else { +// Toast.makeText(context, "not GRANTED", Toast.LENGTH_SHORT).show() +// } +// } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentProfExcelSheetBinding.inflate(layoutInflater) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + checkExistingFile() + setupButtons() +// setupObservers() + } + + private fun checkExistingFile() { + lifecycleScope.launch { + getExcelFileName() + if(atdReportViewModel.fileName == Constants.FILE_NOT_FOUND) { + showCreateLayout() + } else { + showUpdateLayout() + } + } + } + + private fun setupButtons() { + binding.btnCreateFile.setOnClickListener { + lifecycleScope.launch { + showSavingLayout() + + val newFileName = Adapter_ViewModel_Utils.generateFileName() + val isSaved = saveExcelFile(newFileName) + + handleFileSaved(isSaved, newFileName) + } + } + + binding.btnOpenFile.setOnClickListener { + openExcelFile() + } + + binding.btnUpdateFile.setOnClickListener { + lifecycleScope.launch { + showSavingLayout() + Log.i("TAG", "testing: Calling deleteExcelFile()") + val isDeleted = deleteExcelFile() + if(isDeleted) { + Log.i("TAG", "testing: old file deleted") + val newFileName = Adapter_ViewModel_Utils.generateFileName() + val isSaved = saveExcelFile(newFileName) + + handleFileSaved(isSaved, newFileName) + + } else { + Toast.makeText(context, "Couldn't Update File", Toast.LENGTH_LONG).show() + } + } + } + } + + private fun handleFileSaved(isSaved: Boolean, newFileName: String) { + if(isSaved) { + atdReportViewModel.updateFileName("$newFileName.xls") + showUpdateLayout() + } else { + showCreateLayout() + Toast.makeText(context, "Failed to save file in storage.", Toast.LENGTH_LONG).show() + } + } + + private suspend fun deleteExcelFile(): Boolean { + return withContext(Dispatchers.IO) { + try { + Log.i("TAG", "testing_deleteExcelFile: called") + requireContext().deleteFile(atdReportViewModel.fileName) + } catch (e: Exception) { + e.printStackTrace() + false + } + } + } + + private suspend fun getExcelFileName() { + return withContext(Dispatchers.IO) { + val files = requireContext().filesDir.listFiles() + // We only want excel files, so we filter + for(file in files!!) { + if(file.canRead() && file.isFile && file.name.startsWith(Constants.REPORT_FILE_NAME_PREFIX) && file.name.endsWith(".xls")) { + atdReportViewModel.updateFileName(file.name) + break + } + } + Log.i("TAG", "Testing_getExcelFileName: filename = ${atdReportViewModel.fileName}") +// fileName + } + } + + private suspend fun saveExcelFile(newFileName: String): Boolean { + return withContext(Dispatchers.IO) { + try { + val workbook = WriteExcel.getWorkbookWithData( + path = requireContext().filesDir.path, + fileName = newFileName, + atdDetails = atdReportViewModel.atdDetails.value!!.data!!) + + if(workbook != null) { + val fileOutputStream = requireContext().openFileOutput("$newFileName.xls", + AppCompatActivity.MODE_PRIVATE + ) + workbook.write(fileOutputStream) + + fileOutputStream.flush() + fileOutputStream.close() + + true + + } else { + false + } + + } catch (e: IOException) { + e.printStackTrace() + false + } + } + } + + private fun openExcelFile() { + try { + if(atdReportViewModel.fileName != "FILE_NOT_FOUND") { + + val sheet = File(requireContext().filesDir, atdReportViewModel.fileName) + + val contentUri = FileProvider.getUriForFile( + requireContext(), + "com.example.teachjr.fileProvider", + sheet + ) + Log.i("TAG", "TESTING, URI: ${contentUri.toString()}") + + val intent = Intent(Intent.ACTION_VIEW) + if(contentUri.toString().contains(".xls") || contentUri.toString().contains(".xlsx")) { + intent.setDataAndType(contentUri, "application/vnd.ms-excel") + } + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + startActivity(intent) + + } + } catch (e: ActivityNotFoundException) { + binding.tvNoAppToOpenExcel.visibility = View.VISIBLE + Toast.makeText(context, "Excel file can't be opened", Toast.LENGTH_LONG).show() + } + catch (e: Exception) { + e.printStackTrace() + Toast.makeText(context, "Something went wrong", Toast.LENGTH_SHORT).show() + } + } + + + private fun showCreateLayout() { + binding.layoutCreateFile.visibility = View.VISIBLE + binding.layoutExistingFile.visibility = View.GONE + binding.cvSaving.visibility = View.GONE + + binding.btnCreateFile.isEnabled = true + } + + private fun showUpdateLayout() { + binding.layoutExistingFile.visibility = View.VISIBLE + binding.layoutExistingFile.alpha = 1F + binding.cvSaving.visibility = View.GONE + binding.layoutCreateFile.visibility = View.GONE + + binding.btnOpenFile.isEnabled = true + binding.btnUpdateFile.isEnabled = true + + binding.tvFileName.text = atdReportViewModel.fileName + } + + private fun showSavingLayout() { + binding.cvSaving.visibility = View.VISIBLE +// binding.layoutExistingFile.visibility = View.GONE +// binding.layoutCreateFile.visibility = View.GONE + + binding.layoutExistingFile.alpha = 0.5F + binding.layoutCreateFile.alpha = 0.5F + + // Disabling Buttons + binding.btnCreateFile.isEnabled = false + binding.btnOpenFile.isEnabled = false + binding.btnUpdateFile.isEnabled = false + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/teachjr/ui/professor/profFragments/ProfMarkAtdFragment.kt b/app/src/main/java/com/example/teachjr/ui/professor/profFragments/ProfMarkAtdFragment.kt index 01f3665..dec71b8 100644 --- a/app/src/main/java/com/example/teachjr/ui/professor/profFragments/ProfMarkAtdFragment.kt +++ b/app/src/main/java/com/example/teachjr/ui/professor/profFragments/ProfMarkAtdFragment.kt @@ -3,8 +3,10 @@ package com.example.teachjr.ui.professor.profFragments import android.app.Activity import android.app.AlertDialog import android.content.Context +import android.content.pm.PackageManager import android.net.wifi.p2p.WifiP2pManager import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo +import android.os.Build import android.os.Bundle import android.os.Looper import android.util.Log @@ -17,6 +19,7 @@ import android.view.animation.AnimationUtils import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels @@ -78,6 +81,7 @@ class ProfMarkAtdFragment : Fragment() { // } } else { // TODO: Display a message that attendance cannot be initiated without permission + Toast.makeText(context, "Attendance can't be initiated without permission", Toast.LENGTH_SHORT).show() } } @@ -264,7 +268,9 @@ class ProfMarkAtdFragment : Fragment() { private fun initiateAtdMarking() { if(Permissions.hasAccessCoarseLocation(activity as Context) - && Permissions.hasAccessFineLocation(activity as Context)) { + && Permissions.hasAccessFineLocation(activity as Context) + && (Build.VERSION.SDK_INT >= 33 && Permissions.hasNearbyWifiDevices(activity as Context))) { + if(markAtdViewModel.isAtdOngoing == false) { startAttendance() diff --git a/app/src/main/java/com/example/teachjr/ui/student/stdFragments/StdMarkAtdFragment.kt b/app/src/main/java/com/example/teachjr/ui/student/stdFragments/StdMarkAtdFragment.kt index 62a6446..6b88ceb 100644 --- a/app/src/main/java/com/example/teachjr/ui/student/stdFragments/StdMarkAtdFragment.kt +++ b/app/src/main/java/com/example/teachjr/ui/student/stdFragments/StdMarkAtdFragment.kt @@ -5,6 +5,7 @@ import android.app.AlertDialog import android.content.Context import android.net.wifi.p2p.WifiP2pManager import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo +import android.os.Build import android.os.Bundle import android.os.Looper import android.util.Log @@ -173,7 +174,8 @@ class StdMarkAtdFragment : Fragment() { private fun initiateAtdMarking() { if(Permissions.hasAccessCoarseLocation(activity as Context) - && Permissions.hasAccessFineLocation(activity as Context)) { + && Permissions.hasAccessFineLocation(activity as Context) + && (Build.VERSION.SDK_INT >= 33 && Permissions.hasNearbyWifiDevices(activity as Context))) { if(markAtdViewModel.isDiscovering == false) { // checkGpsAndStartAttendance() diff --git a/app/src/main/java/com/example/teachjr/ui/viewmodels/professorViewModels/ProfAtdReportViewModel.kt b/app/src/main/java/com/example/teachjr/ui/viewmodels/professorViewModels/ProfAtdReportViewModel.kt index 59fb1d9..ef92beb 100644 --- a/app/src/main/java/com/example/teachjr/ui/viewmodels/professorViewModels/ProfAtdReportViewModel.kt +++ b/app/src/main/java/com/example/teachjr/ui/viewmodels/professorViewModels/ProfAtdReportViewModel.kt @@ -1,18 +1,21 @@ package com.example.teachjr.ui.viewmodels.professorViewModels import android.util.Log +import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import com.example.teachjr.data.model.ProfAttendanceDetails import com.example.teachjr.data.source.repository.ProfRepository import com.example.teachjr.utils.Adapter_ViewModel_Utils +import com.example.teachjr.utils.Constants import com.example.teachjr.utils.FirebaseConstants import com.example.teachjr.utils.excelReadWrite.WriteExcel import com.example.teachjr.utils.sealedClasses.Response import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import java.io.IOException import java.util.* import javax.inject.Inject @@ -28,14 +31,6 @@ class ProfAtdReportViewModel val detailsLoaded: Boolean get() = _detailsLoaded - private var _sheetName: String? = null - val sheetName: String? - get() = _sheetName - - private val _atdReportSaveStatus = MutableLiveData>() - val atdReportSaveStatus: LiveData> - get() = _atdReportSaveStatus - private val _atdDetails = MutableLiveData>() val atdDetails: LiveData> get() = _atdDetails @@ -73,45 +68,24 @@ class ProfAtdReportViewModel } } - suspend fun downloadExcelSheet(downloadFolderPath: String) { - _atdReportSaveStatus.postValue(Response.Loading()) - Log.i(TAG, "Testing_downloadExcelSheet: Downloading started") + override fun onCleared() { + super.onCleared() + Log.i(TAG, "onCleared: VIEWMODEL CLEARED") + } + - val timestamp = Calendar.getInstance().timeInMillis.toString() - val dateString = Adapter_ViewModel_Utils.getFormattedDate3(timestamp) - val fileName = "AtdReport_$dateString" + /** + * Below stuff is used in ProfExcelSheetFragment + */ - val response = WriteExcel.createExcelFile( - downloadFolderPath, fileName, atdDetails.value!!.data!!) + private var _fileName = Constants.FILE_NOT_FOUND + val fileName: String + get() = _fileName + fun updateFileName(name: String) { _fileName = name } - if(response.equals(FirebaseConstants.STATUS_SUCCESSFUL)) { - _atdReportSaveStatus.postValue(Response.Success(fileName)) - _sheetName = "$fileName.xls" - Log.i(TAG, "Testing: $sheetName") - } else { - _atdReportSaveStatus.postValue(Response.Error(response, null)) - } - Log.i(TAG, "Testing_downloadExcelSheet: Downloading Done") - } +// private val _fileSaveStatus = MutableLiveData>() +// val fileSaveStatus: LiveData> +// get() = _fileSaveStatus -// fun getStdList(sem_sec: String) { -// _studentList.postValue(Response.Loading()) -// viewModelScope.launch { -// val stdListResponse = profRepository.getStdList(sem_sec) -// _studentList.postValue(stdListResponse) -// } -// } -// -// fun getLectureList(sem_sec: String, courseCode: String) { -// _lecturesList.postValue(Response.Loading()) -// viewModelScope.launch { -// val lecListResponse = profRepository.getLectureList(sem_sec, courseCode) -// _lecturesList.postValue(lecListResponse) -// } -// } - override fun onCleared() { - super.onCleared() - Log.i(TAG, "onCleared: VIEWMODEL CLEARED") - } } \ No newline at end of file diff --git a/app/src/main/java/com/example/teachjr/utils/Adapter_ViewModel_Utils.kt b/app/src/main/java/com/example/teachjr/utils/Adapter_ViewModel_Utils.kt index eb8add4..8244a2d 100644 --- a/app/src/main/java/com/example/teachjr/utils/Adapter_ViewModel_Utils.kt +++ b/app/src/main/java/com/example/teachjr/utils/Adapter_ViewModel_Utils.kt @@ -43,7 +43,7 @@ object Adapter_ViewModel_Utils { fun getFormattedDate3(timestamp: String): String { try { // val sdf = SimpleDateFormat("EEE, MMM dd, yyyy") - val sdf = SimpleDateFormat("dd_MM_yy") + val sdf = SimpleDateFormat("dd_MM_yyyy") val netDate = Date(timestamp.toLong()) return sdf.format(netDate) } catch (e: Exception) { @@ -104,4 +104,10 @@ object Adapter_ViewModel_Utils { return "${(seconds / 60).toString().padStart(2, '0')} : " + (seconds % 60).toString().padStart(2, '0') } + + fun generateFileName(): String { + val timestamp = Calendar.getInstance().timeInMillis.toString() + val dateString = getFormattedDate3(timestamp) + return "${Constants.REPORT_FILE_NAME_PREFIX}_$dateString" + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/teachjr/utils/Constants.kt b/app/src/main/java/com/example/teachjr/utils/Constants.kt index d9f3ce8..c59f686 100644 --- a/app/src/main/java/com/example/teachjr/utils/Constants.kt +++ b/app/src/main/java/com/example/teachjr/utils/Constants.kt @@ -24,4 +24,7 @@ object Constants { const val HEX_CODE_RED = "#E11717" const val HEX_CODE_GREEN = "#0EC921" + + const val FILE_NOT_FOUND = "FILE_NOT_FOUND" + const val REPORT_FILE_NAME_PREFIX = "AtdReport" } \ No newline at end of file diff --git a/app/src/main/java/com/example/teachjr/utils/Permissions.kt b/app/src/main/java/com/example/teachjr/utils/Permissions.kt index 87327f2..5d3a873 100644 --- a/app/src/main/java/com/example/teachjr/utils/Permissions.kt +++ b/app/src/main/java/com/example/teachjr/utils/Permissions.kt @@ -20,6 +20,13 @@ object Permissions { fun hasAccessCoarseLocation(context: Context) = ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED + fun hasNearbyWifiDevices(context: Context) = + if (Build.VERSION.SDK_INT >= 33) { + ActivityCompat.checkSelfPermission(context, android.Manifest.permission.NEARBY_WIFI_DEVICES) == PackageManager.PERMISSION_GRANTED + } else { + true + } + fun requestPermission(activity: Activity) { val permissionToRequest = mutableListOf() if(Build.VERSION.SDK_INT >= 23) { @@ -31,6 +38,12 @@ object Permissions { permissionToRequest.add(android.Manifest.permission.ACCESS_FINE_LOCATION) } + if (Build.VERSION.SDK_INT >= 33) { + if(!hasNearbyWifiDevices(activity)) { + permissionToRequest.add(android.Manifest.permission.NEARBY_WIFI_DEVICES) + } + } + if(permissionToRequest.isNotEmpty()) { ActivityCompat.requestPermissions(activity, permissionToRequest.toTypedArray(), 0) } @@ -46,6 +59,11 @@ object Permissions { if(!hasAccessFineLocation(activity)) { pendingPermissions.add(android.Manifest.permission.ACCESS_FINE_LOCATION) } + if (Build.VERSION.SDK_INT >= 33) { + if(!hasNearbyWifiDevices(activity)) { + pendingPermissions.add(android.Manifest.permission.NEARBY_WIFI_DEVICES) + } + } return pendingPermissions.toTypedArray() } diff --git a/app/src/main/java/com/example/teachjr/utils/excelReadWrite/WriteExcel.kt b/app/src/main/java/com/example/teachjr/utils/excelReadWrite/WriteExcel.kt index d96516d..173925c 100644 --- a/app/src/main/java/com/example/teachjr/utils/excelReadWrite/WriteExcel.kt +++ b/app/src/main/java/com/example/teachjr/utils/excelReadWrite/WriteExcel.kt @@ -4,6 +4,7 @@ import android.util.Log import com.example.teachjr.data.model.ProfAttendanceDetails import com.example.teachjr.utils.Adapter_ViewModel_Utils import com.example.teachjr.utils.FirebaseConstants +import com.example.teachjr.utils.sealedClasses.Response import org.apache.poi.ss.usermodel.* import org.apache.poi.xssf.usermodel.XSSFFont import org.apache.poi.xssf.usermodel.XSSFWorkbook @@ -17,9 +18,9 @@ object WriteExcel { private val TAG = WriteExcel::class.java.simpleName - suspend fun createExcelFile(downloadFolderPath: String, fileName: String, atdDetails: ProfAttendanceDetails) : String { + suspend fun getWorkbookWithData(path: String, fileName: String, atdDetails: ProfAttendanceDetails) : Workbook? { return suspendCoroutine { continuation -> - Log.i(TAG, "TESTING : downloadFolderPath = $downloadFolderPath") + Log.i(TAG, "TESTING : downloadFolderPath = $path") try { val workbook = XSSFWorkbook() val sheet = workbook.createSheet(fileName) @@ -27,25 +28,11 @@ object WriteExcel { addEnrollmentColumn(sheet, atdDetails.studentList) // First Column addRows(sheet, atdDetails) -// addData(sheet, atdDetails) - - - val currFile = File(downloadFolderPath, "$fileName.xls") - if(!currFile.exists()) { - currFile.createNewFile() - } - - val fileOutputStream = FileOutputStream(currFile) - workbook.write(fileOutputStream) - - fileOutputStream.flush() - fileOutputStream.close() - - continuation.resume(FirebaseConstants.STATUS_SUCCESSFUL) + continuation.resume(workbook) } catch (e: Exception) { e.printStackTrace() - continuation.resume(e.message.toString()) + continuation.resume(null) } } } diff --git a/app/src/main/res/drawable/ic_baseline_save_alt_24_white.xml b/app/src/main/res/drawable/ic_baseline_insert_drive_file_24.xml similarity index 65% rename from app/src/main/res/drawable/ic_baseline_save_alt_24_white.xml rename to app/src/main/res/drawable/ic_baseline_insert_drive_file_24.xml index ddb9d4d..2a02e12 100644 --- a/app/src/main/res/drawable/ic_baseline_save_alt_24_white.xml +++ b/app/src/main/res/drawable/ic_baseline_insert_drive_file_24.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/layout/fragment_prof_atd_report.xml b/app/src/main/res/layout/fragment_prof_atd_report.xml index 883e851..41b939e 100644 --- a/app/src/main/res/layout/fragment_prof_atd_report.xml +++ b/app/src/main/res/layout/fragment_prof_atd_report.xml @@ -34,77 +34,12 @@ app:layout_constraintTop_toBottomOf="@id/toolbar"/> - - - - - - - - - - - - - - - - - - - - - - + app:layout_constraintTop_toBottomOf="@id/tabLayout" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_prof_excel_sheet.xml b/app/src/main/res/layout/fragment_prof_excel_sheet.xml new file mode 100644 index 0000000..420e088 --- /dev/null +++ b/app/src/main/res/layout/fragment_prof_excel_sheet.xml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/atd_report_page_menu.xml b/app/src/main/res/menu/atd_report_page_menu.xml index 779d6e9..d1e12ea 100644 --- a/app/src/main/res/menu/atd_report_page_menu.xml +++ b/app/src/main/res/menu/atd_report_page_menu.xml @@ -4,9 +4,10 @@ + android:title="Excel" + android:icon="@drawable/ic_baseline_insert_drive_file_24" + android:titleCondensed="Excel" + app:showAsAction="always|withText"/> diff --git a/app/src/main/res/navigation/nav_graph_prof.xml b/app/src/main/res/navigation/nav_graph_prof.xml index 66840ee..6f519c8 100644 --- a/app/src/main/res/navigation/nav_graph_prof.xml +++ b/app/src/main/res/navigation/nav_graph_prof.xml @@ -52,10 +52,23 @@ android:id="@+id/profAtdReportFragment" android:name="com.example.teachjr.ui.professor.profFragments.ProfAtdReportFragment" android:label="Attendance Report" - tools:layout="@layout/fragment_prof_atd_report" /> + tools:layout="@layout/fragment_prof_atd_report" > + + + \ No newline at end of file diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml index 2181946..e035a91 100644 --- a/app/src/main/res/xml/file_paths.xml +++ b/app/src/main/res/xml/file_paths.xml @@ -1,9 +1,9 @@ - - - - + + + \ No newline at end of file