0

I am a newbie on android development and I'm trying to create an sms Reciever app but it is not working. I want the broadcast receiver to capture incoming messages and pass them to the Recycler view so that they can be displayed. At the moment nothing is being displayed.

here is my code (Manifest File)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.test1">

    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Test1">
        <receiver
            android:name=".SmsReceiver"
            android:enabled="true"
            android:exported="true"></receiver>

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>  

here is the MainActivity file

 package com.example.test1;
    
    import android.content.ContentResolver;
    import android.content.pm.PackageManager;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.app.ActivityCompat;
    import androidx.core.content.ContextCompat;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
        //recycler view
        private RecyclerView recyclerView;
         private ArrayList<SmsModel>smsModel=new ArrayList<>();
        private static MainActivity inst;
        public static MainActivity instance() {
            return inst;
        }
    @Override
    public void onStart() {
        super.onStart();
        inst = this;
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView=findViewById(R.id.smsRecycler);
        ArrayAdapter adapter= new ArrayAdapter();
        adapter.setSmsModel(smsModel);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        if(ContextCompat.checkSelfPermission(getBaseContext(), "android.permission.READ_SMS") == PackageManager.PERMISSION_GRANTED) {
            refreshSmsInbox();
        }else {
            // Todo : Then Set Permission
            final int REQUEST_CODE_ASK_PERMISSIONS = 123;
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{"android.permission.READ_SMS"}, REQUEST_CODE_ASK_PERMISSIONS);
        }

        }
    public void refreshSmsInbox() {
        ContentResolver contentResolver = getContentResolver();
        Cursor smsInboxCursor = contentResolver.query(Uri.parse("content://sms/inbox"), null, null, null, null);
        int indexBody = smsInboxCursor.getColumnIndex("body");
        int indexAddress = smsInboxCursor.getColumnIndex("address");
        if (indexBody < 0 || !smsInboxCursor.moveToFirst()) return;
        smsModel.clear();
        do {
            String str = "SMS From: " + smsInboxCursor.getString(indexAddress) +
                    "\n" + smsInboxCursor.getString(indexBody) + "\n";
            smsModel.add((SmsModel) smsInboxCursor);
        } while (smsInboxCursor.moveToNext());
    }

    public void updateList(final String smsMessage) {
       


    }


}

Here is my Recyclerview Adapter class

 package com.example.test1;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ArrayAdapter extends RecyclerView.Adapter<ArrayAdapter.viewHolder> {
    
    
        private ArrayList<SmsModel>smsModel=new ArrayList<>();
    
        public ArrayAdapter() {
    
        }
    
        @NonNull
        @Override
        public viewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.smsview,parent,false);
            viewHolder viewHolder=new viewHolder(view);
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(@NonNull viewHolder holder, int position) {
            holder.ContactsNO.setText(smsModel.get(position).getContactNumber());
            holder.SmsText.setText(smsModel.get(position).getContactSms());
            holder.Time.setText(smsModel.get(position).getTime());
            holder.Number.setText(smsModel.get(position).getNumber());
    
    
        }
    
        @Override
        public int getItemCount() {
            return smsModel.size();
        }
    
        public void setSmsModel(ArrayList<SmsModel> smsModel) {
            this.smsModel = smsModel;
            notifyDataSetChanged();
        }
    
        public class viewHolder extends RecyclerView.ViewHolder {
            private TextView ContactsNO;
            private TextView SmsText;
            private TextView Time;
            private TextView Number;
            public viewHolder(@NonNull View itemView) {
                super(itemView);
                ContactsNO=itemView.findViewById(R.id.contactsNo);
                SmsText=itemView.findViewById(R.id.smsText);
                Time=itemView.findViewById(R.id.time);
                Number=itemView.findViewById(R.id.Number);
            }
        }
    }

And here is my Sms Receiver Class

package com.example.test1;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;

import androidx.annotation.RequiresApi;

public class SmsReceiver extends BroadcastReceiver {
    public static final String SMS_BUNDLE = "pdus";
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle intentExtras = intent.getExtras();
        if (intentExtras != null) {
            Object[] sms = (Object[]) intentExtras.get(SMS_BUNDLE);
            String smsMessageStr = "";
            for (int i = 0; i < sms.length; ++i) {
                SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]);

