2

I am creating an app on android that needs to be able to allow android devices to send SMS data back and forth with SmsManager.sendDataMessage(). For some reason when I try to send data this way my sms receiver doesn't ever get anything. What am I missing?

Here is the code to send the data:

SmsManager sm = SmsManager.getDefault();
sm.sendDataMessage(toPhone, null, (short)8901, message.getBytes(), null, null);

Here is the code to my sms receiver:

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

public class DataReceiver extends BroadcastReceiver
{
    private String myMessage;

    @Override
    public void onReceive(Context context, Intent intent)
    {
        Bundle bundle = intent.getExtras();
        if (bundle == null) return;

        Object[] objs = (Object[]) bundle.get("pdus");
        SmsMessage[] messages = new SmsMessage[objs.length];

        for (int i = 0; i < objs.length; i++)
        {
            messages[i] = SmsMessage.createFromPdu((byte[]) objs[i]);
        }

        for (SmsMessage currMessage : messages)
        {
            if (!currMessage.isStatusReportMessage())
            {
                String messageBody = currMessage.getDisplayMessageBody();
                byte[] messageBytes = currMessage.getPdu();
                int x = 1 + messageBytes[0] + 19 + 7;
                myMessage = new String(messageBytes, x, messageBytes.length - x);
                System.out.printf(myMessage);
            }
        }
    }
}

Here is what I have in my manifest for the receiver:

<receiver android:name=".DataReceiver">
    <intent-filter>
        <action android:name="android.intent.action.DATA_SMS_RECEIVED" />
        <data android:scheme="sms" />
        <data android:host="localhost" />
        <data android:port="8901" />
    </intent-filter>
</receiver>

And here are the permissions I am using:

<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
sabo
  • 911
  • 13
  • 37
  • You need the `RECEIVE_SMS` permission. And, if you're running under Marshmallow or above, with a `targetSdkVersion` >=23, you need to request the permissions at runtime. – Mike M. Jul 05 '16 at 21:40
  • @MikeM. I went ahead and added that permission. I am already requesting permission at runtime as well. I am debugging the app and it just never makes it into the onReceive() function still for some reason. – sabo Jul 05 '16 at 23:03
  • Well, without that permission, it definitely never would've. Have you launched an `Activity` in your app at least once after installation to bring it out of the _stopped_ state? Your Receiver won't be delivered the broadcast until then. Are you sure you're on the right port? You can use `"*"` to listen on all ports. You sure the ``'s in the right place in the manifest, and that its `name` points to the right class file? I would also suggest using log prints to check if it enters `onReceive()`, if you're not. Debuggers can be unreliable for things like this. – Mike M. Jul 05 '16 at 23:16
  • You might also check the number and message right before you send. If you've double-checked everything and it's good, you might create a `PendingIntent` to pass as the fifth argument in `sendDataMessage()`, and check the results to make sure it's actually getting sent. Also, test to see if you can receive a regular text message, as well. – Mike M. Jul 05 '16 at 23:26
  • @MikeM. I have launched an activity to bring it out of the stopped state. I thought I was just supposed to pick a random port number. I have 8901 that is set in the manifest and the receiver. The is in the tag in the manifest. The name points to the correct file. I also put a print statement in the onReceive() function and it never pops up in the logcat. – sabo Jul 05 '16 at 23:57
  • @MikeM. Regular texts go through fine and the number and message seem fine right before sending. I will try a PendingIntent. – sabo Jul 05 '16 at 23:59
  • Yeah, 8901 is fine. Some carriers use it for voice mail data updates, so you might eventually want to change to something else, but it shouldn't be causing a problem now. Everything else sounds good. I should mention that I've heard some users having problems with specifically data SMS, depending on their carriers, especially if the sending and receiving devices are on different ones. – Mike M. Jul 06 '16 at 00:03
  • @MikeM. I'm trying to send and receive on the same device. I mean I am sending the data and it is sending to my own number so I can test it that way. That wouldn't cause any issues would it? – sabo Jul 06 '16 at 00:06
  • Shouldn't. That's my first test for all SMS stuff, sending to my own device. – Mike M. Jul 06 '16 at 00:07
  • @MikeM. Yeah I really have no idea why this isn't working. lol – sabo Jul 06 '16 at 00:15
  • Yeah, dunno. You did specifically include the `RECEIVE_SMS` permission in the runtime request, yeah? Did the `PendingIntent` result tell you anything? You aren't on Verizon, by chance, are you? – Mike M. Jul 06 '16 at 00:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/116525/discussion-between-saboehnke-and-mike-m). – sabo Jul 06 '16 at 00:27

1 Answers1

3

The RECEIVE_SMS permission is required to receive data SMS, too. If your app is running under Marshmallow or above, and the targetSdkVersion is 23 or greater, you'll need to request this permission at runtime, as well.

Even if you're already requesting other SMS permissions, you still need to specifically request RECEIVED_SMS. Your app is granted only those permissions it requests, and though the SMS group is presented when asking for READ_SMS or SEND_SMS, the RECEIVED_SMS will not be granted unless it's included in the request.

It should also be noted that this permission must be in place before the app is to receive data messages. You cannot request permissions from a Receiver, and, by that time, it will have been far too late anyway. Your Receiver would never even know there was a message. Simply add that permission to the request for the rest of the SMS permissions.

Mike M.
  • 38,532
  • 8
  • 99
  • 95