Merge pull request #408 from Naveen3Singh/photo_picker
Allow attaching captured photos from camera
This commit is contained in:
commit
da11ce3c3e
|
@ -10,12 +10,12 @@ if (keystorePropertiesFile.exists()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 31
|
compileSdkVersion 33
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.simplemobiletools.smsmessenger"
|
applicationId "com.simplemobiletools.smsmessenger"
|
||||||
minSdkVersion 22
|
minSdkVersion 22
|
||||||
targetSdkVersion 31
|
targetSdkVersion 33
|
||||||
versionCode 60
|
versionCode 60
|
||||||
versionName "5.15.0"
|
versionName "5.15.0"
|
||||||
setProperty("archivesBaseName", "sms-messenger")
|
setProperty("archivesBaseName", "sms-messenger")
|
||||||
|
@ -63,10 +63,10 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:4f9c2f94ff'
|
implementation 'com.github.SimpleMobileTools:Simple-Commons:82a8684cd8'
|
||||||
implementation 'org.greenrobot:eventbus:3.3.1'
|
implementation 'org.greenrobot:eventbus:3.3.1'
|
||||||
implementation 'com.github.tibbi:IndicatorFastScroll:4524cd0b61'
|
implementation 'com.github.tibbi:IndicatorFastScroll:4524cd0b61'
|
||||||
implementation 'com.github.tibbi:android-smsmms:46e5685db9'
|
implementation 'com.github.tibbi:android-smsmms:4cdacdb701'
|
||||||
implementation "me.leolin:ShortcutBadger:1.1.22"
|
implementation "me.leolin:ShortcutBadger:1.1.22"
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import android.media.MediaMetadataRetriever
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.ContactsContract
|
import android.provider.ContactsContract
|
||||||
|
import android.provider.MediaStore
|
||||||
import android.provider.Telephony
|
import android.provider.Telephony
|
||||||
import android.telephony.SmsMessage
|
import android.telephony.SmsMessage
|
||||||
import android.telephony.SubscriptionManager
|
import android.telephony.SubscriptionManager
|
||||||
|
@ -38,9 +39,11 @@ import com.google.gson.reflect.TypeToken
|
||||||
import com.klinker.android.send_message.Transaction
|
import com.klinker.android.send_message.Transaction
|
||||||
import com.klinker.android.send_message.Utils.getNumPages
|
import com.klinker.android.send_message.Utils.getNumPages
|
||||||
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
||||||
|
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||||
import com.simplemobiletools.commons.extensions.*
|
import com.simplemobiletools.commons.extensions.*
|
||||||
import com.simplemobiletools.commons.helpers.*
|
import com.simplemobiletools.commons.helpers.*
|
||||||
import com.simplemobiletools.commons.models.PhoneNumber
|
import com.simplemobiletools.commons.models.PhoneNumber
|
||||||
|
import com.simplemobiletools.commons.models.RadioItem
|
||||||
import com.simplemobiletools.commons.models.SimpleContact
|
import com.simplemobiletools.commons.models.SimpleContact
|
||||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||||
import com.simplemobiletools.smsmessenger.R
|
import com.simplemobiletools.smsmessenger.R
|
||||||
|
@ -57,6 +60,7 @@ import kotlinx.android.synthetic.main.item_selected_contact.view.*
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
|
@ -64,6 +68,10 @@ class ThreadActivity : SimpleActivity() {
|
||||||
private val MIN_DATE_TIME_DIFF_SECS = 300
|
private val MIN_DATE_TIME_DIFF_SECS = 300
|
||||||
private val PICK_ATTACHMENT_INTENT = 1
|
private val PICK_ATTACHMENT_INTENT = 1
|
||||||
private val PICK_SAVE_FILE_INTENT = 11
|
private val PICK_SAVE_FILE_INTENT = 11
|
||||||
|
private val TAKE_PHOTO_INTENT = 42
|
||||||
|
|
||||||
|
private val TYPE_TAKE_PHOTO = 12
|
||||||
|
private val TYPE_CHOOSE_PHOTO = 13
|
||||||
|
|
||||||
private var threadId = 0L
|
private var threadId = 0L
|
||||||
private var currentSIMCardIndex = 0
|
private var currentSIMCardIndex = 0
|
||||||
|
@ -78,6 +86,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
private var attachmentSelections = mutableMapOf<String, AttachmentSelection>()
|
private var attachmentSelections = mutableMapOf<String, AttachmentSelection>()
|
||||||
private val imageCompressor by lazy { ImageCompressor(this) }
|
private val imageCompressor by lazy { ImageCompressor(this) }
|
||||||
private var lastAttachmentUri: String? = null
|
private var lastAttachmentUri: String? = null
|
||||||
|
private var capturedImageUri: Uri? = null
|
||||||
private var loadingOlderMessages = false
|
private var loadingOlderMessages = false
|
||||||
private var allMessagesFetched = false
|
private var allMessagesFetched = false
|
||||||
private var oldestMessageDate = -1
|
private var oldestMessageDate = -1
|
||||||
|
@ -190,26 +199,14 @@ class ThreadActivity : SimpleActivity() {
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, resultData)
|
super.onActivityResult(requestCode, resultCode, resultData)
|
||||||
if (requestCode == PICK_ATTACHMENT_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
|
if (resultCode != Activity.RESULT_OK) return
|
||||||
|
|
||||||
|
if (requestCode == TAKE_PHOTO_INTENT) {
|
||||||
|
addAttachment(capturedImageUri!!)
|
||||||
|
} else if (requestCode == PICK_ATTACHMENT_INTENT && resultData != null && resultData.data != null) {
|
||||||
addAttachment(resultData.data!!)
|
addAttachment(resultData.data!!)
|
||||||
} else if (requestCode == PICK_SAVE_FILE_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
|
} else if (requestCode == PICK_SAVE_FILE_INTENT && resultData != null && resultData.data != null) {
|
||||||
val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
saveAttachment(resultData)
|
||||||
applicationContext.contentResolver.takePersistableUriPermission(resultData.data!!, takeFlags)
|
|
||||||
var inputStream: InputStream? = null
|
|
||||||
var outputStream: OutputStream? = null
|
|
||||||
try {
|
|
||||||
inputStream = contentResolver.openInputStream(Uri.parse(lastAttachmentUri))
|
|
||||||
outputStream = contentResolver.openOutputStream(Uri.parse(resultData.dataString!!), "rwt")
|
|
||||||
inputStream!!.copyTo(outputStream!!)
|
|
||||||
outputStream.flush()
|
|
||||||
toast(R.string.file_saved)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
showErrorToast(e)
|
|
||||||
} finally {
|
|
||||||
inputStream?.close()
|
|
||||||
outputStream?.close()
|
|
||||||
}
|
|
||||||
lastAttachmentUri = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,7 +455,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
|
|
||||||
thread_type_message.setText(intent.getStringExtra(THREAD_TEXT))
|
thread_type_message.setText(intent.getStringExtra(THREAD_TEXT))
|
||||||
thread_add_attachment.setOnClickListener {
|
thread_add_attachment.setOnClickListener {
|
||||||
launchPickPhotoVideoIntent()
|
takeOrPickPhotoVideo()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intent.extras?.containsKey(THREAD_ATTACHMENT_URI) == true) {
|
if (intent.extras?.containsKey(THREAD_ATTACHMENT_URI) == true) {
|
||||||
|
@ -730,6 +727,36 @@ class ThreadActivity : SimpleActivity() {
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun takeOrPickPhotoVideo() {
|
||||||
|
val items = arrayListOf(
|
||||||
|
RadioItem(TYPE_TAKE_PHOTO, getString(R.string.take_photo)),
|
||||||
|
RadioItem(TYPE_CHOOSE_PHOTO, getString(R.string.choose_photo))
|
||||||
|
)
|
||||||
|
RadioGroupDialog(this, items = items) {
|
||||||
|
val checkedId = it as Int
|
||||||
|
if (checkedId == TYPE_TAKE_PHOTO) {
|
||||||
|
launchTakePhotoIntent()
|
||||||
|
} else if (checkedId == TYPE_CHOOSE_PHOTO) {
|
||||||
|
launchPickPhotoVideoIntent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchTakePhotoIntent() {
|
||||||
|
val imageFile = createImageFile()
|
||||||
|
capturedImageUri = getMyFileUri(imageFile)
|
||||||
|
try {
|
||||||
|
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
|
||||||
|
putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri)
|
||||||
|
}
|
||||||
|
startActivityForResult(intent, TAKE_PHOTO_INTENT)
|
||||||
|
} catch (e: ActivityNotFoundException) {
|
||||||
|
showErrorToast(getString(R.string.no_app_found))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
showErrorToast(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun launchPickPhotoVideoIntent() {
|
private fun launchPickPhotoVideoIntent() {
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
val mimeTypes = arrayOf("image/*", "video/*")
|
val mimeTypes = arrayOf("image/*", "video/*")
|
||||||
|
@ -832,6 +859,26 @@ class ThreadActivity : SimpleActivity() {
|
||||||
checkSendMessageAvailability()
|
checkSendMessageAvailability()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun saveAttachment(resultData: Intent) {
|
||||||
|
val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||||
|
applicationContext.contentResolver.takePersistableUriPermission(resultData.data!!, takeFlags)
|
||||||
|
var inputStream: InputStream? = null
|
||||||
|
var outputStream: OutputStream? = null
|
||||||
|
try {
|
||||||
|
inputStream = contentResolver.openInputStream(Uri.parse(lastAttachmentUri))
|
||||||
|
outputStream = contentResolver.openOutputStream(Uri.parse(resultData.dataString!!), "rwt")
|
||||||
|
inputStream!!.copyTo(outputStream!!)
|
||||||
|
outputStream.flush()
|
||||||
|
toast(R.string.file_saved)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
showErrorToast(e)
|
||||||
|
} finally {
|
||||||
|
inputStream?.close()
|
||||||
|
outputStream?.close()
|
||||||
|
}
|
||||||
|
lastAttachmentUri = null
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkSendMessageAvailability() {
|
private fun checkSendMessageAvailability() {
|
||||||
if (thread_type_message.text!!.isNotEmpty() || (attachmentSelections.isNotEmpty() && !attachmentSelections.values.any { it.isPending })) {
|
if (thread_type_message.text!!.isNotEmpty() || (attachmentSelections.isNotEmpty() && !attachmentSelections.values.any { it.isPending })) {
|
||||||
thread_send_message.isClickable = true
|
thread_send_message.isClickable = true
|
||||||
|
@ -1084,4 +1131,13 @@ class ThreadActivity : SimpleActivity() {
|
||||||
}
|
}
|
||||||
thread_send_message.setText(stringId)
|
thread_send_message.setText(stringId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createImageFile(): File {
|
||||||
|
val outputDirectory = File(cacheDir, "captured").apply {
|
||||||
|
if (!exists()) {
|
||||||
|
mkdirs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return File.createTempFile("IMG_", ".jpg", outputDirectory)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ class DirectReplyReceiver : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
val address = intent.getStringExtra(THREAD_NUMBER)
|
val address = intent.getStringExtra(THREAD_NUMBER)
|
||||||
val threadId = intent.getLongExtra(THREAD_ID, 0L)
|
val threadId = intent.getLongExtra(THREAD_ID, 0L)
|
||||||
var msg = RemoteInput.getResultsFromIntent(intent).getCharSequence(REPLY)?.toString() ?: return
|
var msg = RemoteInput.getResultsFromIntent(intent)?.getCharSequence(REPLY)?.toString() ?: return
|
||||||
|
|
||||||
msg = context.removeDiacriticsIfNeeded(msg)
|
msg = context.removeDiacriticsIfNeeded(msg)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<paths>
|
<paths>
|
||||||
<cache-path name="compressed_files" path="compressed/"/>
|
<cache-path name="compressed_files" path="compressed/"/>
|
||||||
|
<cache-path name="captured_files" path="captured/"/>
|
||||||
</paths>
|
</paths>
|
||||||
|
|
Loading…
Reference in New Issue