Monitoring an incoming SMS with Toast - java

I want to monitor an incoming sms in a phone by making a Toast message pop up when a sms is received. However, with the following code, I don't receive the Toast message even when a sms is received. Why is that so? I'm using Android Studio 3.0.1 and there are no errors when I run the code.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mapp.com.sg.broadcastreceiver">
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java
public class MainActivity extends Activity {
private static final int NOTIFY_ME_ID = 1337;
private BroadcastReceiver the_receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, "SMS Message Received!", duration);
toast.show();
}
};
private IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
// Register receiver if activity is in front
this.registerReceiver(the_receiver, filter);
super.onResume();
}
#Override
protected void onPause() {
// Unregister receiver if activity is not in front
this.unregisterReceiver(the_receiver);
super.onPause();
}
}

Do as following by adding the receiver in the manifest file
<receiver
android:name=".receivers.SMSReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
and then create SMSReceiver class
public class SMSReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Bundle myBundle = intent.getExtras();
SmsMessage[] messages;
if (myBundle != null) {
Toast toast = Toast.makeText(context, "SMS Message Received!",duration);
}
}
}

Related

How to set broadcast receiver attributes programmatically?

I'm broadcasting an intent in my app and receiving it with a broadcast receiver. I can handle the broadcasting and receiving. No problem with that. However, I want to register the receiver completely programmatically instead of doing it in the manifest file. Notice, that in the manifest file, there are two attributes of the receiver android:enabled="true" and android:exported="false". I need to know, how do I specifically set these two attributes when I register the receiver programmatically?
My AndroidManifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mybroadcastapplication">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.MyBroadcastApplication">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="false">
</receiver>
</application>
</manifest>
My MainActivity.java file:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
MyBroadcastReceiver myReceiver;
IntentFilter intentFilter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver = new MyBroadcastReceiver();
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.mybroadcastapplication.EXPLICIT_INTENT");
findViewById(R.id.button1).setOnClickListener(this);
}
public void broadcastIntent() {
Intent intent = new Intent();
intent.setAction("com.example.mybroadcastapplication.EXPLICIT_INTENT");
getApplicationContext().sendBroadcast(intent);
}
#Override
protected void onPostResume() {
super.onPostResume();
registerReceiver(myReceiver, intentFilter);
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(myReceiver);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
broadcastIntent();
break;
default:
}
}
}
My MyBroadcastReceiver.java file:
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() != null && intent.getAction().equals("com.example.mybroadcastapplication.EXPLICIT_INTENT"))
Toast.makeText(context, "Explicit intent received.", Toast.LENGTH_LONG).show();
}
}
Regards
You don't need to declare the BroadcastReceiver in the manifest if you are registering/unregistering programmatically. You only need to declare BroadcastReceivers in the manifest if you want them to be instantiated from external triggers (for example, on device boot, or from the Alarm Manager, etc.)

Can't read SMS on android

