将数据从通知发送到已结束的活动

时间:2016-04-20 17:23:51

标签: java android notifications

我决定制作简单的接收/发送短信应用。目前几乎所有功能都运行良好,除了一件事 - 将数据从通知发送到已关闭的应用程序。例如,当用户收到短信并弹出通知时,他会按下它并启动主要活动。在此主要活动中应显示来自短信和发件人编号的文本。但是当我点击通知主要活动启动并且什么也没显示时。

主要活动.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。问题仅在app关闭(从堆栈移动)时出现,在其他情况下它可以正常工作。

1 个答案:

答案 0 :(得分:1)

为了从通知中获取数据,将其发送到已关闭的主要活动并在屏幕上显示,您需要通过在onCreate()方法中调用getIntent()来获取意图数据。代码看起来像这样:

    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"));
            }