Best App to Download Sms Log on Android

Despite the popularity of social media networks and messengers, texting is all the same the most mutual way to communicate via smartphones. According to the 2020 State of Texting report by Zipwhip, 77% of people use their texting app more ofttimes than other messengers.

But default SMS applications aren't always comfy for receiving SMS on Android, so users beginning looking for third-party apps. Additionally, not-messenger Android applications may still need SMS handling functionality (for example to ostend SMS authentication codes). In this article, we share our experience in developing SMS (and other service) handlers. In particular, nosotros describe how to:

  • Make your application the default SMS handler
  • Develop an Android SMS receiver
  • Encrypt and decrypt SMS messages
  • Add together texts to the SMS table in a device database

This text will be useful for developers who need to add SMS handling functionality to their app or create a new SMS messaging app.

Contents:

Making an app the default SMS handler

Developing the Android app manifest file

Editing the ViewModel

Encrypting and decrypting SMS messages

Handling received SMS messages

Reading and decrypting SMS messages

Determination

Making an app the default SMS handler

It's important to make your application the default for handling SMS messages because only such app can tape information to the SMS database. Your app should asking permission to go the default SMS app before requesting any other permissions. This is besides a requirement of the Google Play Store: if an app requests SMS, MMS, or Telephone call LOG permissions and isn't a default SMS or Contact app, it volition be rejected past Google.

In order to become the default messaging app, your app needs to:

  • Register a receiver to handle incoming SMS messages
  • Annals a receiver to handle incoming MMS messages
  • Create an activity that allows users to send new SMS or MMS messages in the Android application
  • Create a service that sends out quick response messages

In our example, we'll focus on how to receive SMS and ship new SMS and MMS letters on Android. All of this functionality must exist implemented in order to make our app the default handler.

Nosotros tin can use this code to ask a user to make our app the default for receiving SMS letters on Android:

          
val setSmsAppIntent = Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT) setSmsAppIntent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, packageName) startActivityForResult(setSmsAppIntent, REQUEST_DEFAULT_APP)            