I can't seem to get a basic sms reading app to work on android. Not sure what am I missing here. I think I have all the basic minimum specified in the code, despite that it seems to be not working. The onReceive() of SmsReceiver is never invoked. All the required permissions are set.
Here are my files.
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//...
//...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestReadAndSendSmsPermission();
smsReceiver = new SmsReceiver() {
#Override
protected void onData(String data) {
//handle
}
};
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
//intentFilter.setPriority(999);
registerReceiver(smsReceiver, intentFilter);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(smsReceiver);
}
private void requestReadAndSendSmsPermission() {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_SMS},1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECEIVE_SMS},1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_RESPOND_VIA_MESSAGE}, 1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_SMS}, 1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_NETWORK_STATE}, 1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CHANGE_NETWORK_STATE}, 1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.INTERNET}, 1);
}
//...
//...
}
SmsReceiver.java
public abstract class SmsReceiver extends BroadcastReceiver {
private static final String TAG = "SmsReceiver";
#Override
public void onReceive(Context context, Intent intent) {
if (context == null || intent == null) {
return;
}
String action = intent.getAction();
if (!action.equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
return;
}
//read sms
onData("sms received");
}
protected abstract void onData(String data);
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mysmsapp">
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.MySMSApp">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
You are missing defining the receiver entry in AndroidManifest.xml file for your BroadcastReceiver named SmsReceiver please make the entry for it else OS will not know if you have a broadcast receiver waiting to be triggered.
Depending upon what is your use case it might be something like
<receiver
android:name=".SmsReceiver"
android:exported="true"
android:permission="com.google.android.gms.auth.api.phone.permission.SEND">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>
Or
<receiver
android:name=". SmsReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Note: These receiver are sample receiver please use the correct one as per your use case, the main point is you are missing receiver entry in your manifest file
i use this code to read incoming message
public class SmsReceiver extends BroadcastReceiver {
private static final Uri smsuri = Apconsts.smsuri;
private static final String pdu_type = "pdus";
#Override
public void onReceive(Context context, Intent intent){
// Get the SMS message.
Bundle bundle = intent.getExtras();
SmsMessage[] msgs;
String format = bundle.getString("format");
// Retrieve the SMS message received.
Object[] pdus = (Object[]) bundle.get(pdu_type);
String body="";String adrs="";
if (pdus != null) {
msgs = new SmsMessage[pdus.length];
for (int i = 0; i < msgs.length; i++){
if(Build.VERSION.SDK_INT < 23){ msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); }
else{ msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i], format); }
adrs=msgs[i].getOriginatingAddress();
body += ""+msgs[i].getMessageBody();
}
Toast.makeText(getApplicationContext(), "The message Body: "+body+"\nThe address: "+adrs, Toast.LENGTH_LONG).show();
}
}
}
and this receiver in manifest
<receiver android:name=".SmsReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>

scheduling alarmmanager not working on reboot my phone

It's toasting until I didn't restart my phone but after restarting broadcastreceiver2 doesn't receive and nothing happens.
I followed http://stacktips.com/tutorials/android/how-to-start-an-application-at-device-bootup-in-android and many other but nothing happens.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.k2.alarmmanagerdemo">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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" />
</intent-filter>
</activity>
<receiver android:name="com.k2.alarmmanagerdemo.MyBroadcastReceiver"
android:enabled="true">
</receiver>
<receiver android:name="com.k2.alarmmanagerdemo.BroadCastRecevier2"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity.java
public class MainActivity extends Activity {
Button b1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1=(Button) findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
startAlert();
}
});
}
public void startAlert() {
EditText text = (EditText) findViewById(R.id.time);
int i = Integer.parseInt(text.getText().toString());
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this.getApplicationContext(), 234324243, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),
1000 * 5,pendingIntent);
Toast.makeText(this, "Alarm set in " + i + " seconds",Toast.LENGTH_LONG).show();
}
}
MyBroadcastReceiver.java
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm...." + System.currentTimeMillis(), Toast.LENGTH_SHORT).show();
Log.i("Alarm.", "alarm called" + System.currentTimeMillis());
}
}
BroadCastRecevier2.java
public class BroadCastRecevier2 extends BroadcastReceiver {
MainActivity activity = new MainActivity();
#Override
public void onReceive(Context context, Intent intent) {
activity.startAlert();
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Intent i = new Intent();
i.setClassName("com.k2.alarmmanagerdemo",
"com.k2.alarmmanagerdemo.MainActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Toast.makeText(context, "BOOT", Toast.LENGTH_SHORT).show();
Log.i("myboot","boot compleated inside");
}
}
}
Remove this line from your <receiver> declaration for BroadcastReceiver2:
android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
That line in the <receiver> tag is telling the system that only packages which have this permission are allowed to send your class the Intent. Its' likely confusing the system and preventing the Intent from being sent to your receiver.
You may also find this article helpful when learning about alarms and the boot complete receiver.

