Hi everyone .
i send message to one device and receive this sms in another device's application.I used Broascast receiver to listen sms body or number .I have taken all permission in manifest but my reciver not call.I have used many thing in 2 days related to manifest like android:priority,android:enabled="true", android:exporte but stiil receiver not working.
/* final SmsManager sms = SmsManager.getDefault();*/
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "in receiver", Toast.LENGTH_SHORT).show();
// TODO Auto-generated method stub
Log.e("out", "out");
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;
Toast.makeText(context, "broad cast reciver", Toast.LENGTH_SHORT).show();
if (bundle != null){
//---retrieve the SMS message received---
try{
Log.e("in", "in");
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());
}
}
}
}
manifest....
<
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_SMS" />
<application android:icon="#drawable/ic_launcher">
<activity android:name=".MainActivity" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".SmsListener" android:enabled="true" android:exported="true" android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
Have your SmsListener extend BroadcastReceiver:
public class SmsListener extends BroadcastReceiver {
public SmsListener() {
}
#Override
public void onReceive(Context context, Intent intent) {
//you code here
}
}
And now you can register your receiver in your main activity:
String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
SmsListener smsListener = new SmsListener();
registerReceiver(smsListener, new IntentFilter(SMS_RECEIVED));
Remember to unregister it at the end.
When i uninstalled other application in my device it have also same functionality like my application for example hello application (check out at play store).Then i installed my application it work great.I think another application set priority or other thing in manifest for new incoming sms.So due to this reason our application broadcast receiver not called
Changing the Priority to 1 made it work for me. It defaulted to 1000.
I also had to change the name from .SmsListener to .MainActivity$SmsListener but that would probably depend on where you defined the class (in my case it was within the MainActivity).
<receiver android:name=".MainActivity$SmsListener"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="1">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
Related
Situation: My apartment building has a closed parking lot with a gate that opens upon calling a specific number (only some numbers can open the gate, including mine).
My request: I am trying to make an application (for my own phone), which would read an incoming SMS with a specific keyword, and then call the number, which opens the gate. Furthermore, this app should work while it is not in foreground (either by running in background or maybe intent-filters?).
Is it at all possible, and how do I achieve this?
My current "solution" is provided below, but it does not work (keep in mind I'm a complete beginner).
Main activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SmsListener listener = new SmsListener();
String msgBody = listener.getMsgBody();
if (msgBody.contains("keyword")) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("number"));
startActivity(callIntent);
}
}
}
SmsListener class:
public class SmsListener extends BroadcastReceiver{
private SharedPreferences preferences;
String msgBody = "";
public String getMsgBody(){
return msgBody;
}
#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();
msgBody = msgs[i].getMessageBody();
Toast.makeText(context, msgBody, Toast.LENGTH_LONG).show();
}
}catch(Exception e){
// Log.d("Exception caught",e.getMessage());
}
}
}
}
}
I have no idea if the above code is at least partially correct, any help would be appreciated.
When I send a text from another phone, the toast I wrote does not appear, meaning that the code doesn't even run probably.
My manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.BROADCAST_SMS" /> // Error saying that only system apps can use this permission
<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">
<receiver android:name=".SmsListener">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I am trying to detect SMS received and read it via texttospeech.
when i declare the Broadcast Receiver in manifest it doesn't work. But it works when done dynamically in an activity.
I am aware that some Broadcast actions cant be caught in a receiver when declared in manifest and requires an activity(as mentioned here), but have seen people using RECEIVE_SMS in manifest as in here.
I don't know what I am doing wrong. Any help would be greatly appreciated!
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bulsy.smstalk1">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<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>
<receiver android:name="com.bulsy.smstalk1.SmsListener"
android:enabled="true"
android:permission="android.permission.BROADCAST_SMS"
android:exported="true">
<intent-filter android:priority="2147483647">//this doesnt work
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
SmsListener.java
public class SmsListener extends BroadcastReceiver{
private SharedPreferences preferences;
TextToSpeech textToSpeech;
String msg_from;
public SmsListener()
{
}
#Override
public void onReceive(final 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;
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();
final String msgBody = msgs[i].getMessageBody();
textToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
textToSpeech.setLanguage(Locale.UK);
String fromName = getContactName(context,msg_from);
fromName = fromName==null? msg_from:fromName;
textToSpeech.speak("You have a text message from " + fromName + ". Content: " + msgBody , TextToSpeech.QUEUE_FLUSH, null);
}
}
}
);
}
}catch(Exception e){
// Log.d("Exception caught",e.getMessage());
}
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SmsListener smsListener = new SmsListener();//Dynamically setting the receiver. this works.
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
this.registerReceiver(smsListener,filter);
}
}
The root of the problem here is the lifetime of a manifest-registered Receiver instance. An instance of such a Receiver will only be alive until the onReceive() method completes. The TextToSpeech object will not be ready before the Receiver dies, and without any other indication of the Receiver working, it appears as though the Receiver has just failed.
The solution is to move the TextToSpeech functionality to a Service you can run from the Receiver, and pass the necessary info as extras on the Intent used to start it.
My app needs to be able to receive SMS messages. It all works, but I get this lint warning:
BroadcastReceivers that declare an intent-filter for SMS_DELIVER or
SMS_RECEIVED must ensure that the caller has the BROADCAST_SMS
permission, otherwise it is possible for malicious actors to spoof
intents.
How do I "ensure that the caller has the BROADCAST_SMS permission"?
In my manifest I have:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application ...>
<receiver
android:name=".SmsReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
My code:
public class SmsReceiver extends BroadcastReceiver {
public SmsReceiver() {}
#Override
public void onReceive(final Context context, final Intent intent) {
final Bundle bundle = intent.getExtras();
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
final SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
// use currentMessage
}
}
}
}
Add android:permission="android.permission.BROADCAST_SMS" to the opening <receiver> tag. For example:
<receiver
android:name=".SmsReceiver"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
This android:permission attribute on a <receiver> specifies which permission the sender of the broadcast must hold in order for it to be able to broadcast to your <receiver>. It's a security measure; in this case, so you can be relatively certain that it is the system sending the SMS_RECEIVED broadcast. It's not strictly required, but lint will complain if it's not there, obviously.
I have read many similar questions that usually results in an answer about priority. The reason I don't think this is true in my case is that other SMS readers on my phone (like automation apps) receive the broadcasts just fine. I would like to post the process of what I'm doing currently and make triple sure that I'm not doing something wrong in my code that would cause this to fail. Thanks for any tips you can give!
Note: I've tried with the highest integer priority, priority 99, 100, 0, or none set at all. They all don't work.
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hennessylabs.appname" >
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_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:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.hennessylabs.drivercompanion.ProcessTextMessage" android:exported="true">
<intent-filter android:priority="999" android:permission="android.permission.BROADCAST_SMS">
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
</application>
</manifest>
BroadcastReceiver:
package com.hennessylabs.appname;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Telephony;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
/**
* Created by kyleC on 11/15/2015.
*/
public class ProcessTextMessage extends BroadcastReceiver {
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
final SmsManager sms = SmsManager.getDefault();
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Entered onReceive", Toast.LENGTH_LONG).show();
// Retrieves a map of extended data from the 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();
Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + message);
// Show alert
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, "senderNum: " + senderNum + ", message: " + message, duration);
toast.show();
} // end for loop
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" +e);
}
}
}
Expected Result:
The expected result is that when an SMS arrives, the screen would first show a Toast that it entered the OnReceive method. Then it would log and Toast the contents of the SMS.
Actual Result:
Nothing from the expected result happens. In fact even while connected to USB and in debug mode it never seems to enter that class at all. So maybe I have my manifest set up wrong?
Provided everything else is correct, it looks like you're just missing the RECEIVE_SMS permission.
<uses-permission android:name="android.permission.RECEIVE_SMS" />
You are missing some things from the manifest declaration of your receiver. You must declare exported=true and you must require the BROADCAST_SMS permission. See working example:
<receiver android:name=".sms.IncomingSmsReceiver" android:exported="true">
<intent-filter android:priority="999" android:permission="android.permission.BROADCAST_SMS">
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
So what is the version of the device your app is running on?
Begins in Android 4.4, only the default sms app can receive the SMS_DELIVER_ACTION broadcast.
more information: http://android-developers.blogspot.sg/2013/10/getting-your-sms-apps-ready-for-kitkat.html
I am trying to get phone number and phonebook name from a text message. When I run it from application, and close application, it works, but, when I restart my mobile, it doesn't work. Anybody?
public class IncomingSMSReceiver extends BroadcastReceiver {
private static final String queryString = "#zovi";
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
public void onReceive(Context _context, Intent _intent) {
if (_intent.getAction().equals(SMS_RECEIVED)) {
Intent intent = new Intent(_context, IncomingSMSService.class);
_context.startService(intent);
Bundle bundle = _intent.getExtras();
if (bundle != null) {
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 msg = message.getMessageBody();
Log.i("Poruka", msg);
String to = message.getOriginatingAddress();
String contactName = TelefonUtils.getContact(_context, to);
Log.i("Od", contactName + "\n" + to);
}
}
}
}
}
My XML:
<receiver android:name=".telefon.receivers.IncomingSMSReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="500">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
In your AndroidManifest.xml try to add <action android:name="android.intent.action.BOOT_COMPLETED" /> action under IncomingSMSReceiver receiver tag.
To start Services or BroadcastReceiver automatically after the Android system restarts or starts you can register a BroadcastReceiver to the Android android.intent.action.BOOT_COMPLETED system event.
Try this code.
<receiver android:name=".telefon.receivers.IncomingSMSReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="500">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
If you have tried android.intent.action.BOOT_COMPLETED then it will not work in your case because you forgot to add BOOT_COMPLETED intent in your
IncomingSMSReceiver and it will work only in case of android.provider.Telephony.SMS_RECEIVED because of if condition you have used in IncomingSMSReceiver. so change if condition from
if (_intent.getAction().equals(SMS_RECEIVED)) {
to
if (_intent.getAction().equals(SMS_RECEIVED) || _intent.getAction().equals(BOOT_COMPLETED)) {
and also define private static final String BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED"; in IncomingSMSReceiver. Below is full code of IncomingSMSReceiver.
Change your IncomingSMSReceiver code to this:
public class IncomingSMSReceiver extends BroadcastReceiver {
private static final String queryString = "#zovi";
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private static final String BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
public void onReceive(Context _context, Intent _intent) {
if (_intent.getAction().equals(SMS_RECEIVED) || _intent.getAction().equals(BOOT_COMPLETED)) {
Intent intent = new Intent(_context, IncomingSMSService.class);
_context.startService(intent);
Bundle bundle = _intent.getExtras();
if (bundle != null) {
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 msg = message.getMessageBody();
Log.i("Poruka", msg);
String to = message.getOriginatingAddress();
String contactName = TelefonUtils.getContact(_context, to);
Log.i("Od", contactName + "\n" + to);
}
}
}
}
}
So when your phone restarts it will receive android.intent.action.BOOT_COMPLETED and call your IncomingSMSReceiver receiver then it will start your IncomingSMSService.
I hope it will help you.
Make sure that the receiver starts after phone reboots.
Add <action android:name="android.intent.action.BOOT_COMPLETED" /> in intent-filter
I used this in my project, find this from Android SMS Receive Listener
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import java.util.ArrayList;
/**
* ##author Chathura Wijesinghe <cdanasiri#gmail.com>
*
* <receiver android:name=".SMSReceiver" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
*/
public class SMSReceiver extends BroadcastReceiver {
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private static ArrayList<SMSReceivedListner> smsListner = new ArrayList<SMSReceivedListner>();
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
final Bundle extras = intent.getExtras();
if (action.equals(SMSReceiver.SMS_RECEIVED)) {
final boolean smsValid = extras != null;
if (smsValid) {
//Create SMSMessages from PDUs in the Bundle
final Object[] pdus = (Object[])extras.get("pdus");
final SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++)
messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
//Assemble
final ArrayList<Long> vibrations = new ArrayList<Long>();
for (SmsMessage message : messages) {
for (SMSReceivedListner smsReceivedListner : smsListner )
smsReceivedListner.message(message);
}
}
}
}
public static void addSMSListner(SMSReceivedListner listner){
smsListner.add(listner);
}
public static void removeSMSListner(SMSReceivedListner listner){
smsListner.remove(listner);
}
public interface SMSReceivedListner{
public void message(SmsMessage message);
}
}
You have to remove the android:permission="android.permission.BROADCAST_SMS" from the receiver declaration. No BOOT_COMPLETED or other permission are required.
explicitly set exported to true in your manifest as an element for the Receiver
android:exported="true"
and make sure both of your application element and receiver element are enabled
android:enabled="true"
Broadcast code seems to be okay and Make sure that you are using any other SMS apps in your device(May this SMS Broadcast might interrupting your apps Broadcast) . If you are not using no other SMS apps then it should work otherwise un-install that SMS app and try once.
and also check you have added the following permissions in your AndroidManifest.xml
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
Hope this will work.
Ideally it should have worked.Is weird that its not working.
Remove android:permission="android.permission.BROADCAST_SMS" from the broadcast receiver.It is not required.
Try increasing the priority android:priority="2147483647" to maximum.It might be some other app is consuming the event or try the below solution.
Add <action android:name="android.intent.action.BOOT_COMPLETED" /> in your intent filter and see if it works.
Something like this:
<receiver android:name=".telefon.receivers.IncomingSMSReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="500">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
and add permission:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>