In the code higher up, REQUEST_DEFAULT_APP is the request code to store the user'southward choice. If the user allows the app to be the default, implementing this choice looks equally follows:

          
override fun onActivityResult(requestCode: Int, resultCode: Int, information: Intent?) {     super.onActivityResult(requestCode, resultCode, information)     if (requestCode != Activity.RESULT_OK){         return     }     when(resultCode){         REQUEST_DEFAULT_APP -> //user immune the app to become default     } }            

Now nosotros can proceed to the app manifest file and app permissions.

Developing the Android app manifest file

The app manifest file is a very important part of an Android application. Information technology contains information on the app's:

  • Package name
  • Components (activities, content providers, services, circulate receivers)
  • Required permissions
  • Required software and hardware features

Allow'southward focus on the permissions for our application.

In Android 6, Google introduced runtime permissions. They protect the privacy of user data, tell users what information will be used by the app, and make sure users understand what an app can exercise with their data.

The runtime permissions system defines two permission levels:

  • Normal — Permissions to admission data or resources that pose little to no chance to the user's personal information (due east.chiliad. device time zone). These permissions don't require the user's approval.

Dangerous — Permissions to handle a user's sensitive information (e.grand. texts, messages, photos, notes, etc.). These crave the user's approval.

Types of Android permissions

When an application requests permission, a system dialog appears. It contains a list of the permissions the app requires and Allow and Deny buttons.

If the user denies a permission, when the app requests information technology the next time, the dialog box volition comprise a Do non ask me again checkbox.

When developing an app, you should take into account the scenario when a user denies permissions. All logic that relies on the denied permissions should not cause the app to fail.

In our example, the app's manifest file declares permissions to read, send, and get all SMS in Android programmatically, as well as receive MMS messages, and receive push notifications:

          
<uses-permission android:proper noun="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:proper noun="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.RECEIVE_MMS" /> <uses-permission android:proper noun="android.permission.RECEIVE_WAP_PUSH" />            

After the proclamation, the app should get the following permissions:

          
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED ||     ContextCompat.checkSelfPermission(context, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED ||     ContextCompat.checkSelfPermission(context, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED ||     ContextCompat.checkSelfPermission(context, Manifest.permission.RECEIVE_MMS) != PackageManager.PERMISSION_GRANTED ||     ContextCompat.checkSelfPermission(context, Manifest.permission.RECEIVE_WAP_PUSH) != PackageManager.PERMISSION_GRANTED  ) {     ActivityCompat.requestPermissions(activity,         arrayOf(Manifest.permission.READ_SMS,             Manifest.permission.RECEIVE_SMS,             Manifest.permission.SEND_SMS,             Manifest.permission.RECEIVE_MMS,             Manifest.permission.RECEIVE_WAP_PUSH),         MY_PERMISSIONS_REQUEST_SMS) }            

And handle the result of its requests in this way:

          
override fun onRequestPermissionsResult(requestCode: Int,                                         permissions: Array<String>, grantResults: IntArray) {     val granted = if(permission.checkPermissionGranted(requestCode, permissions, grantResults)) "permission granted" else "permission non granted"     Toast.makeText(this,granted, Toast.LENGTH_SHORT).show() }   fun checkPermissionGranted(requestCode: Int,                                permissions: Array<Cord>, grantResults: IntArray): Boolean{         when (requestCode) {             MY_PERMISSIONS_REQUEST_SMS -> {                 // If request is cancelled, the result arrays are empty.                 return (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)             }         }         return false     } }            

All of these permissions are in the aforementioned group, then they're granted all together. If you request permissions from different permission groups, you'll need to check the grantedResults array and so you don't miss any denied permissions.

To simplify the process of acquiring permissions, you can use a library like Quick Permissions.

Now it's time to start a standard activity. In our example, this is part of an awarding that decrypts an SMS and shows information technology to the user. But in a existent messaging app, there should also be an activity that provides functionality to create and send new SMS and MMS messages.

The part of our Manifest.xml file that describes our main activeness looks like this:

          
<activity android:name=".MainActivity">     <intent-filter>         <action android:proper noun="android.intent.action.Master" />         <category android:proper noun="android.intent.category.LAUNCHER" />         <action android:proper name="android.intent.action.SEND" />         <activeness android:name="android.intent.activeness.SENDTO" />         <category android:name="android.intent.category.DEFAULT" />         <category android:name="android.intent.category.BROWSABLE" />         <data android:scheme="sms" />         <data android:scheme="smsto" />         <information android:scheme="mms" />         <data android:scheme="mmsto" />     </intent-filter> </activity>            

Now we need to create an SMS receiver:

          
<receiver android:name=".SmsReceiver"     android:permission="android.permission.BROADCAST_SMS">     <intent-filter>     <action android:name="android.provider.Telephony.SMS_RECEIVED" />         <action android:name="android.provider.Telephony.SMS_DELIVER" />     </intent-filter> </receiver>            

We also need to create an MMS receiver:

          
<receiver android:name=".MmsReceiver"     android:permission="android.permission.BROADCAST_WAP_PUSH">         <intent-filter>             <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />             <data android:mimeType="application/vnd.wap.mms-message" />         </intent-filter> </receiver>            

Finally, we should add a service that allows the user to respond to texts:

          
<service android:name=".HeadlessSmsSendService"     android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"     android:exported="true" >     <intent-filter>         <activeness android:proper name="android.intent.action.RESPOND_VIA_MESSAGE" />         <category android:name="android.intent.category.DEFAULT" />         <data android:scheme="sms" />         <data android:scheme="smsto" />         <data android:scheme="mms" />         <data android:scheme="mmsto" />     </intent-filter> </service>            

By this stage, our app tin can receive, display, and respond to texts. Let's have a expect at its ViewModel file.

Editing the ViewModel

At this phase, our project contains merely 1 Extensible Markup Language (XML) layout. There's 1 button and one list. The push is used for getting SMS messages from the organization inbox; the list is used for showing messages.

Here's the XML layout code:

          
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context=".MainActivity">     <Button         android:id="@+id/UpdateList"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_margin="2dip"         android:text="Update SMS listing"         app:layout_constraintBottom_toBottomOf="parent"         tools:layout_editor_absoluteX="2dp" />     <ListView         android:id="@+id/SMSList"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_margin="2dip"         app:layout_constraintStart_toStartOf="parent"         app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>            

And hither's a screenshot of our elementary user interface:

Our UI

As you tin can meet, this XML doesn't contain any listeners. We'll add them later. Next, we need to introduce encryption and decryption algorithms.

Encrypting and decrypting SMS messages

All texts that our app receives will be encrypted. To handle them, we demand to add a course that provides encryption and decryption.

In our application, encryption is done by executing the fun encrypt(data: String): String office. Information technology encrypts a string with a key generated using the Password-Based Cardinal Derivation Function (PBKDF2) algorithm. The returned value is an encrypted Base64 string.

Here'due south what happens when we execute this function:

          
// Encrypts cord and encode in Base64 @Throws(Exception::class) fun encrypt(data: Cord): String {     val encrypted = cryptoOperation(Nothing.ENCRYPT_MODE, data.toByteArray())     return Base64.encodeToString(encrypted, Base64.DEFAULT) }            

After that, nosotros need to decrypt the SMS. To do that, we use the fun decrypt(encryptedData: Cord): String office. It decrypts the Base64 string with a PBKDF2 algorithm.

The decryption process looks like this:

          
// Decrypts string encoded in Base64 @Throws(Exception::class) fun decrypt(encryptedData: Cord): String {     val encrypted = Base64.decode( encryptedData, Base64.DEFAULT )     val decrypted = cryptoOperation(Cipher.DECRYPT_MODE, encrypted)     render Cord(decrypted) }            

To encrypt and decrypt the given ByteArray, we can apply the fun cryptoOperation(cipherMode: Int, information: ByteArray): ByteArray function. Nosotros tin execute information technology using the following code:

          
individual fun cryptoOperation(cipherMode: Int, data: ByteArray): ByteArray{     val secretKey = generateKey()     val secretKeySpec = SecretKeySpec(secretKey, CIPHER_ALGORITHM)     val cipher = Cipher.getInstance(CIPHER_ALGORITHM)     cipher.init(cipherMode, secretKeySpec)     return  cipher.doFinal(data) }            

Encryption algorithms such equally AES, Rivest–Shamir–Adleman, MD5, etc. require a cloak-and-dagger key in the form of a ByteArray. We tin can generate a cloak-and-dagger key that uses salt with the fun generateKey(): ByteArray function. Here'south an example of how to generate a key:

          
individual fun generateKey(): ByteArray{     val factory = SecretKeyFactory.getInstance(ALGORITHM)     val ks = PBEKeySpec(Countersign.toCharArray(), SALT, 1024, RANDOM_KEY_SIZE)     val secretKey = factory.generateSecret(ks)     return secretKey.encoded }            

After executing these functions, our app can encrypt and decrypt texts. Now we tin add an SMS handler.

Treatment received SMS letters

The main course that receives SMS messages is SmsReceiver. It extends the BroadcastReceiver class. Any kid form of BroadcastReceiver must contain the onReceive method, which receives Context and Intent parameters.

The BroadcastReceiver class is well-described in the official documentation, which is why nosotros won't focus on its properties.

When we get an event upon receiving a text, we need to become to the onReceive method. Start, permit's confirm that all of the received content is valid:

          
              if(context == naught || intent == null || intent.action == nix){         return     }            

The next pace is to check that nosotros've received the SMS data past checking the activity value:

          
if (intent.action != (Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {         return     }            

Now we're ready to receive the SMS content with the val smsMessages = Telephony.Sms.Intents.getMessagesFromIntent(intent) method. It will provide us an assortment of smsMessages. Here'south an instance:

          
override fun onReceive(context: Context?, intent: Intent?) {     // Become SMS map from Intent     if(context == cypher || intent == nix || intent.action == aught){         render     }     if (intent.action != (Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {         return     }     val contentResolver = context.contentResolver     val smsMessages = Telephony.Sms.Intents.getMessagesFromIntent(intent)     for (message in smsMessages) {         Toast.makeText(context, "Message from ${message.displayOriginatingAddress} : torso ${message.messageBody}", Toast.LENGTH_SHORT)             .show()         putSmsToDatabase( contentResolver, message)     } }            

When the SMS list gets intoIntent, and then the SMS should be parsed. For this purpose, we phone call the getMessagesFromIntent method from the Telephony.Sms.Intents class.

Then SmsReceiver gets the SMS and can do anything with it. In our example, SMS messages are encrypted and recorded in the SMS tabular array of the device database. We need to practice this to allow the default Android SMS viewer to view encrypted SMS messages.

When our app receives an SMS, it'south displayed using the Toast class.

Reading and decrypting SMS messages

After we've created encryption procedures, it's time to add together functionality for reading and decrypting SMS letters. Let'southward list the click listener for the push on the main screen. All texts from the inbox are read, and and then the sender information and SMS text are put into the list using this code:

          
private fun click(){     val contentResolver = contentResolver ?: return     val cursor = contentResolver.query( Uri.parse( "content://sms/inbox" ), null, naught, nada, zero)         ?: return     val indexBody = cursor.getColumnIndex( SmsReceiver.Torso );     val indexAddr = cursor.getColumnIndex( SmsReceiver.Address );     if ( indexBody < 0 || !cursor.moveToFirst() ) return     smsList.clear()     do {         val str = "Sender: " + cursor.getString( indexAddr ) + "\northward" + cursor.getString( indexBody )         smsList.add together( str )     } while( cursor.moveToNext() )     smsListView = findViewById(R.id.SMSList)     smsListView.adapter =         ArrayAdapter<Cord>( this, android.R.layout.simple_list_item_1, smsList)     smsListView.setOnItemClickListener { parent, view, position, id ->  clickItem(position)} }            

The SMS is obtained from the list, decrypted, and then displayed to the user. The item listener list is as follows:

          
individual fun clickItem(pos: Int){     try {         val splitted = smsList.go( pos ).split("\due north")         val sender = splitted[0]         var encryptedData = ""         for(i in 1 until splitted.size){             encryptedData += splitted[i]         }         val data = sender + "\n" + StringEncryptor.decrypt(encryptedData)         Toast.makeText( this, data, Toast.LENGTH_SHORT ).testify()     }     catch (e: Exception) {         east.printStackTrace();     } }            

Later on that, our application is fix to handle SMS messages!

Decision

An awarding for treatment text messages is must on any device. Lots of users aren't satisfied with their default SMS app and are looking for a more comfortable solution. But there are several tricks to making an SMS app in Android Studio. It has to:

  • be the default application for SMS letters
  • ask for all necessary permissions (and not crash it a user denies them)
  • receive, display, and permit the user to respond to texts
  • exist secure
  • add received texts to the device'due south SMS database

In this article, nosotros've shown you how to build an Android app with this functionality. Creating such applications is merely the tip of the iceberg in terms of our experience in mobile app development. If yous have a complex Android-related projection, challenge usa with information technology!

DOWNLOAD HERE

Posted by: shiresprien1947.blogspot.com

0 Komentar

Postar um comentário




banner