Need help in android. Voice and gesture based Messaging app for visually impaired people

Hi. I’m a beginner in android development. I want to create a voice and gesture based messaging app. Now, I’ve created an app which is able to receive and send messages. But i want my app to read incoming messages aloud. Any help in this matter would be appreciated. !.. if you want i can send the whole program to you via email or any other source. Any suggestions to change the ugly layout are also welcome.

Screenshot_20200213-121227|281x500

Below is the whole code.

//Broadcast receiver
package com.example.myapplication;

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 SmsBroadcastReceiver extends BroadcastReceiver {


    public static final String SMS_BUNDLE = "pdus";

    @RequiresApi(api = Build.VERSION_CODES.M)
    public void onReceive(Context context, Intent intent) {
        Bundle intentExtras = intent.getExtras();


        Toast.makeText(context, "Message Received!", Toast.LENGTH_SHORT).show();


        if (intentExtras != null) {
            Object[] sms = (Object[]) intentExtras.get(SMS_BUNDLE);
            String smsMessageStr = "";
            for (int i = 0; i < sms.length; ++i) {
                String format = intentExtras.getString("format");
                SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms[i], format);

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

                smsMessageStr += "SMS From: " + address + "\n";
                smsMessageStr += smsBody + "\n";
            }

            if (MainActivity.active) {
                MainActivity inst = MainActivity.instance();
                inst.updateInbox(smsMessageStr);
            } else {
                Intent i = new Intent(context, MainActivity.class);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(i);
            }
        }
    }
}
//Main Activity

package com.example.myapplication;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    FloatingActionButton fabNewMsg;
    ImageButton newmessage;

    public static MainActivity instance() {
        return instance();
    }

    static boolean active = false;
    @Override
    public void onStart() {
        super.onStart();
       MainActivity instance = this;
    }
    @Override
    public void onStop() {
        super.onStop();
        active = false;
    }


    ArrayList<String> smsMessagesList = new ArrayList<>();
    ListView messages;
    ArrayAdapter arrayAdapter;



    private static final int READ_SMS_PERMISSIONS_REQUEST = 1;

    @RequiresApi(api = Build.VERSION_CODES.M)
    public void getPermissionToReadSMS() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS)
                != PackageManager.PERMISSION_GRANTED) {
            if (shouldShowRequestPermissionRationale(
                    Manifest.permission.READ_SMS)) {
                Toast.makeText(this, "Please allow permission!", Toast.LENGTH_SHORT).show();
            }
            requestPermissions(new String[]{Manifest.permission.READ_SMS},
                    READ_SMS_PERMISSIONS_REQUEST);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String permissions[],
                                           @NonNull int[] grantResults) {
        // Make sure it's our original READ_CONTACTS request
        if (requestCode == READ_SMS_PERMISSIONS_REQUEST) {
            if (grantResults.length == 1 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "Read SMS permission granted", Toast.LENGTH_SHORT).show();
                refreshSmsInbox();
            } else {
                Toast.makeText(this, "Read SMS permission denied", Toast.LENGTH_SHORT).show();
            }

        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    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;
        arrayAdapter.clear();
        do {
            String str = "SMS From: " + smsInboxCursor.getString(indexAddress) +
                    "\n" + smsInboxCursor.getString(indexBody) + "\n";
            arrayAdapter.add(str);
        } while (smsInboxCursor.moveToNext());
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        messages = (ListView) findViewById(R.id.messages);
//        EditText input = (EditText) findViewById(R.id.input);
        arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, smsMessagesList);
        messages.setAdapter(arrayAdapter);
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS)
                != PackageManager.PERMISSION_GRANTED) {
            getPermissionToReadSMS();
        } else {
            refreshSmsInbox();
        }

        fabNewMsg = findViewById(R.id.fab_new);
        fabNewMsg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Intent code for open new activity through intent.
                Intent intent = new Intent(MainActivity.this, SmsSend.class);
                startActivity(intent);
            }
        });

        newmessage = (ImageButton)findViewById(R.id.sttact);
        newmessage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Intent code for open new activity through intent.
                Intent intent = new Intent(MainActivity.this, Speechtotext.class);
                startActivity(intent);
            }
        });

        messages.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

                smsMessagesList.remove(position);
                arrayAdapter.notifyDataSetChanged();
                Toast.makeText(MainActivity.this, "Item Deleted", Toast.LENGTH_LONG).show();
                return true;
            }
        });



    }

    //sending sms
    EditText input;
    SmsManager smsManager = SmsManager.getDefault();

    @RequiresApi(api = Build.VERSION_CODES.M)
    public void onSendClick(View view) {

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS)
                != PackageManager.PERMISSION_GRANTED) {
            getPermissionToReadSMS();
        } else {
            smsManager.sendTextMessage("+923322977643c", null, input.getText().toString(), null, null);
            Toast.makeText(this, "Message sent!", Toast.LENGTH_SHORT).show();
        }
    }

    public void updateInbox(String smsMessageStr) {
    }
}
// Sms send speech to text implemented. 
package com.example.myapplication;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.speech.RecognizerIntent;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.telephony.SmsManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;


