Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

Adding text messaging to my Android app?

Hi everyone,

I'm looking to add simple text messaging to my Android application. I have added a button to the action bar which takes the user to a text message activity with a edit text field and a send button. I'm just now a little stumped as to the best way to upload the text to parse and to the recipients inbox. I understand it should be fairly simple to do however I'm fairly new Android development.

Any help you can give would be greatly appreciated!

Thank you! :)

Hey Luke,

I think I downloaded your version of Ribbit from the app store. I recognized you picture from your app. How did you get the progressbar to show up on the list view for friends and message part of the app? Also when you are sending you message to the recipients how did you have the app go back to the main activity so fast? Mine freezes for 5secs before displaying a toast.

3 Answers

Hey Luke!

It should actually be relatively simple for your to set this up.


First of all, in Parse, you need to decide how you're going to store the data. Right now, we have a column called file but, that's not going to do as, we want a String, not a file! So, we're going to create a new column called text which is a String - this is going to hold the users message.

Go in your ParseConstants file and add these lines:

public static final String KEY_TEXT = "text";

public static final String TYPE_TEXT = "text";

Next, you need to create an EditText somewhere - this will be where the user can type in the message that they want to send. There are a few ways to go about this but, a good yet easy option would be to create a new button on the Action Bar that leads to a new activity (Perhaps you could call it SendTextActivity or similar).

In this activity, you would have an EditText and a Button - clicking on the button will take the user to RecipientsActivity (But don't forget to pass the message on in an intent!).

Now, we should be ok when sending text as, it usually isn't very long but, we should also probably add a limit to the number of characters that we send across. This is completely optional but, can be checked quickly with String.length().


Now, in the createMessage() method, we're actually dealing with a file here. You'll need to rearrange things so that if we have a file, deal with it. If we don't, ignore anything relating to files and let's send some text to Parse instead (An if/else statement should be ringing in your head here but, if you need any help implementing this, let me know).

So, what if we do have a message? Well, we'll need to get our message first using something like getIntent().getStringExtra("message"); (If message was the key for your intent).

Then, we can go ahead and send this message off to Parse. First though, we need to put the values in:

mFileType = ParseConstants.TYPE_TEXT;
message.put(ParseConstants.KEY_FILE_TYPE, mFileType);
// Make sure you store the text from the intent.
message.put(ParseConstants.KEY_TEXT, intentMessage);

Then, you can return and send the message!


Finally, you will want the recipient to be able to read the message - perhaps to do this you could create a ViewTextActivity with a TextView and then inflate the TextView with the received String?

You should be able to figure this out yourself but, you're creating an Intent from the InboxFragment in the onListItemClick() method.


I believe this is the main things you have to do but, I have missed some things out here so, do try yourself to figure out the bits I haven't discussed (e.g: Images for the action bar/list items in the inbox). If you do have any problems with anything though, please keep me updated on this forum post and I'd be happy to help out. Best of luck :)

Wow thank you Harry for your answer! Appreciate the time you took to layout what needed to be done!

I've now managed to get it working! :)

One issue though - I'd really like to make it so when the user begins to type in the Edit Text on my text message activity, a button taking them to the recipients appears in the action bar. Similar to how the current recipients page works with leading the user on to send the message.

I understand this should be pretty simple but I cannot seem to get the code right for detecting when input is made to the Edit Text and then showing the action bar button.

Again, I really appreciate any advice you can give!

Sure thing! That's a great alternative to a button and is definitely possible! Using a TextWatcher hasn't been taught in the Android courses here but, I'd be happy to guide you through it.

I'm going to use a send button on the EditTextActivity however, you can always swap this out to whatever you want.


First of all, we have two options.

  • Use send button
  • Don't use send button

If you are using the send button, we're in luck because we already have a send button in our recipients.xml file. Now, if we're using this button in both EditTextActivity and RecipientsActivity then maybe this isn't such a great name. We can perform a refactor by Right-clicking on recipients.xml and choosing Refactor >> Rename and then give it something like sendMenu.

If you're not using the send button, create a new file called editText.xml and copy the same code from recipients.xml, changing the image icon.


Next, in EditTextActivity, you want to add this method and member variable:

protected MenuItem mSendMenuItem;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.recipients, menu);
        mSendMenuItem = menu.getItem(0);
        return true;
    }

This will inflate our objects onto the menu (Only the send button which we won't see as we set it to be hidden), set mSendMenuItem to the item at index 0 (Again, the send button) and then return true to say that this has completed.


This is where the magic happens! We're now going to create a TextWatcher to detect if the text has changed and, if it has, show our icon! Let's update our onCreate() method in EditTextActivity to do that:

    // Add this member variable:
    protected EditText mEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // misc code - setContentView() and super methods.

        // Copy from here \/

        mEditText = (EditText) findViewById(R.id.editText);

        mEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // Intentionally blank
            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // Intentionally blank
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (s.length() > 0) {
                    mSendMenuItem.setVisible(true);
                }
                else {
                    mSendMenuItem.setVisible(false);
                }
            }
        });

    // To here /\

    }

Note: Replace the inner of the onCreate() method. Don't just replace your whole onCreate() method with this as, it doesn't include the misc code. I've provided comments of what bit should be copied.

Here, what we're doing is we're defining and initializing our EditText and then creating a TextWatcher listener that detects when our text has changed and whether its total length is greater than 0 (We have text).

This is foolproof and means a user can also backspace their text, causing the icon to then disappear again.


Now, in my previous post, I also talked about how you could limit the size of the message, just so that people aren't stupid and send a really long spammy message.

We could do this here with:

if (s.length > 0 && s.length < 20000) {

which would mean that the send icon only appears if the length is greater than 0 yet less than 20000. This works and, there is also another option (That's the beauty of programming - there's more than one way to do things).

We could also check once the button was pressed - so, in onOptionsItemSelected(), we could make it so that the user would only be brought to RecipientsActivity if the length is less than 20000 (Or any value you choose). This would mean that the user would be shown the button but, we should then prompt them that their message was too long and couldn't be sent. If we didn't show them a prompt, they could think that our app was broken!

I would usually recommend a better option here but, there isn't really one. I mean, we are checking if the length is less than 20000 every time a new character is entered but, even if we got rid of that, we're still checking if the length is greater than 0 every time. Therefore, there would probably be no noticeable performance difference between either option but, in the future, you should take these things into account and only run code where necessary, especially as we're developing for mobile devices with batteries.


Hopefully this should explain everything for you but, as always if there's anything else, give me a shout :)

Hello Harry James

can you please upload the code for send text feature in order to use it in ribbit app ?

regards