Android: Receive and forward text message from service

I am trying to make a simple app that will forward all messages with particular body to another number.
Broadcast receiver in my class is not being called. Any leads will be appreciated
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Settings.Applog("App started !!");
Intent intent = new Intent(this, SMSService.class);
startService(intent);
}
SMSService.java
public class SMSService extends Service {
private IntentFilter mIntentFilter;
private SMSreceiver mSMSreceiver;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate()
{
super.onCreate();
Settings.Applog("Service started !!");
//SMS event receiver
mSMSreceiver = new SMSreceiver();
mIntentFilter = new IntentFilter();
mIntentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(mSMSreceiver, mIntentFilter);
}
#Override
public void onDestroy()
{
super.onDestroy();
// Unregister the SMS receiver
unregisterReceiver(mSMSreceiver);
}
private String ConvertNumber(String from){
return from;
}
public class SMSreceiver extends BroadcastReceiver
{
private final String TAG = this.getClass().getSimpleName();
#Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
String strMessage = "";
Settings.Applog("Got a message!!");
if ( bundle != null )
{
try{
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage[] msgs = new SmsMessage[pdus.length];
for(int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
String msg_from = msgs[i].getOriginatingAddress();
String msgBody = msgs[i].getMessageBody();
Settings.Applog("Message body ::"+msgBody);
}
}catch(Exception e){
//Log.d("Exception caught",e.getMessage());
}
}
}
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="mypackage">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".SMSService"
android:exported="false">
</service>
</application>
</manifest>
You have to register the Broadcast Receiver for receiving SMS in the manifest file.
Just the permission will not work.
Inside the application tag it would look something like:
<application android:icon="#drawable/icon" android:label="#string/app_name" android:debuggable="true" >
<receiver android:name=".SMSBroadcastReceiver">
<intent-filter>
<action android:name="android.provider.telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
</application>
Use this as an example for receiving the SMS message. It should be a good starting point.
http://javapapers.com/android/android-receive-sms-tutorial/

Starting a process when the phone turns on and Keep it running when the app closes. Android

I am new to android and I am trying to learn by doing some basics projects. The current app I am working on requires me to use BroadcastReceiver, but I need it to run when the phone starts and when the app closes.
I need it to receive all the incoming SMS, even when the app is not running.
Currently I have a startForeground which uses a notification to run. Is there a way to make the app run without the notification?
Please help. Here is my code:
public class IncomingSMS extends Service {
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
//get audioManager
AudioManager aud;
public void onCreate(){
Log.i("MyActivity", "aaa");
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, filter);
registerReceiver(receiver, filter);
Notification notification= new Notification();
startForeground(1, notification);
}
public void onDestroy(){
unregisterReceiver(receiver);
Log.i("MyActivity", "Destroyed");
}
public int onStartCommand(Intent intent, int flags, int startId){
return START_STICKY;
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Retrieves a map of extended data from the intent.
Log.i("MyActivity", "aaa");
final Bundle bundle = intent.getExtras();
aud = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
try {
if (bundle != null) {
Log.i("MyActivity", "Bundle");
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String message = currentMessage.getDisplayMessageBody();
Log.i("MyActivity", message);
//Some Code
} // end for loop
} // bundle is null
}catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" + e);
Log.i("MyActivity", "bbb");
}
}
};
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
And AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pi.sum.nesbtesh.SARA" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="......"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="......">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</service>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent" />
</application>
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
</manifest>
What you want is a BroadcastRceiever to run on phone startup, here you go. Basically you start your service in its callback.
For when the app closes, I wouldn't say that's quite possible because most of the times when you close an app, it just stats in Stopped but isn't destroyed. So I'd suggest you create a BaseActivity which is an Activity subclass that override onStop() or onPause() and start your service in this method.
Then every other Activity in your app are subclass of BaseActivity

Categories

Resources