Skip to content

Commit

Permalink
Merge branch 'master' into 3645-illegalstateexception
Browse files Browse the repository at this point in the history
  • Loading branch information
dogi authored Jul 8, 2024
2 parents b6923d4 + 54f59ed commit 20db11d
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ abstract class BaseRecyclerFragment<LI> : BaseRecyclerParentFragment<Any?>(), On
"submission" -> (v as TextView).setText(R.string.no_submissions)
"teams" -> (v as TextView).setText(R.string.no_teams)
"chatHistory" -> (v as TextView).setText(R.string.no_chats)
"feedback" -> (v as TextView).setText(R.string.no_feedback)
else -> (v as TextView).setText(R.string.no_data_available_please_check_and_try_again)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import org.ole.planet.myplanet.model.RealmSubmission
import org.ole.planet.myplanet.model.RealmUserModel
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.ui.exam.TakeExamFragment
import org.ole.planet.myplanet.utilities.CameraUtils.CapturePhoto
import org.ole.planet.myplanet.utilities.CameraUtils.capturePhoto
import org.ole.planet.myplanet.utilities.CameraUtils.ImageCaptureCallback
import org.ole.planet.myplanet.utilities.Constants
import org.ole.planet.myplanet.utilities.Constants.showBetaFeature
Expand Down Expand Up @@ -164,7 +164,7 @@ class CourseStepFragment : BaseContainerFragment(), ImageCaptureCallback {
takeExam.arguments = b
homeItemClickListener?.openCallFragment(takeExam)
context?.let { it1 ->
CapturePhoto(it1, object : ImageCaptureCallback {
capturePhoto(it1, object : ImageCaptureCallback {
override fun onImageCapture(fileUri: String?) {
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import org.ole.planet.myplanet.model.RealmExamQuestion
import org.ole.planet.myplanet.model.RealmSubmission
import org.ole.planet.myplanet.model.RealmSubmission.Companion.createSubmission
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.utilities.CameraUtils.CapturePhoto
import org.ole.planet.myplanet.utilities.CameraUtils.capturePhoto
import org.ole.planet.myplanet.utilities.CameraUtils.ImageCaptureCallback
import org.ole.planet.myplanet.utilities.JsonParserUtils.getStringAsJsonArray
import org.ole.planet.myplanet.utilities.JsonUtils.getString
Expand Down Expand Up @@ -210,7 +210,7 @@ class TakeExamFragment : BaseExamFragment(), View.OnClickListener, CompoundButto
try {
if (isCertified && !isMySurvey) {
context?.let { it1 ->
CapturePhoto(it1, object : ImageCaptureCallback {
capturePhoto(it1, object : ImageCaptureCallback {
override fun onImageCapture(fileUri: String?) {
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.ole.planet.myplanet.model.RealmFeedback
import org.ole.planet.myplanet.model.RealmUserModel
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.ui.feedback.FeedbackFragment.OnFeedbackSubmittedListener
import org.ole.planet.myplanet.base.BaseRecyclerFragment.Companion.showNoData

class FeedbackListFragment : Fragment(), OnFeedbackSubmittedListener {
private lateinit var fragmentFeedbackListBinding: FragmentFeedbackListBinding
Expand All @@ -25,6 +26,7 @@ class FeedbackListFragment : Fragment(), OnFeedbackSubmittedListener {
fragmentFeedbackListBinding = FragmentFeedbackListBinding.inflate(inflater, container, false)
mRealm = DatabaseService(requireActivity()).realmInstance
userModel = UserProfileDbHandler(requireContext()).userModel

fragmentFeedbackListBinding.fab.setOnClickListener {
val feedbackFragment = FeedbackFragment()
feedbackFragment.setOnFeedbackSubmittedListener(this)
Expand All @@ -33,15 +35,13 @@ class FeedbackListFragment : Fragment(), OnFeedbackSubmittedListener {
}
}

mRealm.executeTransactionAsync(
Realm.Transaction { },
Realm.Transaction.OnSuccess {
feedbackList = mRealm.where(RealmFeedback::class.java)
.equalTo("owner", userModel?.name).findAllAsync()
feedbackList?.addChangeListener { results ->
updatedFeedbackList(results)
}
})
feedbackList = mRealm.where(RealmFeedback::class.java)
.equalTo("owner", userModel?.name).findAllAsync()

feedbackList?.addChangeListener { results ->
updatedFeedbackList(results)
}

return fragmentFeedbackListBinding.root
}

Expand All @@ -53,6 +53,11 @@ class FeedbackListFragment : Fragment(), OnFeedbackSubmittedListener {
if (userModel?.isManager() == true) list = mRealm.where(RealmFeedback::class.java).findAll()
val adapterFeedback = AdapterFeedback(requireActivity(), list)
fragmentFeedbackListBinding.rvFeedback.adapter = adapterFeedback

val itemCount = feedbackList?.size ?: 0
showNoData(fragmentFeedbackListBinding.tvMessage, itemCount, "feedback")

updateTextViewsVisibility(itemCount)
}

override fun onDestroy() {
Expand All @@ -74,11 +79,25 @@ class FeedbackListFragment : Fragment(), OnFeedbackSubmittedListener {
updatedFeedbackList(updatedList)
})
}

private fun updatedFeedbackList(updatedList: RealmResults<RealmFeedback>?) {
activity?.runOnUiThread {
val adapterFeedback = updatedList?.let { AdapterFeedback(requireActivity(), it) }
fragmentFeedbackListBinding.rvFeedback.adapter = adapterFeedback
adapterFeedback?.notifyDataSetChanged()

val itemCount = updatedList?.size ?: 0
showNoData(fragmentFeedbackListBinding.tvMessage, itemCount, "feedback")
updateTextViewsVisibility(itemCount)
}
}

private fun updateTextViewsVisibility(itemCount: Int) {
val visibility = if (itemCount == 0) View.GONE else View.VISIBLE
fragmentFeedbackListBinding.tvTitle.visibility = visibility
fragmentFeedbackListBinding.tvType.visibility = visibility
fragmentFeedbackListBinding.tvPriority.visibility = visibility
fragmentFeedbackListBinding.tvStatus.visibility = visibility
fragmentFeedbackListBinding.tvOpenDate.visibility = visibility
}
}
77 changes: 50 additions & 27 deletions app/src/main/java/org/ole/planet/myplanet/utilities/CameraUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,28 @@ import android.content.pm.PackageManager
import android.graphics.ImageFormat
import android.graphics.SurfaceTexture
import android.hardware.camera2.*
import android.hardware.camera2.params.OutputConfiguration
import android.hardware.camera2.params.SessionConfiguration
import android.media.ImageReader
import android.os.Build
import android.os.Handler
import android.os.HandlerThread
import android.util.Size
import android.view.Surface
import androidx.core.content.ContextCompat
import java.io.File
import java.io.FileOutputStream
import java.util.*
import java.util.concurrent.Executors

object CameraUtils {
private var cameraDevice: CameraDevice? = null
private var captureSession: CameraCaptureSession? = null
private var imageReader: ImageReader? = null
private var backgroundHandler: Handler
private var backgroundThread: HandlerThread
private var backgroundThread: HandlerThread = HandlerThread("CameraBackground")

@JvmStatic
fun CapturePhoto(context: Context, callback: ImageCaptureCallback) {
fun capturePhoto(context: Context, callback: ImageCaptureCallback) {
if (ContextCompat.checkSelfPermission(
context,
Manifest.permission.CAMERA
Expand All @@ -48,11 +52,7 @@ object CameraUtils {
captureBuilder?.addTarget(imageReader!!.surface)
captureBuilder?.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE)

val captureCallback = object : CameraCaptureSession.CaptureCallback() {
override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) {
super.onCaptureCompleted(session, request, result)
}
}
val captureCallback = object : CameraCaptureSession.CaptureCallback() {}

captureSession?.stopRepeating()
captureSession?.abortCaptures()
Expand Down Expand Up @@ -83,13 +83,6 @@ object CameraUtils {
val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
try {
val cameraId = manager.cameraIdList[0] // Assuming we want to use the first (rear) camera
val characteristics = manager.getCameraCharacteristics(cameraId)
val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
val largest = Collections.max(
listOf(*map!!.getOutputSizes(ImageFormat.JPEG)),
CompareSizesByArea()
)
val reader = ImageReader.newInstance(largest.width, largest.height, ImageFormat.JPEG, 2)
manager.openCamera(cameraId, object : CameraDevice.StateCallback() {
override fun onOpened(camera: CameraDevice) {
cameraDevice = camera
Expand Down Expand Up @@ -117,9 +110,10 @@ object CameraUtils {
val surface = Surface(texture)
val captureRequestBuilder = cameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
captureRequestBuilder.addTarget(surface)
cameraDevice!!.createCaptureSession(
listOf(surface),
object : CameraCaptureSession.StateCallback() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val outputConfigurations = listOf(OutputConfiguration(surface))
val executor = Executors.newSingleThreadExecutor()
val stateCallback = object : CameraCaptureSession.StateCallback() {
override fun onConfigured(session: CameraCaptureSession) {
if (cameraDevice == null) return
captureSession = session
Expand All @@ -139,9 +133,44 @@ object CameraUtils {
}

override fun onConfigureFailed(session: CameraCaptureSession) {}
},
backgroundHandler
)
}

val sessionConfiguration = SessionConfiguration(
SessionConfiguration.SESSION_REGULAR,
outputConfigurations,
executor,
stateCallback
)

cameraDevice!!.createCaptureSession(sessionConfiguration)
} else {
@Suppress("DEPRECATION")
cameraDevice!!.createCaptureSession(
listOf(surface),
object : CameraCaptureSession.StateCallback() {
override fun onConfigured(session: CameraCaptureSession) {
if (cameraDevice == null) return
captureSession = session
try {
captureRequestBuilder.set(
CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE
)
captureSession!!.setRepeatingRequest(
captureRequestBuilder.build(),
null,
backgroundHandler
)
} catch (e: CameraAccessException) {
e.printStackTrace()
}
}

override fun onConfigureFailed(session: CameraCaptureSession) {}
},
backgroundHandler
)
}
} catch (e: CameraAccessException) {
e.printStackTrace()
}
Expand All @@ -151,13 +180,7 @@ object CameraUtils {
fun onImageCapture(fileUri: String?)
}

private class CompareSizesByArea : Comparator<Size> {
override fun compare(lhs: Size, rhs: Size): Int {
return java.lang.Long.signum(lhs.width.toLong() * lhs.height - rhs.width.toLong() * rhs.height)
}
}
init {
backgroundThread = HandlerThread("CameraBackground")
backgroundThread.start()
backgroundHandler = Handler(backgroundThread.looper)
}
Expand Down
98 changes: 63 additions & 35 deletions app/src/main/java/org/ole/planet/myplanet/utilities/FileUtils.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.ole.planet.myplanet.utilities

import android.app.PendingIntent
import android.app.usage.StorageStatsManager
import android.content.Context
import android.content.Intent
Expand All @@ -13,9 +14,8 @@ import android.provider.MediaStore
import android.text.TextUtils
import android.webkit.MimeTypeMap
import androidx.annotation.RequiresApi
import androidx.core.content.FileProvider
import org.ole.planet.myplanet.BuildConfig
import org.ole.planet.myplanet.MainApplication
import android.content.pm.PackageInstaller
import org.ole.planet.myplanet.R
import java.io.BufferedReader
import java.io.File
Expand Down Expand Up @@ -116,29 +116,42 @@ object FileUtils {

@JvmStatic
fun installApk(activity: Context, file: String?) {
if (!file?.endsWith("apk")!!) return
val toInstall = File(file)
if (!toInstall.exists()) return
try {
if (!file?.endsWith("apk")!!) return
val toInstall = getSDPathFromUrl(file)
toInstall.setReadable(true, false)
val apkUri: Uri
val intent: Intent
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
apkUri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", toInstall)
intent = Intent(Intent.ACTION_INSTALL_PACKAGE)
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.setData(apkUri)
} else {
apkUri = Uri.fromFile(toInstall)
intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
activity.startActivity(intent)
val packageInstaller = activity.packageManager.packageInstaller
val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
val sessionId = packageInstaller.createSession(params)
val session = packageInstaller.openSession(sessionId)
addApkToInstallSession(toInstall, session)
val intent = Intent(activity, activity.javaClass)
val pendingIntent = PendingIntent.getActivity(activity, 0, intent,
PendingIntent.FLAG_IMMUTABLE)
val intentSender = pendingIntent.intentSender
session.commit(intentSender)
session.close()
} catch (e: Exception) {
e.printStackTrace()
}
}

@Throws(IOException::class)
private fun addApkToInstallSession(apkFile: File, session: PackageInstaller.Session) {
val out: OutputStream = session.openWrite("my_app_session", 0, -1)
val fis = FileInputStream(apkFile)
fis.use { input ->
out.use { output ->
val buffer = ByteArray(4096)
var length: Int
while (input.read(buffer).also { length = it } != -1) {
output.write(buffer, 0, length)
}
session.fsync(out)
}
}
}

private fun getMimeType(url: String): String? {
var type: String? = null
val extension = MimeTypeMap.getFileExtensionFromUrl(url)
Expand Down Expand Up @@ -223,24 +236,39 @@ object FileUtils {

@JvmStatic
fun getImagePath(context: Context, uri: Uri?): String? {
var cursor = uri?.let { context.contentResolver.query(it, null, null, null, null) }
return if (cursor != null && cursor.moveToFirst()) {
var document_id = cursor.getString(0)
document_id = document_id.substring(document_id.lastIndexOf(":") + 1)
cursor.close()
cursor = context.contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", arrayOf(document_id), null)
if (uri == null) return null
val projection = arrayOf(MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA)
var cursor: Cursor? = null
try {
cursor = context.contentResolver.query(uri, projection, null, null, null)
if (cursor != null && cursor.moveToFirst()) {
val path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
cursor.close()
path
} else {
// Handle the case when the cursor is empty or null
null // or return an appropriate default value or handle the error accordingly
val documentIdIndex = cursor.getColumnIndex(MediaStore.Images.Media._ID)
if (documentIdIndex >= 0) {
val documentId = cursor.getString(documentIdIndex)
cursor.close()
val selection = "${MediaStore.Images.Media._ID} = ?"
val selectionArgs = arrayOf(documentId)
cursor = context.contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
selectionArgs,
null
)
if (cursor != null && cursor.moveToFirst()) {
val dataIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA)
if (dataIndex >= 0) {
val path = cursor.getString(dataIndex)
cursor.close()
return path
}
}
}
}
} else {
// Handle the case when the cursor is empty or null
null // or return an appropriate default value or handle the error accordingly
} finally {
cursor?.close()
}
return null
}

@JvmStatic
Expand Down Expand Up @@ -417,7 +445,7 @@ object FileUtils {

fun nameWithoutExtension(fileName: String?): String?{
extractFileName(fileName)
val nameWithExtension = FileUtils.extractFileName(fileName)
val nameWithExtension = extractFileName(fileName)
val nameWithoutExtension = nameWithExtension?.substringBeforeLast(".")
return nameWithoutExtension
}
Expand Down
Loading

0 comments on commit 20db11d

Please sign in to comment.