Arthur
Arthur

Reputation: 789

Sending data from notification to closed activity

I've decided to make my simple receiving/sending sms app. For now almost all functionality works good except one thing - sending data from notification to closed app. For example, when user receives an sms and notification pops up, he pushes on it and Main Activity launches. In this Main Activity should be shown text from sms and sender number. But when I hit on notification Main Activity launches and shows nothing.

Main activity.java

public class MainActivity extends AppCompatActivity {
    public static final String TAG = "logs";
    Button sendSms;
    EditText address, body;
    IntentFilter intentFilter;
    TextView receivedSmsTextView;
    private BroadcastReceiver smsReceiver = new BroadcastReceiver () {
        @Override
        public void onReceive (Context context, Intent intent) {
            receivedSmsTextView = (TextView) findViewById (R.id.receivedSmsTextView);
            receivedSmsTextView.setText ("From : " + intent.getStringExtra ("address") + "\n" +
                    "Message : " + intent.getStringExtra ("body"));

        }
    };

    @Override
    protected void onResume () {
        registerReceiver (smsReceiver, intentFilter);
        super.onResume ();
    }

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.activity_main);
        sendSms = (Button) findViewById (R.id.sendButton);
        intentFilter = new IntentFilter ("SMS_RECEIVED_ACTION");
        sendSms.setOnClickListener (new View.OnClickListener () {
            @Override
            public void onClick (View v) {
                if (!address.getText ().toString ().isEmpty ()) {
                    onSendSmsButtonClick (address.getText ().toString (), body.getText ().toString ());
                    address.setText ("");
                } else {
                    Toast.makeText (MainActivity.this, "Enter number", Toast.LENGTH_SHORT).show ();
                }

            }
        });
    }

    private void onSendSmsButtonClick (String address, String body) {
        String SENT = "SMS_SENT";
        String DELIVERED = "SMS_DELIVERED";

        PendingIntent sentPendingIntent = PendingIntent.getBroadcast (this, 0, new Intent (SENT), PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent deliveredPendingIntent = PendingIntent.getBroadcast (this, 0, new Intent (DELIVERED), PendingIntent.FLAG_UPDATE_CURRENT);

        BroadcastReceiver sentReceiver = new BroadcastReceiver () {
            @Override
            public void onReceive (Context context, Intent intent) {

                switch (getResultCode ()) {
                    case RESULT_OK:
                        Toast.makeText (MainActivity.this, "Message sent", Toast.LENGTH_SHORT).show ();
                        break;
                    case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                        Toast.makeText (MainActivity.this, "Unknown error", Toast.LENGTH_SHORT).show ();
                        break;
                    case SmsManager.RESULT_ERROR_NO_SERVICE:
                        Toast.makeText (MainActivity.this, "Network unavailable", Toast.LENGTH_SHORT).show ();
                        break;
                    case SmsManager.RESULT_ERROR_NULL_PDU:
                        Toast.makeText (MainActivity.this, "No pdu provider detected", Toast.LENGTH_SHORT).show ();
                        break;
                    case SmsManager.RESULT_ERROR_RADIO_OFF:
                        Toast.makeText (MainActivity.this, "Radio off", Toast.LENGTH_SHORT).show ();
                        break;
                }
            }
        };

        registerReceiver (sentReceiver, new IntentFilter (SENT));

        BroadcastReceiver deliveredReceiver = new BroadcastReceiver () {
            @Override
            public void onReceive (Context context, Intent intent) {
                switch (getResultCode ()) {
                    case RESULT_OK:
                        Toast.makeText (MainActivity.this, "Message delivered", Toast.LENGTH_SHORT).show ();
                        break;
                    case RESULT_CANCELED:
                        Toast.makeText (MainActivity.this, "Message delivery failed", Toast.LENGTH_SHORT).show ();
                }
            }
        };

        registerReceiver (deliveredReceiver, new IntentFilter (DELIVERED));

        SmsManager sms = SmsManager.getDefault ();
        sms.sendTextMessage (address, null, body, sentPendingIntent, deliveredPendingIntent);
    }
}

SmsReceiver.java

public class SmsReceiver extends BroadcastReceiver {
    private static final int REQUEST_CODE = 800;
    public static final String TAG = "logs";

    @Override
    public void onReceive (Context context, Intent intent) {
        Bundle bundle = intent.getExtras ();
        SmsMessage[] messages;

        String address = "";
        String body = "";
        if (bundle != null) {
            Object[] pdus = (Object[]) bundle.get ("pdus");
            messages = new SmsMessage[pdus.length];
            for (int i = 0; i < messages.length; i++) {
                messages[i] = SmsMessage.createFromPdu ((byte[]) pdus[i]);
                address = messages[i].getOriginatingAddress ();
                body = messages[i].getMessageBody ().toString ();
            }

            Toast.makeText (context, address + "\n" + body, Toast.LENGTH_SHORT).show ();

            Intent broadcastIntent = new Intent ("SMS_RECEIVED_ACTION")
                    .putExtra ("address", address)
                    .putExtra ("body", body);
            context.sendBroadcast (broadcastIntent);

            sendNotification (address, body, context);
            abortBroadcast ();
        }
    }

    private void sendNotification (String address, String body, Context context) {
        NotificationCompat.Builder builder = new NotificationCompat.Builder (context);
        Intent smsIntent = new Intent (context, MainActivity.class);

        smsIntent.putExtra ("address", address).putExtra ("body", body)
                .setAction ("SMS_RECEIVED_ACTION")
                .setFlags (Intent.FLAG_ACTIVITY_NEW_TASK)//Not sure but problem can be in this flags, but I don't know which flags better to use
                .setFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP)
        ;

        PendingIntent smsNotificationPendingIntent = PendingIntent.getActivity (context,
                REQUEST_CODE,
                smsIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        builder.setContentTitle (address)
                .setContentText (body)
                .setSmallIcon (android.R.drawable.ic_dialog_email)
                .setContentIntent (smsNotificationPendingIntent)
                .setAutoCancel (true)
        ;

        Notification notification = builder.build ();

        NotificationManager manager = (NotificationManager) context.getSystemService (context.NOTIFICATION_SERVICE);
        manager.notify (0, notification);
    }

}

Manifest.xml

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

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity" android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <receiver android:name=".SmsReceiver">
            <intent-filter android:priority="999">
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

P.S. Problem appears only when app is closed (moved from stack) in other cases it works fine.

Upvotes: 0

Views: 396

Answers (1)

Arthur
Arthur

Reputation: 789

SOLUTION

In order to get data from notification, send it to closed main activity and show it on screen you need to get data from intent by invoking getIntent() in onCreate() method. Code should look something like this:

    if (getIntent ().getExtras ()!=null){ //checking if intent send from notification contains any data, otherwise TextView will show "null" 
       receivedSmsTextView.setText (getIntent ()
      .getStringExtra ("address") + "\n" +
       getIntent ().getStringExtra ("body"));
            }

Upvotes: 1

Related Questions