I want open App when receive SMS.
I try to handle this problem using Manifest-declared receivers.
Here is my code
<AndroidManifest.xml>
<receiver
android:name=".service.SMSReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
#Override
public void onReceive(Context context, Intent intent) {
packageManager = context.getPackageManager();
if("android.provider.Telephony.SMS_RECEIVED".equals(intent.getAction())) {
Bundle bundle = intent.getExtras();
Object[] messages = (Object[]) bundle.get("pdus");
for (Object pdu : messages)
{
SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu);
if(message == null)
{
Log.e(TAG,"message is null");
break;
}
smsSender = message.getDisplayOriginatingAddress();
if(smsSender.compareTo(number)==0)
{
receivedData = new Date(message.getTimestampMillis());
smsBody = message.getDisplayMessageBody();
Log.i(TAG, "onReceive: "+smsBody);
SendToActivity(context,smsSender,smsBody,receivedData);
}
}
}
}
private void SendToActivity(Context context, String sender, String contents, Date receivedDate) {
Log.i(TAG, "SendToActivity: TEST ");
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|
Intent.FLAG_ACTIVITY_SINGLE_TOP|
Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("contents",contents);
context.startActivity(intent);
Log.i(TAG, "SendToActivity: RUN >> ");
}
this code works only when app is onPause().
I want to work even app is terminated.
Is possible that terminated app open automatically when SMS received at Android 9?
No, you can't do this. There are certain limitations that Android had put on the Broadcast Receivers.
There are certain broadcasts that Apps can't listen to, and it includes the SMS broadcast too.
You can find more about here
There are some broadcasts which your app can listen to when terminated, you can find the list here
Related
I have a broadcast receiver registered to receive SMS inside a service. The intention of the Application is to get the SMS on receive and save the contents of SMS from expected sender in Sqlite storage. The App need to capture the SMS received also even when the App is not running in background.
public class SMSService extends Service {
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public static final String SMS_BUNDLE = "pdus";
ContentValues userValues;
Object[] sms;
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("android.provider.Telephony.SMS_RECEIVED")) {
Log.d("~~~ SMS !!!", "~~~ SMS ~~~ SMS ~~~ SMS~~~ SMS ~~~");
AsyncSmsHandler asyncSmsHandler = new AsyncSmsHandler(context, intent);
asyncSmsHandler.execute("");
}
}
class AsyncSmsHandler extends AsyncTask<String, Void, String> {
Context context;
Intent intent;
public AsyncSmsHandler(Context context, Intent intent) {
this.context = context;
this.intent = intent;
}
#Override
protected String doInBackground(String... params) {
String smsBody = "", address = "";
Bundle intentExtras = intent.getExtras();
SmsMessage smsMessage = null;
if (intentExtras != null) {
sms = (Object[]) intentExtras.get(SMS_BUNDLE);
String smsMessageStr = "";
for (int i = 0; i < sms.length; ++i) {
smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]);
smsBody = smsBody + smsMessage.getMessageBody();
smsMessageStr += smsBody + "\n";
}
address = smsMessage.getOriginatingAddress();
Log.d("SMS RECEIVER NUMBER", " " + smsBody + " -- " + sms.length);
//SAVE THE MESSAGE AND NUMBER
}
return "";
}
#Override
protected void onPostExecute(String result) {
// Create an explicit intent for an Activity in your app
Intent intent = new Intent(context, AquaOrderList.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "CHANNEL_ID")
.setSmallIcon(R.drawable.logo)
.setContentTitle(“TITLE”)
.setContentText(“Message”)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(1, builder.build());
}
}
};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(receiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(receiver);
}
}
In this way registering the receiver in onCreate and unregisterReceiver on onDestroy methods.
This work as expected but when I kill the App and after a while, If I receive SMS, it is not getting triggered. If I open the App again, after that SMS starts saving in the storage.
Is the service getting destroyed ? I checked in the "Running Services" in mobile and I can see the service running.
I have also added the permissions in manifest file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xyz.app”>
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<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">
<service
android:name=".SMSService"
android:enabled="true"
android:exported="true"></service>
<activity
android:name=".OrderList"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/title_activity_order_list"
android:theme="#style/FullscreenTheme"></activity>
<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>
I want to have the Application listening for incoming SMS even the App is not in the stack. What can be the approach I can follow to get this done.
I am not in total agreement with #Ranjan's comments. Yes, services are
destroyed and kept running by android & yeah, it is difficult to run a
service permanently. However if you have done everything correctly,
how many ever times your service is destroyed, it would be launched
again (automatically), and on launch, your receiver should be
registered.
My tips are:
Firstly, make sure your are NOT targeting latest SDK. I am using targetSDK 10, minSDK 17, and compileSDK 26. That could make a difference on how your services are treated. Play around with these values to check if this alone makes it work.
Next, please follow this thread HERE and try to create your receiver properly.
I'm not sure about what your problem is exactly, however I can tell you, that we have a video conferencing application, that listens to incoming calls and messages. So of course, the BroadcastReceiver needs to be registered and Service should be running in the background. This app is a little old, and was developed with targetSDK 10 etc. So they are doing it in the way that was common then. We still haven't ported our application, so we don't know what problems exist in newer Android. As I mentioned, our app compiles with SDK26.
Code Sample:
public SampleService() {
super();
Log.d(TAG, "SampleService: Constructor");
final HandlerThread mHandlerThread = new HandlerThread(BR_THREAD_NAME, Process.THREAD_PRIORITY_BACKGROUND);
mHandlerThread.start();
bgLooper = mHandlerThread.getLooper();
mBRHandler = new Handler(bgLooper);
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate: ");
registerReceiver();
}
private void registerReceiver() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(SOME_ACTION);
myReceiver = new MyReceiver();
registerReceiver(myReceiver, intentFilter, null, mBRHandler);
}
This should be good enough
Can anyone please tell me if it is possible to "wake up" my Android service as soon as there's an incoming SMS event? What I meant to say is that, whenever an SMS is received, there will be a system-wide broadcast of this event. Can I intercept this broadcast to start my own background service? I know, it's not possible to run my service permanently in the background (not to mention it's a bad design practice).
Any help would be highly appreciated!
EDIT: Adding more detail to my original question. My broadcast receiver will be wrapped inside a service class. But there is a chance the Android will kill my background service in the event of memory crunch. In that case, even if there is an incoming SMS, my service won't be fired. How can I deal with this situation? This was the main intent of the question. I know it's not possible to run my service permanently in the background (or is it possible? perhaps if I have root access?)
Create Broadcast Receiver
public class BrodcastReceiverClass extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber;
String message = currentMessage.getDisplayMessageBody();
try {
if (senderNum.equals("MD-DOCOMO")){ //SMS Provider Name
OTPActivity Sms = new OTPActivity();
Sms.recivedSms(message);
}
} catch (Exception e) {
}
}
}
} catch (Exception e) {
}
}
}
Register BrodcastReceiver in your manifest
<receiver android:name=".BrodcastReceiverClass ">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
call in you activity for e.g your activity name is OTPActivity than write thi code in your OTPActivity.
public void recivedSms(String message) {
try {
Log.d("message is receive", message);
} catch (Exception e) {
Log.e("message not receive", e.getMessage() + "");
}
}
Add permission in manifest read sms
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
We are looking to build the functionality in our app to read a security code that being sent as part of SMS and display on the textView.
Also, I am not looking to build a broadcast receiver, may be an intent service which only will start run on a particular screen and kill the service once user navigated to another screen.
It would be great if anyone can shade some light and help with some sample code.
To read incoming SMS you have to do three things.
Broadcast Receiver
Declare Broadcast Receiver in manifest
Need SMS Receive permissions
Note: If you are compiling against 6.0 Marshmallow you have get android.permission.RECEIVE_SMS at runtime. Runtime Permissions
Lets Starts Receiving incoming SMS
1) First add permissions in manifest
<uses-permission android:name="android.permission.RECEIVE_SMS" />
2) Declare Broadcast Receiver in Manifest.
What this declaration do it will inform you when ever a new SMS Receive by device.
<receiver android:name="com.example.abc.ReciveSMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
3) Add this code to your declared class in manifest
public class ReciveSMS extends BroadcastReceiver{
private SharedPreferences preferences;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
Bundle bundle = intent.getExtras(); //---get the SMS message passed in---
SmsMessage[] msgs = null;
String msg_from;
if (bundle != null){
//---retrieve the SMS message received---
try{
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for(int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
msg_from = msgs[i].getOriginatingAddress();
String msgBody = msgs[i].getMessageBody();
}
}catch(Exception e){
// Log.d("Exception caught",e.getMessage());
}
}
}
}
}
Original Post here.
I'd like to intercept a Rich Communication message (know as Chat on some networks like Vodafone). I've successfully implemented an SMS receiver using an intent filter and broadcast receiver which works great. However if the SMS is a Rich Communication message the receiver never gets called.
In my manifest:
<receiver
android:name=".IncomingSMS"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
and my broadcast receiver looks like this:
public class IncomingSMS extends WakefulBroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// Retrieves a map of extended data from the intent.
final Bundle bundle = intent.getExtras();
if (bundle != null)
{
final Object[] pdusObj = (Object[]) bundle.get("pdus");
SmsMessage currentMessage;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
String format = bundle.getString("format");
currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[0], format);
}
else
{
//noinspection deprecation
currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[0]);
}
String number = currentMessage.getDisplayOriginatingAddress();
Intent serviceintent = new Intent(context, ChargingMonitorService.class);
serviceintent.putExtra(NUMBER, number);
startWakefulService(context, serviceintent);
} // bundle is null
}
}
This all works perfectly except if the text message is a Rich Communication (or chat) message the onReceive() is never called.
There is nothing in the Android docs so I'm assuming its going to be a vendor specific intent but what is it?
After a bit of reverse engineering I've figured out and answer for Samsung devices. I looked at the manifest of the Messages app on a rooted Samsung device to find the intents. I then setup my own receiver and inspected the Bundle extras for any useful data.
In the manifest:
<receiver
android:name=".RCSReceiver"
android:permission="com.samsung.rcs.permission.RCS_APP_PERMISSION"
android:enabled="true"
android:exported="true">
<intent-filter>
<category android:name="com.samsung.rcs.framework.instantmessaging.category.ACTION"/>
<category android:name="com.samsung.rcs.framework.instantmessaging"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_CHAT_INVITATION"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_INSERTED"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_UPDATED"/>
</intent-filter>
</receiver>
with the additional permission:
<uses-permission android:name="com.samsung.rcs.im.READ_PERMISSION"/>
And the receiver code looks like this:
public class RCSReceiver extends BroadcastReceiver
{
private static final String RECEIVE_CHAT_INVITATION = "com.samsung.rcs.framework.instantmessaging.action.RECEIVE_CHAT_INVITATION";
private static final String RECEIVE_PARTICIPANT_UPDATED = "com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_UPDATED";
private static final String RECEIVE_PARTICIPANT_INSERTED = "com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_INSERTED";
private Logger log = LoggerFactory.getLogger(MainActivity.class);
#Override
public void onReceive(Context context, Intent intent)
{
log.debug("RCS Receiver");
String action = intent.getAction();
Bundle bundle = intent.getExtras();
if(bundle != null)
{
if (RECEIVE_PARTICIPANT_UPDATED.equals(action) || RECEIVE_PARTICIPANT_INSERTED.equals(action))
{
String participant = bundle.getString("participant");
if (participant != null)
{
String number = participant.substring(4); // get the string after "tel:"
log.debug("Chat number is: " + number);
}
}
else if (RECEIVE_CHAT_INVITATION.equals(action))
{
String subject = bundle.getString("subject");
if(subject != null)
{
log.debug("Chat subject: " + subject);
}
}
}
}
}
In the "participant" extra was the telephone number prefixed with "tel:" and the message text was in the subject bundle extra.
This, of course, will only work on Samsung devices and since its not a published API is obviously subject to change without notice so its unknown how long it will work for or if it works on all versions of Android on Samsung. However, it served my purpose of intercepting the number of an incoming chat.
The full list of actions is below however only the two shown above had anything useful in the bundle extras. The extra data for the other intents were in Parcels and would require quite a bit more effort in reverse engineering.
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_TYPING_NOTIFICATION"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_CHAT_CLOSED"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_NEW_MESSAGE"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.DELETE_MESSAGES_RESPONSE"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.DELETE_CHATS_RESPONSE"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_CHAT_INVITATION"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.SEND_MESSAGE_RESPONSE"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_MESSAGE_NOTIFICATION_STATUS"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_SEND_MESSAGE_RESPONSE"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.ADD_PARTICIPANTS_RESPONSE"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_MESSAGE_INSERTED"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_INSERTED"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_UPDATED"/>
<action android:name="com.samsung.rcs.framework.instantmessaging.action.GET_IS_COMPOSING_ACTIVE_URIS_RESPONSE"/>
I want to make an aaplication that has the feature of controlling my phone from remotely.Such as on/off GPS through text message from another phone.Getting the location from phone via text message.
Is it possible to on/off gps through text message from another phone?
Definitely yes.
You just need to add in you application a receiver for the Action android.provider.Telephony.SMS_RECEIVED and parse the message text if you recognize ac command in your phone, you execute some code.
Basically you need to do three things:
Update you manifest abd add permission for your application to receive SMS:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
Then you have to add, again in the manifest a receiver, that receive the SMS_RECEIVED Action, in a way similar to the following:
<receiver android:name=".SMSReceiver" android:enabled="true" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
Where android.name is the name of your Receiver class.
And finally you have to implement that class, that extends BroadCastReceiver and has at least the onReceive Method implemented.
public class SmsReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
}
}
For your help, below there an example onReceive code:
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Object[] pdus = (Object[])bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[pdus.length];
for(int i = 0; i < pdus.length; i++){
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
for(SmsMessage message: messages){
String messagestr = message.getMessageBody();
String sender = message.getOriginatingAddress();
Toast.makeText(context, sender + ": " + messagestr, Toast.LENGTH_SHORT).show();
}
}
That code, read the message content and show it on a Toast. You can find a full working example here: https://github.com/inuyasha82/ItalialinuxExample/tree/master/LezioniAndroid
Recieving (handling) SMS-es is possible with Android. Your software should read the SMS, then decide if it contains command and turn off the GPS like normal app would.
This link shows how http://www.apriorit.com/dev-blog/227-handle-sms-on-android