                String smsBody = smsMessage.getMessageBody().toString();
                String address = smsMessage.getOriginatingAddress();

                smsMessageStr += "SMS From: " + address + "\n";
                smsMessageStr += smsBody + "\n";
            }
            Toast.makeText(context, smsMessageStr, Toast.LENGTH_SHORT).show();

            //this will update the UI with message
            MainActivity inst = MainActivity.instance();
            inst.updateList(smsMessageStr);
            }
        }


    }

here is my sms model class

package com.example.test1;

public class SmsModel {
    private  String Id;
    private String ContactNumber;
    private String ContactSms;
    private String Time;
    private String Number;

    public SmsModel(String id, String contactNumber, String contactSms, String time, String number) {
        Id = id;
        ContactNumber = contactNumber;
        ContactSms = contactSms;
        Time = time;
        Number = "Number";
    }

    public String getId() {
        return Id;
    }

    public void setId(String id) {
        Id = id;
    }

    public String getContactNumber() {
        return ContactNumber;
    }

    public void setContactNumber(String contactNumber) {
        ContactNumber = contactNumber;
    }

    public String getContactSms() {
        return ContactSms;
    }

    public void setContactSms(String contactSms) {
        ContactSms = contactSms;
    }

    public String getTime() {
        return Time;
    }

    public void setTime(String time) {
        Time = time;
    }

    public void setNumber(String number) {
        Number = number;
    }

    public String getNumber() {
        return Number;
    }

    @Override
    public String toString() {
        return "SmsModel{" +
                "Id='" + Id + '\'' +
                ", ContactNumber='" + ContactNumber + '\'' +
                ", ContactSms='" + ContactSms + '\'' +
                ", Time='" + Time + '\'' +
                ", Number='" + Number + '\'' +
                '}';
    }
}

here is my main Activity code

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">


<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/sms"
    android:text="SMS APP"
    android:layout_centerHorizontal="true"
    android:textFontWeight="600"
    android:textStyle="bold"/>

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/sms"
        android:id="@+id/smsRecycler"
/>

</RelativeLayout>

and my layout resource file(smsview.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">

    <TextView
        android:id="@+id/Number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Number:" />

    <TextView
        android:id="@+id/contactsNo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@+id/Number"
        android:text="0700000000" />

    <TextView
        android:id="@+id/smsText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/Number"
        android:layout_marginTop="10dp"
        android:hint="sms text will apear here" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="200dp"
        android:layout_toRightOf="@+id/contactsNo"
        android:text="21:59"
        android:id="@+id/time"
        />

</RelativeLayout>

i have tried anything i can but am not able to make it work.

  • Receiving messages as they arrive, and reading them after that are two different things. You'll need to focus on one at a time for quesions here. In the way of general advice, each individual SMS permission used must be requested at runtime; currently, you're requesting only `READ_SMS`. Also, if your app is crashing, as you mention below, that needs to be stated in the question, along with a description of when and how it happens, and [the complete stack trace from the crash](https://stackoverflow.com/a/23353174). – Mike M. Dec 02 '21 at 17:40

1 Answers1

0

You should declare the BroadcastReceiver in AndroidManifest.xml.

<receiver
  android:name="com.example.test1.SmsReceiver"
  android:priority="1000"
  android:permission="android.permission.BROADCAST_SMS">
  <intent-filter android:priority="1000">
    <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
  </intent-filter>
</receiver>
anemomylos
  • 546
  • 1
  • 6
  • 14
  • i have declared that and the application still isn't working...Again the application launches perfectly on the first click and crashes when i try to launch it again...i have to clear data for it to work...Might you have an idea? –  Dec 02 '21 at 09:57
  • The fact that the app crashes could be a consequence of how you're making the Service communicate with the Activity. Using a static variable like `private static MainActivity inst` is not recommended. Start reading the following thread to understand more: https://stackoverflow.com/questions/2463175/how-to-have-android-service-communicate-with-activity – anemomylos Dec 03 '21 at 08:14