import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.google.android.material.textfield.TextInputEditText;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;

public class Speechtotext extends AppCompatActivity {

    int Ask_Contact = 11;
    int Ask_MESSAGE = 12;
    int Send_OR_CANCEL = 13;
    int SEND_MSG_OR_CANCEL_MSG;
    int CANCEL_MESSAGE = 14;
    Context context;


    TextToSpeech tts;

    public String FULL_MESSAGE, CONTACT_NUMBER = null;
    private String number = null;
    private String ret = null;
    private String username = null;
    private String No = null;

    private String body = null;

    private ListView contactsList;
    TextView phone_number;




    Button sendBtn;
    Button mcancel;
    ImageView micBtn;

    TextInputEditText mMessage;

    Spinner  mContact;

    HashMap<String,String> map;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_speechtotext);


        context=getApplicationContext();
        contactsList = findViewById(R.id.contact_list);

        sendBtn = (Button) findViewById(R.id.btnsend);
        mcancel = (Button) findViewById(R.id.btncancel);
        micBtn=(ImageView)findViewById(R.id.mic_btn);

        mContact = (Spinner) findViewById(R.id.textInputEditText);
        mMessage =  (TextInputEditText) findViewById(R.id.textInputEditText2);
        phone_number=(TextView)findViewById(R.id.tv_phone);

        map = new HashMap<String, String>();


        tts = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {

            @Override
            public void onInit(int status) {
                map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"UniqueID");

                if (status != TextToSpeech.ERROR) {
                    tts.setLanguage(new Locale("ur"));

                    tts.speak("Who do you want to send the message", TextToSpeech.QUEUE_FLUSH, map);
                    tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                        @Override
                        public void onStart(String utteranceId) {

                        }

                        @Override
                        public void onDone(String utteranceId) {
                            startVoiceRecognization(Ask_Contact);

                        }

                        @Override
                        public void onError(String utteranceId) {

                        }
                    });



                } }});





        micBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                resetActivity();
            }
        });


        mcancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                resetActivity();
            }
        });

        sendBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (CONTACT_NUMBER != null && FULL_MESSAGE != null) {
                    sendSms(CONTACT_NUMBER, FULL_MESSAGE);
                }
            }
        });



    }



    public void resetActivity()
    {
        Intent intent = getIntent();
        overridePendingTransition(0, 0);
        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        finish();
        overridePendingTransition(0, 0);
        startActivity(intent);
    }

    //to speak or system response

    public void speakAndStartListening(final String text, final int RequestCode)
    {
        tts.speak(text, TextToSpeech.QUEUE_FLUSH, map);
        tts.setOnUtteranceProgressListener(new UtteranceProgressListener()
        {
            @Override
            public void onStart(String s)
            { }


            @Override
            public void onDone(String s)
            {
                startVoiceRecognization(RequestCode);
            }

            @Override
            public void onError(String s)
            { }
        });
    }



    public void speakOnly(final String text)
    {
        tts.speak(text, TextToSpeech.QUEUE_FLUSH, map);
    }


    //tostart listeining
    public void startVoiceRecognization(int CODE)
    {

        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        startActivityForResult(intent, CODE);
    }


    //results of voice recognization
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);

        //result of contact
        if (requestCode == Ask_Contact && resultCode == RESULT_OK)
        {

            ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            number = matches.get(0).toString();
            Cursor contacts = getListOfContactNames(number);

            String from[]={ContactsContract.Contacts.DISPLAY_NAME,
                    ContactsContract.CommonDataKinds.Phone.NUMBER};
            int ids[]={R.id.tv_name,R.id.tv_phone};
            SimpleCursorAdapter simpleCursorAdapter=new SimpleCursorAdapter(getApplicationContext(),
                    R.layout.contact_list_view_item,contacts,from,ids,0);
            mContact.setAdapter(simpleCursorAdapter);


            //OR USING CUSTOMADAPTER

            //ContactAdapter contactAdapter=new ContactAdapter(getApplicationContext(),contacts);
            // mContact.setAdapter(contactAdapter);


            if (mContact.getCount()==0)
            {
                speakAndStartListening("Sorry! say the name again",Ask_Contact);
            }

            else if (mContact.getCount() > 1)
            {
                mContact.performClick();

                speakOnly("which one?" + number);

                //START SOME WORK AFTER SPEECH IS ENDED
                tts.setOnUtteranceProgressListener(new UtteranceProgressListener()
                {
                    @Override
                    public void onStart(String s) { }

                    @Override
                    public void onDone(String s)
                    {

                        mContact.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
                        {@Override

                        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l)
                        {
                            Cursor cursor=(Cursor)adapterView.getItemAtPosition(i);
                            CONTACT_NUMBER= cursor.getString(2);
                            speakAndStartListening("Please speak your message.",Ask_MESSAGE);
                        }

                            @Override
                            public void onNothingSelected(AdapterView<?> adapterView)
                            { }
                        });
                        return;
                    }

                    @Override
                    public void onError(String s)
                    {
                        speakOnly(s);
                        startVoiceRecognization(Ask_Contact);
                    }
                });
            }
            else
            {
                speakAndStartListening("Please speak your message",Ask_MESSAGE);
            }
        }


        //result of change contact or send
        if (requestCode == Send_OR_CANCEL && resultCode == RESULT_OK)
        {

            ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            if (matches.get(0).equals("change")||matches.get(0).equals("change it"))
            {
                startVoiceRecognization(Ask_Contact);
            }

            else if (matches.get(0).equals("send")||matches.get(0).equals("send it"))
            {
                speakAndStartListening("What is your message",Ask_MESSAGE);
            }
        }
        //result of user message
        if (requestCode == Ask_MESSAGE && resultCode == RESULT_OK)
        {
            ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            FULL_MESSAGE = matches.get(0).toString();
            mMessage.setText(FULL_MESSAGE);
            speakAndStartListening("send message or change it",SEND_MSG_OR_CANCEL_MSG);

        }



        //result of change message or send
        if (requestCode == SEND_MSG_OR_CANCEL_MSG && resultCode == RESULT_OK)
        {

            ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            if (matches.get(0).equals("change")||matches.get(0).equals("change it")||
                    matches.get(0).equals("change kar do")||matches.get(0).equals("Badal do")
                    ||matches.get(0).equals("Badal"))
            {
                speakAndStartListening("speak your message",Ask_MESSAGE);
            }


            else if (matches.get(0).equals("send")||matches.get(0).equals("send it")
                    ||matches.get(0).equals("send kar do"))
            {
                sendSms(CONTACT_NUMBER, FULL_MESSAGE);
                //   speakOnly(".");
            }

            else
            {
                speakAndStartListening("please speak again" +
                        "",SEND_MSG_OR_CANCEL_MSG);
            }
        }
    }


    public void sendSms(String no, String body)
    {

        SmsManager smgr = SmsManager.getDefault();
        smgr.sendTextMessage(no, null, body, null, null);
        toast("SMS Sent Successfully");

    }

    public Cursor getListOfContactNames(String searchText)
    {

        Cursor cur = null;
        ContentResolver cr = getContentResolver();

        String[] mProjection = new String[]{ContactsContract.CommonDataKinds.Phone._ID,
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER,
                ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER};

        Uri uri = ContactsContract.Contacts.CONTENT_URI;

        String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME   + " like'%" + searchText + "%'";
        cur  = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                mProjection, selection, null, null);

        return cur;
    }


    public void toast(String text)
    {
        Toast.makeText(getApplicationContext(),text,Toast.LENGTH_SHORT).show();
    }
}
// Android manifest file.

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

    <uses-permission android:name="android.permission.WRITE_SMS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/mic"
        android:label="@string/app_name"
        android:roundIcon="@drawable/mic"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />

            <action android:name="android.intent.action.SEND" />
            <action android:name="android.intent.action.SENDTO" />
        </intent-filter>
        </activity>

        <activity android:name=".Speechtotext" />
        <activity android:name=".SmsSend"/>

        <receiver
            android:name=".SmsBroadcastReceiver"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS">
            <intent-filter android:priority="999">
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
                <action android:name="android.provider.Telephony.SMS_DELIVER" />
                <action android:name="android.provider.Telephony.SMS_DELIVER_ACTION" />
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>



    </application>

</manifest>

Hey. Im glad you replied. I have posted the code and a picture with a brief description of what help I’m asking for. Can you please look into it?. It would really be helpful. Thanks.
Here is the link.
http://forum.freecodecamp.org/t/need-help-in-android-voice-and-gesture-based-messaging-app-for-visually-impaired-people/349849

Hi,

I would like to understand whether you are developing this app for purely learning purposes or you would like to publish this? If the latter, I would advise that you take a look at Talkback, which is a built-in screen reader in the Android operating system. It allows accessing of apps and OS functionality through text-to-speech. I am blind myself, however I use ios ut essentially its doing a similar thing.

I hope this helps you.