diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt
index cfb2abc90a..64dfbbb1f9 100644
--- a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt
@@ -298,6 +298,7 @@ abstract class BaseRecyclerFragment
: BaseRecyclerParentFragment(), 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)
}
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseStepFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseStepFragment.kt
index fd61014b61..e2a44d1c8d 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseStepFragment.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseStepFragment.kt
@@ -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
@@ -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?) {
}
})
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/exam/TakeExamFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/exam/TakeExamFragment.kt
index b698a9102f..e47cb79318 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/exam/TakeExamFragment.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/exam/TakeExamFragment.kt
@@ -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
@@ -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?) {
}
})
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackListFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackListFragment.kt
index 09d5b33970..bf49250c18 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackListFragment.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackListFragment.kt
@@ -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
@@ -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)
@@ -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
}
@@ -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() {
@@ -74,11 +79,25 @@ class FeedbackListFragment : Fragment(), OnFeedbackSubmittedListener {
updatedFeedbackList(updatedList)
})
}
+
private fun updatedFeedbackList(updatedList: RealmResults?) {
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
+ }
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/utilities/CameraUtils.kt b/app/src/main/java/org/ole/planet/myplanet/utilities/CameraUtils.kt
index 59efc46ee8..b9caaf7d66 100644
--- a/app/src/main/java/org/ole/planet/myplanet/utilities/CameraUtils.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/utilities/CameraUtils.kt
@@ -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
@@ -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()
@@ -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
@@ -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
@@ -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()
}
@@ -151,13 +180,7 @@ object CameraUtils {
fun onImageCapture(fileUri: String?)
}
- private class CompareSizesByArea : Comparator {
- 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)
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/utilities/FileUtils.kt b/app/src/main/java/org/ole/planet/myplanet/utilities/FileUtils.kt
index d1436a27a1..f8f48ebf93 100644
--- a/app/src/main/java/org/ole/planet/myplanet/utilities/FileUtils.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/utilities/FileUtils.kt
@@ -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
@@ -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
@@ -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)
@@ -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
@@ -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
}
diff --git a/app/src/main/res/layout/fragment_feedback_list.xml b/app/src/main/res/layout/fragment_feedback_list.xml
index b430b2fde6..a566f95885 100644
--- a/app/src/main/res/layout/fragment_feedback_list.xml
+++ b/app/src/main/res/layout/fragment_feedback_list.xml
@@ -22,7 +22,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
-
-
-
-
\ No newline at end of file
+
+
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 228ad83a45..1ff4fea205 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -1051,6 +1051,7 @@
كوكب %s
التقديمات غير متاحة
لا توجد محادثات سابقة
+ لا توجد تعليقات متاحة
%s
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 47d2cb2eec..cc2c828a20 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -1051,6 +1051,7 @@
%s Planeta
envíos no disponibles
no hay chats anteriores
+ No hay comentarios aquí
%s
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 1c26669b65..e9f31a26a5 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -1051,6 +1051,7 @@
%s planète
soumissions non disponibles
aucune discussion précédente
+ aucun commentaire disponible
%s
diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml
index c75d0b674e..855313a00a 100644
--- a/app/src/main/res/values-ne/strings.xml
+++ b/app/src/main/res/values-ne/strings.xml
@@ -1051,6 +1051,7 @@
%s ग्रह
पेशाहरू उपलब्ध छैनन्
अघिल्ला कुराकानीहरू छैनन्
+ कुनै प्रतिक्रिया उपलब्ध छैन
%s
diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml
index 38c3ada43d..ccedfc34df 100644
--- a/app/src/main/res/values-so/strings.xml
+++ b/app/src/main/res/values-so/strings.xml
@@ -1051,6 +1051,7 @@
%s Meerah
soo gudbin lama heli karo
ma jiraan wada sheekaysi hore
+ wax jawaab celin ah lama hayo
%s
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 599bfa36ff..f35f36b6e2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1051,6 +1051,7 @@
%s\'s Planet
submissions not available
no previous chats
+ no feedback available
%s