From c04db76af9eb23fdfa3937aaf1a4e2f5da658dd3 Mon Sep 17 00:00:00 2001 From: bruhascended Date: Fri, 18 Sep 2020 18:03:48 +0530 Subject: [PATCH] fixed receive mms --- MMSHandler.java | 100 ---------- app/build.gradle | 1 + .../sms/data/IncomingMMSManager.kt | 182 ++++++++++++++++++ .../sms/data/IncomingSMSManager.kt | 2 +- .../bruhascended/sms/services/MMSReceiver.kt | 9 +- .../sms/ui/MediaPreviewManager.kt | 55 +++--- .../sms/ui/MessageNotificationManager.kt | 89 +++++---- .../conversastion/MessageListViewAdaptor.kt | 98 ++++++---- .../main/res/drawable-xxhdpi/github_raw.png | Bin 4268 -> 0 bytes .../main/res/drawable-xxhdpi/github_raw.webp | Bin 0 -> 1584 bytes app/src/main/res/drawable/bg_message.xml | 3 +- app/src/main/res/drawable/bg_mms.xml | 25 +++ app/src/main/res/layout/item_message.xml | 89 +++++++-- app/src/main/res/layout/item_message_out.xml | 50 +++-- app/src/main/res/values/strings.xml | 1 - gradle.properties | 21 +- settings.gradle | 2 - 17 files changed, 451 insertions(+), 276 deletions(-) delete mode 100644 MMSHandler.java create mode 100644 app/src/main/java/com/bruhascended/sms/data/IncomingMMSManager.kt delete mode 100644 app/src/main/res/drawable-xxhdpi/github_raw.png create mode 100644 app/src/main/res/drawable-xxhdpi/github_raw.webp create mode 100644 app/src/main/res/drawable/bg_mms.xml diff --git a/MMSHandler.java b/MMSHandler.java deleted file mode 100644 index ff2e0fa..0000000 --- a/MMSHandler.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.bruhascended.sms; - -import android.content.Context; -import android.webkit.MimeTypeMap; - -import androidx.room.Room; - -import com.bruhascended.db.Message; -import com.bruhascended.db.MessageDao; -import com.bruhascended.db.MessageDatabase; -import com.google.android.mms.ContentType; -import com.google.android.mms.pdu_alt.MultimediaMessagePdu; -import com.google.android.mms.pdu_alt.PduBody; -import com.google.android.mms.pdu_alt.PduPart; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; - -import io.michaelrocks.libphonenumber.android.NumberParseException; -import io.michaelrocks.libphonenumber.android.PhoneNumberUtil; -import io.michaelrocks.libphonenumber.android.Phonenumber; - -public class MMSHandler { - private static String saveMedia(String content, Context mContext, Long date, String typeString) throws IOException { - String name = date.toString() + "." + MimeTypeMap.getSingleton().getExtensionFromMimeType(typeString); - File destination = new File(mContext.getFilesDir(), name); - OutputStreamWriter output = new OutputStreamWriter( new FileOutputStream(destination)); - output.write(content); - output.flush(); - return destination.getAbsolutePath(); - } - - private static String getRaw(Context context, String number) { - if (number.startsWith("+")) { - try { - PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.createInstance(context); - Phonenumber.PhoneNumber numberProto = phoneNumberUtil.parse(number, ""); - return Long.toString(numberProto.getNationalNumber()).replaceAll("\\s", ""); - } catch (NumberParseException e) { - return number.replaceAll("\\s", ""); - } - } else return number.replaceAll("\\s", ""); - } - - public static void processPduAttachments(Context context, MultimediaMessagePdu pdu) { - PduBody body = pdu.getBody(); - if (body != null) { - int partsNum = body.getPartsNum(); - for (int i = 0; i < partsNum; i++) { - try { - PduPart part = body.getPart(i); - if (part == null || part.getData() == null || part.getContentType() == null || part.getName() == null) - continue; - String partType = new String(part.getContentType()); - String address = pdu.getFrom().toString(); - String name = getRaw(context, address); - long date = System.currentTimeMillis(); - - MessageDao db = Room.databaseBuilder( - context.getApplicationContext(), - MessageDatabase.class, - name - ).build().manager(); - Message m = null; - if (ContentType.isTextType(partType)) { - m = new Message( - null, - name, - body.toString(), - 1, - date, - -1, - false, - null - ); - } else if (ContentType.isImageType(partType) || - ContentType.isVideoType(partType) || - ContentType.isAudioType(partType)) { - m = new Message( - null, - name, - "", - 1, - date, - -1, - false, - saveMedia(body.toString(), context, date, partType) - ); - } - if (m != null) db.insert(m); - } catch (Exception e) { - e.printStackTrace(); - // Bad part shouldn't ruin the party for the other parts - } - } - } - } -} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0499cc3..fc66d27 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -79,6 +79,7 @@ dependencies { implementation 'com.mikhaellopez:circularprogressbar:3.0.3' implementation 'io.michaelrocks:libphonenumber-android:8.12.6' + implementation 'com.squareup.picasso:picasso:2.71828' implementation 'com.klinkerapps:android-smsmms:5.2.5' } \ No newline at end of file diff --git a/app/src/main/java/com/bruhascended/sms/data/IncomingMMSManager.kt b/app/src/main/java/com/bruhascended/sms/data/IncomingMMSManager.kt new file mode 100644 index 0000000..dd51d5e --- /dev/null +++ b/app/src/main/java/com/bruhascended/sms/data/IncomingMMSManager.kt @@ -0,0 +1,182 @@ +package com.bruhascended.sms.data + +import android.annotation.SuppressLint +import android.content.Context +import android.net.Uri +import android.webkit.MimeTypeMap +import androidx.room.Room +import com.bruhascended.sms.db.Conversation +import com.bruhascended.sms.db.ConversationDatabase +import com.bruhascended.sms.db.Message +import com.bruhascended.sms.db.MessageDatabase +import com.bruhascended.sms.ui.conversationDao +import com.bruhascended.sms.ui.conversationSender +import com.bruhascended.sms.ui.isMainViewModelNull +import com.bruhascended.sms.ui.main.MainViewModel +import com.bruhascended.sms.ui.mainViewModel +import java.io.* + + +class IncomingMMSManager(private val context: Context) { + private var date: Long = 0 + + @SuppressLint("Recycle") + private fun getAddressNumber(id: String): String? { + val selection = "type=137 AND msg_id=$id" + val uriAddress = Uri.parse("content://mms/${id}/addr") + val cursor = context.contentResolver.query( + uriAddress, arrayOf("address"), selection, null, null + )!! + var address = "" + if (cursor.moveToFirst()) { + do { + address = cursor.getString(cursor.getColumnIndex("address")) + if (address != null) break + } while (cursor.moveToNext()) + } + cursor.close() + return address + } + + private fun getMmsText(id: String): String { + val partURI = Uri.parse("content://mms/part/$id") + val inp: InputStream? = context.contentResolver.openInputStream(partURI) + val sb = StringBuilder() + if (inp != null) { + val isr = InputStreamReader(inp, "UTF-8") + val reader = BufferedReader(isr) + var temp: String? = reader.readLine() + while (temp != null) { + sb.append(temp) + temp = reader.readLine() + } + } + return sb.toString() + } + + private fun saveFile(_id: String, typeString: String): String { + val partURI = Uri.parse("content://mms/part/$_id") + val ext = MimeTypeMap.getSingleton().getExtensionFromMimeType(typeString) + val name = "$date.$ext" + val destination = File(context.filesDir, name) + val output = FileOutputStream(destination) + val input = context.contentResolver.openInputStream(partURI) ?: return "" + val buffer = ByteArray(4 * 1024) + var read: Int + while (input.read(buffer).also { read = it } != -1) { + output.write(buffer, 0, read) + } + output.flush() + return destination.absolutePath + } + + @SuppressLint("Recycle") + fun putMMS(uri: Uri) : Pair { + date = System.currentTimeMillis() + val mmsId = uri.toString().split("/").last() + + val selectionPart = "mid=$mmsId" + val partUri = Uri.parse("content://mms/part") + val cursor = context.contentResolver.query( + partUri, null, + selectionPart, null, null + )!! + var body = "" + var file: String? = null + if (cursor.moveToFirst()) { + do { + val partId: String = cursor.getString(cursor.getColumnIndex("_id")) + val typeString = cursor.getString(cursor.getColumnIndex("ct")) + if ("text/plain" == typeString) { + body = getMmsText(partId) + } else if ( + typeString.startsWith("video") || + typeString.startsWith("image") || + typeString.startsWith("audio") + ) { + file = saveFile(partId, typeString) + } + } while (cursor.moveToNext()) + } + cursor.close() + + val sender = getAddressNumber(mmsId)!! + + val rawNumber = ContactsManager(context).getRaw(sender) + val senderNameMap = ContactsManager(context).getContactsHashMap() + + val message = Message( + null, + sender, + body, + 1, + date, + 0, + false, + file + ) + + if (isMainViewModelNull()) { + mainViewModel = MainViewModel() + mainViewModel.daos = Array(6){ + Room.databaseBuilder( + context, ConversationDatabase::class.java, + context.resources.getString(labelText[it]) + ).allowMainThreadQueries().build().manager() + } + } + + var conversation: Conversation? = null + for (i in 0..4) { + val got = mainViewModel.daos[i].findBySender(rawNumber) + if (got.isNotEmpty()) { + conversation = got.first() + for (item in got.slice(1 until got.size)) + mainViewModel.daos[i].delete(item) + break + } + } + + conversation = if (conversation != null) { + conversation.apply { + read = false + time = message.time + lastSMS = message.text + lastMMS = true + label = 0 + forceLabel = 0 + name = senderNameMap[rawNumber] + mainViewModel.daos[0].update(this) + } + conversation + } else { + val con = Conversation( + null, + rawNumber, + senderNameMap[rawNumber], + "", + false, + message.time, + message.text, + 0, + 0, + FloatArray(5) { + if (it == 0) 1f else 0f + }, + lastMMS = true + ) + mainViewModel.daos[0].insert(con) + con.id = mainViewModel.daos[0].findBySender(rawNumber).first().id + con + } + + val mdb = if (conversationSender == rawNumber) conversationDao + else Room.databaseBuilder( + context, MessageDatabase::class.java, rawNumber + ).build().manager() + + mdb.insert(message) + + return mdb.search(message.time).first() to conversation + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bruhascended/sms/data/IncomingSMSManager.kt b/app/src/main/java/com/bruhascended/sms/data/IncomingSMSManager.kt index cc4010b..bd158fb 100644 --- a/app/src/main/java/com/bruhascended/sms/data/IncomingSMSManager.kt +++ b/app/src/main/java/com/bruhascended/sms/data/IncomingSMSManager.kt @@ -91,7 +91,7 @@ class IncomingSMSManager(context: Context) { prediction, -1, FloatArray(5) { - if (it == 0) 1f else 0f + if (it == prediction) 1f else 0f } ) mainViewModel.daos[prediction].insert(con) diff --git a/app/src/main/java/com/bruhascended/sms/services/MMSReceiver.kt b/app/src/main/java/com/bruhascended/sms/services/MMSReceiver.kt index 53038d7..6b42540 100644 --- a/app/src/main/java/com/bruhascended/sms/services/MMSReceiver.kt +++ b/app/src/main/java/com/bruhascended/sms/services/MMSReceiver.kt @@ -2,17 +2,16 @@ package com.bruhascended.sms.services import android.content.Context import android.net.Uri +import com.bruhascended.sms.data.IncomingMMSManager +import com.bruhascended.sms.ui.MessageNotificationManager import com.klinker.android.send_message.MmsReceivedReceiver class MMSReceiver : MmsReceivedReceiver() { override fun onMessageReceived(context: Context, uri: Uri) { - val k = 1 - val p = 1+k + MessageNotificationManager(context).sendSmsNotification(IncomingMMSManager(context).putMMS(uri)) } - override fun onError(p0: Context?, p1: String?) { - TODO("Not yet implemented") - } + override fun onError(p0: Context?, p1: String?) {} } diff --git a/app/src/main/java/com/bruhascended/sms/ui/MediaPreviewManager.kt b/app/src/main/java/com/bruhascended/sms/ui/MediaPreviewManager.kt index 894f486..420c08d 100644 --- a/app/src/main/java/com/bruhascended/sms/ui/MediaPreviewManager.kt +++ b/app/src/main/java/com/bruhascended/sms/ui/MediaPreviewManager.kt @@ -93,35 +93,38 @@ class MediaPreviewManager( playPauseButton.visibility = View.VISIBLE mp.apply { setDataSource(mActivity, mmsURI) - prepare() - seekBar.max = mp.duration / 500 + prepareAsync() + setOnPreparedListener { + seekBar.max = mp.duration / 500 - val mHandler = Handler(mActivity.mainLooper) - mActivity.runOnUiThread(object : Runnable { - override fun run() { - seekBar.progress = currentPosition / 500 - mHandler.postDelayed(this, 500) - } - }) + val mHandler = Handler(mActivity.mainLooper) + mActivity.runOnUiThread(object : Runnable { + override fun run() { + seekBar.progress = currentPosition / 500 + mHandler.postDelayed(this, 500) + } + }) - seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { - override fun onStopTrackingTouch(seekBar: SeekBar) {} - override fun onStartTrackingTouch(seekBar: SeekBar) {} - override fun onProgressChanged( - seekBar: SeekBar, progress: Int, fromUser: Boolean - ) { - if (fromUser) seekTo(progress * 500) - } - }) + seekBar.setOnSeekBarChangeListener(object : + SeekBar.OnSeekBarChangeListener { + override fun onStopTrackingTouch(seekBar: SeekBar) {} + override fun onStartTrackingTouch(seekBar: SeekBar) {} + override fun onProgressChanged( + seekBar: SeekBar, progress: Int, fromUser: Boolean + ) { + if (fromUser) seekTo(progress * 500) + } + }) - playPauseButton.apply { - setOnClickListener { - if (isPlaying) { - pause() - setImageResource(R.drawable.ic_play) - } else { - start() - setImageResource(R.drawable.ic_pause) + playPauseButton.apply { + setOnClickListener { + if (isPlaying) { + pause() + setImageResource(R.drawable.ic_play) + } else { + start() + setImageResource(R.drawable.ic_pause) + } } } } diff --git a/app/src/main/java/com/bruhascended/sms/ui/MessageNotificationManager.kt b/app/src/main/java/com/bruhascended/sms/ui/MessageNotificationManager.kt index 68bedae..4bc58c7 100644 --- a/app/src/main/java/com/bruhascended/sms/ui/MessageNotificationManager.kt +++ b/app/src/main/java/com/bruhascended/sms/ui/MessageNotificationManager.kt @@ -47,50 +47,57 @@ class MessageNotificationManager(private val mContext: Context) { ) val otp = getOtp(message.text) + val copyPI = PendingIntent.getBroadcast(mContext, 0, Intent("COPY"), 0) + val deletePI = PendingIntent.getBroadcast(mContext, 0, Intent("DELETE"), 0) - val builder = if (otp == null) { - NotificationCompat.Builder(mContext, conversation.label.toString()) - .setStyle(NotificationCompat.BigTextStyle().bigText(message.text)) - .setContentTitle(conversation.name ?: message.sender) - } else { - val copyPI = PendingIntent.getBroadcast(mContext, 0, Intent("COPY"), 0) - val deletePI = PendingIntent.getBroadcast(mContext, 0, Intent("DELETE"), 0) - - mContext.applicationContext.registerReceiver(object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val clip = ClipData.newPlainText("OTP", otp) - clipboard.setPrimaryClip(clip) - Toast.makeText(context, "Copied", Toast.LENGTH_LONG).show() - } - }, IntentFilter("COPY")) - mContext.applicationContext.registerReceiver(object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - val mdb = Room.databaseBuilder( - mContext, MessageDatabase::class.java, conversation.sender - ).allowMainThreadQueries().build().manager() - mdb.delete(message) - if (mdb.loadAllSync().isEmpty()) { - if (isMainViewModelNull()) { - Room.databaseBuilder( - mContext, ConversationDatabase::class.java, - mContext.resources.getString(labelText[conversation.label]) - ).allowMainThreadQueries().build().manager() - } else { - mainViewModel.daos[conversation.label] - }.delete(conversation) - } - NotificationManagerCompat.from(mContext).cancel(conversation.id!!.toInt()) - Toast.makeText(context, "Deleted", Toast.LENGTH_LONG).show() - mContext.applicationContext.unregisterReceiver(this) + mContext.applicationContext.registerReceiver(object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText("OTP", otp) + clipboard.setPrimaryClip(clip) + Toast.makeText(context, "Copied", Toast.LENGTH_LONG).show() + } + }, IntentFilter("COPY")) + mContext.applicationContext.registerReceiver(object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + val mdb = Room.databaseBuilder( + mContext, MessageDatabase::class.java, conversation.sender + ).allowMainThreadQueries().build().manager() + mdb.delete(message) + if (mdb.loadAllSync().isEmpty()) { + if (isMainViewModelNull()) { + Room.databaseBuilder( + mContext, ConversationDatabase::class.java, + mContext.resources.getString(labelText[conversation.label]) + ).allowMainThreadQueries().build().manager() + } else { + mainViewModel.daos[conversation.label] + }.delete(conversation) } - }, IntentFilter("DELETE")) + NotificationManagerCompat.from(mContext).cancel(conversation.id!!.toInt()) + Toast.makeText(context, "Deleted", Toast.LENGTH_LONG).show() + mContext.applicationContext.unregisterReceiver(this) + } + }, IntentFilter("DELETE")) - NotificationCompat.Builder(mContext, conversation.label.toString()) - .setContentTitle("OTP from ${message.sender}") - .setStyle(NotificationCompat.BigTextStyle().bigText(otp)) - .addAction(R.drawable.ic_content_copy, mContext.getString(R.string.copy_otp), copyPI) - .addAction(R.drawable.ic_baseline_delete_24, mContext.getString(R.string.delete), deletePI) + val builder = when { + message.path != null -> { + NotificationCompat.Builder(mContext, conversation.label.toString()) + .setStyle(NotificationCompat.BigTextStyle().bigText(message.text)) + .setContentTitle("Media from ${conversation.name ?: message.sender}") + } + otp == null -> { + NotificationCompat.Builder(mContext, conversation.label.toString()) + .setStyle(NotificationCompat.BigTextStyle().bigText(message.text)) + .setContentTitle(conversation.name ?: message.sender) + } + else -> { + NotificationCompat.Builder(mContext, conversation.label.toString()) + .setContentTitle("OTP from ${message.sender}") + .setStyle(NotificationCompat.BigTextStyle().bigText(otp)) + .addAction(R.drawable.ic_content_copy, mContext.getString(R.string.copy_otp), copyPI) + .addAction(R.drawable.ic_baseline_delete_24, mContext.getString(R.string.delete), deletePI) + } }.setSmallIcon(R.drawable.message) .setAutoCancel(true) .setContentIntent(pendingIntent) diff --git a/app/src/main/java/com/bruhascended/sms/ui/conversastion/MessageListViewAdaptor.kt b/app/src/main/java/com/bruhascended/sms/ui/conversastion/MessageListViewAdaptor.kt index 2455168..987ac0a 100644 --- a/app/src/main/java/com/bruhascended/sms/ui/conversastion/MessageListViewAdaptor.kt +++ b/app/src/main/java/com/bruhascended/sms/ui/conversastion/MessageListViewAdaptor.kt @@ -20,6 +20,7 @@ import androidx.core.content.FileProvider import androidx.core.view.doOnDetach import com.bruhascended.sms.R import com.bruhascended.sms.db.Message +import com.squareup.picasso.Picasso import java.io.File import java.io.FileOutputStream import java.util.* @@ -31,6 +32,26 @@ class MessageListViewAdaptor(context: Context, data: List) : BaseAdapte private var messages: List = data private var mSelectedItemsIds = SparseBooleanArray() private val previewCache: MutableMap = mutableMapOf() + private val picasso = Picasso.get() + + init { + Thread { + for (position in data.indices) { + val sms = data[position] + val p = sms.path + if (p != null && getMimeType(p).startsWith("video")) { + val retriever = MediaMetadataRetriever() + retriever.setDataSource(p) + val length = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)!!.toLong() + val bm = retriever.getFrameAtTime( + length / 2, + MediaMetadataRetriever.OPTION_CLOSEST + )!! + previewCache[position] = saveCache(bm, getItem(position).time) + } + } + }.start() + } private fun displayTime(time: Long): String { val smsTime = Calendar.getInstance() @@ -77,7 +98,8 @@ class MessageListViewAdaptor(context: Context, data: List) : BaseAdapte contentLayout: LinearLayout, position: Int ) { mediaLayout.visibility = View.VISIBLE - contentLayout.setBackgroundResource(R.drawable.bg_mms_out) + if (getItem(position).type == 1) contentLayout.setBackgroundResource(R.drawable.bg_mms) + else contentLayout.setBackgroundResource(R.drawable.bg_mms_out) val data = Uri.parse(path) val mmsTypeString = getMimeType(path) val contentUri = FileProvider.getUriForFile( @@ -94,7 +116,7 @@ class MessageListViewAdaptor(context: Context, data: List) : BaseAdapte when { mmsTypeString.startsWith("image") -> { image.visibility = View.VISIBLE - image.setImageURI(data) + picasso.load(File(data.toString())).into(image) image.setOnClickListener{ mContext.startActivity(contentIntent) } @@ -105,36 +127,36 @@ class MessageListViewAdaptor(context: Context, data: List) : BaseAdapte playPause.visibility = View.VISIBLE setDataSource(mContext, data) prepareAsync() - slider.max = duration / 500 + setOnPreparedListener { + slider.max = duration / 500 - val mHandler = Handler(mContext.mainLooper) - (mContext as Activity).runOnUiThread(object : Runnable { - override fun run() { - slider.progress = currentPosition / 500 - mHandler.postDelayed(this, 500) - } - }) - - slider.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { - override fun onStopTrackingTouch(seekBar: SeekBar) {} - override fun onStartTrackingTouch(seekBar: SeekBar) {} - override fun onProgressChanged( - seekBar: SeekBar, progress: Int, fromUser: Boolean - ) { - if (fromUser) seekTo(progress * 500) - } - }) - - playPause.setOnClickListener { - if (isPlaying) { - pause() - playPause.setImageResource(R.drawable.ic_play) - } else { - start() - slider.doOnDetach { - reset() + val mHandler = Handler(mContext.mainLooper) + (mContext as Activity).runOnUiThread(object : Runnable { + override fun run() { + slider.progress = currentPosition / 500 + mHandler.postDelayed(this, 500) + } + }) + + slider.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { + override fun onStopTrackingTouch(s: SeekBar) {} + override fun onStartTrackingTouch(s: SeekBar) {} + override fun onProgressChanged( + seekBar: SeekBar, progress: Int, fromUser: Boolean + ) { + if (fromUser) seekTo(progress * 500) + } + }) + + playPause.setOnClickListener { + if (isPlaying) { + pause() + playPause.setImageResource(R.drawable.ic_play) + } else { + start() + slider.doOnDetach { reset() } + playPause.setImageResource(R.drawable.ic_pause) } - playPause.setImageResource(R.drawable.ic_pause) } } } @@ -143,19 +165,18 @@ class MessageListViewAdaptor(context: Context, data: List) : BaseAdapte videoPlayPause.visibility = View.VISIBLE image.visibility = View.VISIBLE if (previewCache.containsKey(position)) - image.setImageURI(Uri.parse(previewCache[position])) + picasso.load(File(previewCache[position]!!)).into(image) else Thread { val retriever = MediaMetadataRetriever() retriever.setDataSource(path) val length = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)!!.toLong() - previewCache[position] = saveCache(retriever.getFrameAtTime( + val bm = retriever.getFrameAtTime( length / 2, MediaMetadataRetriever.OPTION_CLOSEST - )!!, getItem(position).time) - previewCache[position]!! - + )!! + previewCache[position] = saveCache(bm, getItem(position).time) (mContext as Activity).runOnUiThread { - image.setImageURI(Uri.parse(previewCache[position])) + picasso.load(File(previewCache[position]!!)).into(image) } }.start() @@ -169,7 +190,8 @@ class MessageListViewAdaptor(context: Context, data: List) : BaseAdapte override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { val message = messages[position] val layoutInflater = LayoutInflater.from(mContext) - val root = if (messages[position].type == 1) + + val root = if (messages[position].type == 1) layoutInflater.inflate(R.layout.item_message, parent, false) else layoutInflater.inflate(R.layout.item_message_out, parent, false) @@ -187,7 +209,7 @@ class MessageListViewAdaptor(context: Context, data: List) : BaseAdapte else when (message.type) { 2 -> "sent" 5 -> "failed" - 6 -> "sending" + 6 -> "queued" else -> "unknown" } } diff --git a/app/src/main/res/drawable-xxhdpi/github_raw.png b/app/src/main/res/drawable-xxhdpi/github_raw.png deleted file mode 100644 index ea6ff545a246caa64074ba809bbc86fcb8589071..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4268 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 XLyRvu{aX3a{{tgEGu={c*U0|?Dtn-9 diff --git a/app/src/main/res/drawable-xxhdpi/github_raw.webp b/app/src/main/res/drawable-xxhdpi/github_raw.webp new file mode 100644 index 0000000000000000000000000000000000000000..943b8992b870517fa89c6f01c4667f1107c9add3 GIT binary patch literal 1584 zcmV-02G99YNk&E}1^@t8MM6+kP&iB*1^@srcfcJG|E8dA8zv;iA8en-U@pdjK++a( z`^~0pgXdDUX8^Zg4+5d#sKFNF;d_?aSfDeZP{3fuagiMfxj}RA1hkq$_WqUbQ&79M z&5$HTX;9r`qcyf|+qP}nSliy-9oyACwx=`%Ms)uz3HCp$ z&N*U&-?_t001aaRb4AEE@}3&rC?6A@4-jkU?hprTB}7zuW6bG6=KhuAyEaX&R)K7) zhvQf7&wSt%+gyf;w+6sNt_C4sBIJUo{)xOl*K|x~pkBw-f8?EP$lQh!0654+@D{{F za_{pqsn(MFM-aDzV$(U~IRFjML*R6w&|Q#YCO8ISONmUue-gAJSukf!;K5`I^hVex zCO{bM{l1@pip%Ne6$Ab9o~j8T?51Bg1oo;rt>n-<^xFZ2E1k}QMf8h+S%-84AFZDU zh8ZPRf^8=QZUb9c;t154pb5}I9VMc045+X%Gh(9xARA`X2Z29ehCB#_mS_vmyQ-$B z`VMFdqr*U-GGl%UWEtfGwKInW%4M|>_8uA3gF!n0=p&PS3}lxAjWfx3prr?Z(oB*L zbl_K*M8G7$0vLN5<{mTZ1DMmdU?OITz}(7#Ic}CyFgbCUQ)W2}6GzyHSt2mdcg%8M zrH5vDtWw-(5`O}y00wKBq&C79#!-puc0i<0m3<^n1jH%j1EEF@S7oc z1L_c?El@ba3>Klc67>dqQr-mk1gtlsGBGIp+yq~6Xj_Jej)37r{U&p8j}g&QxM)Y+ zIwRb&5-D)_s=Z#`D}+xeLFeG`RbQP3yhiwQ%yFp%EZQ2-#oJko5|=quNk~9E)m)EO zXSvKoRVVsU3Ko7`SG}~)in-Ju>Al^BPH&jK&ADEYUFP3P zsw^!#8IDq(i{K6iDqD@H?d8lctJANPqzbZLq%xTuqawJ_L19_ZPE795A`#pdQmcxb zqTwWak`=+LeUwU-QZ$LlpJqi6&&{tcQX`;E(QHz2k`+S4yT2XWx@PU(ua4#N3c3_c zVrmYKx)83WNpvWw+Wr|>svgfeGIdj~m?SHOshsqcIlfLJ#b>=S!<*Tpe!a6MINN}9 z46KOi7F`u!nx_1!*RQFhanDQoT<*>E_Km+T)J&c0 - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_message.xml b/app/src/main/res/layout/item_message.xml index c5ef9f7..4d03811 100644 --- a/app/src/main/res/layout/item_message.xml +++ b/app/src/main/res/layout/item_message.xml @@ -7,28 +7,89 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" - android:paddingTop="12dp" + android:paddingTop="8dp" android:background="@drawable/bg_conversation" android:paddingStart="8dp" - android:paddingBottom="12dp" + android:paddingBottom="8dp" android:paddingEnd="75dp"> - + app:layout_constraintTop_toTopOf="parent" > + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_message_out.xml b/app/src/main/res/layout/item_message_out.xml index 17b9935..533533b 100644 --- a/app/src/main/res/layout/item_message_out.xml +++ b/app/src/main/res/layout/item_message_out.xml @@ -8,7 +8,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" - android:paddingTop="12dp" + android:paddingTop="8dp" android:paddingEnd="8dp" android:paddingBottom="8dp" android:background="@drawable/bg_conversation" @@ -16,35 +16,40 @@ xmlns:tools="http://schemas.android.com/tools"> - + + + - Title Describe bug here Call - View Contact Copy OTP Forward \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 95bc3cb..6116371 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,23 +19,4 @@ android.useAndroidX=true android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official -kapt.incremental.apt=true - -VERSION_NAME=5.2.6 -VERSION_CODE=76 -GROUP=com.klinkerapps - -POM_DESCRIPTION=Android Messaging library for SMS and MMS -POM_URL=https://github.com/klinker41/android-smsmms -POM_SCM_URL=https://github.com/klinker41/android-smsmms -POM_SCM_CONNECTION=scm:git@github.com:klinker41/android-smsmms.git -POM_SCM_DEV_CONNECTION=scm:git@github.com:klinker41/android-smsmms.git -POM_LICENCE_NAME=The Apache Software License, Version 2.0 -POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt -POM_LICENCE_DIST=repo -POM_DEVELOPER_ID=klinker41 -POM_DEVELOPER_NAME=Jacob Klinker - -POM_NAME=Andorid Messaging -POM_ARTIFACT_ID=android-smsmms -POM_PACKAGING=aar \ No newline at end of file +kapt.incremental.apt=true \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 573aacf..a6cebbd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,2 @@ -include ':database' -include ':android-smsmms' include ':app' rootProject.name = "SMS Organiser" \ No newline at end of file