BroadcastReceiver onReceive not firing - android

I am currently trying to create a phone number verification on registering on my Android app. Thank you for your help to read my long post!
Here is my Manifest file with other activities omitted
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.opensem"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application
android:name=".AppHelper"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<receiver android:name=".SMSReceiver">
<intent-filter android:priority="2147483647">
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
<activity
android:name=".OpenSem"
android:label="#string/title_activity_opensem" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Here is my class which I want to show a log on receive SMS
public class SMSReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG", "Received");
}
}
Here is my class sending the SMS
public class RegisterPageSubmitListener implements OnClickListener{
public void onClick(View v) {
SmsManager sm = SmsManager.getDefault();
number = ParamList.get("phone");
code = randInt(100000, 999999) + "";
sm.sendTextMessage(number, null, code, null, null);
}
}
My problem is that I successfully send the SMS and received it on my phone, but the "Received" Log was never shown. I came across the priority problem on StackOverflow and thus I added the android:priority="2147483647" in my manifest. I then added these lines (Copied from another SO post) in other activities to see if my receiver is properly registered.
Intent intent = new Intent("android.provider.Telephony.SMS_RECEIVED");
List<ResolveInfo> infos = getPackageManager().queryBroadcastReceivers(intent, 0);
for (ResolveInfo info : infos) {
Log.d("OpenSEM", "Receiver name:" + info.activityInfo.name + "; priority=" + info.priority);
}
and the resulting log is shown below:
08-01 15:27:10.417: D/OpenSEM(12880): Receiver name:com.android.mms.transaction.HighPrivilegedSmsReceiver; priority=1000
08-01 15:27:10.417: D/OpenSEM(12880): Receiver name:com.example.opensem.SMSReceiver; priority=999
08-01 15:27:10.417: D/OpenSEM(12880): Receiver name:com.android.mms.transaction.PrivilegedSmsReceiver; priority=0
It seems that my receiver's priority was set to 999 instead of 2147483647. Also, I didn't install any SMS applications, so the other priority=1000 receiver seems to belong to the system messaging application.
Did I do anything wrong? I tested my code on a Red MI (MIUI) and Samsung note II. My SMSReceiver seems to be registered and not receiving the SMS which was successfully sent back to both phones. I would really appreciate any help!!
Potato. For the long post.

It may be the restrict of your ROM, that is MIUI, I have encountered the problem that my BroadcastReceiver can't receive broadcast, but my app is OK on SamSung phone.

Related

Xamarin, Android and BroadcastReceiver

In my app I want to create a service to save constantly a device location. This service has to start when the phone is rebooted.
I changed the Android.Manifest like this
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="LocationTest">
<receiver>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
I also changed the received tag like this
<receiver android:permission="RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I defined a BroadcastReceiver like
[BroadcastReceiver]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
Intent i = new Intent(context, typeof(LocationService));
i.AddFlags(ActivityFlags.NewTask);
context.StartService(i);
}
}
I created another one from Xamarin Template like
[BroadcastReceiver]
public class BroadcastReceiverTest : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Toast.MakeText(context, "New Received intent!", ToastLength.Short).Show();
}
}
If I reboot my device, no one of the BroadcastReceiver is fired. I don't know how I can do that. My project is on GitHub
Thank you in advance.
Although it is possible to find a lot of posts about this question on line, I couldn't find one with all right information. I have created a post for future reference here.
The important thing is in your AndroidManifest: you mustn't declare your broadcast receiver in it. If you have any services, you must declare them in it. For example
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1" android:versionName="1.0"
package="pro.wordbank.app.locationtest">
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="LocationTest">
<service android:name=".TimerService" />
<service android:name=".LocationService" />
</application>
</manifest>
Also, it isn't possible to call Toast.MakeText from your Broadcast Receiver but you have to use instead NotificationManager.

Receiving SMS messages when app is closed

How can I receive SMS messages when app is closed?
Following code works fine, but when app is closed, e.g. after reboot, It doesn't work. (Actually, it works just first few minutes after app is closed, Strange...)
My AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:hardwareAccelerated="true" android:icon="#drawable/icon" android:label="#string/app_name" android:supportsRtl="true">
<activity ....>
....
</activity>
<receiver android:name=".Receiver" android:exported="true" android:enabled="true">
<intent-filter android:priority="1">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
My Receiver.java
public class Receiver extends BroadcastReceiver
{
#Override public void onReceive(Context context, Intent intent)
{
if(cond)
{
abortBroadcast();
Toast.makeText(context, "Registration Completed", Toast.LENGTH_LONG).show();
}
}
}
If you want to continue receiving SMS after your app is closed, you should implement all the stuff relied to SMS receiving in a Service that won't be closing with your application. Refer this sample to do this:
Having a Service receive SMS messages

Android text messaging app fails to run in background

I want to develop a single activity android text messaging application that receives messages from a particular phone number. All other messages are to be sent to the inbox. For this purpose, I registered a BroadcastReceiver in the AndroidManifest.xml which checks for the incoming message's phone number and then aborts the broadcast if the number matches. The message is then stored in a sqlite database which is used to display messages in a ListActivity.
However, the issue I am facing is the broadcast is not received consistently by my app, sometimes it receives the intended message and sometimes it does not(goes to inbox). The message is received in th app as long as the app is opened, and a bit after it is closed. It is simply not consistent. I gave my app a higher priority (999) in the manifest.
My Manifest is below:
`
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:allowBackup="true">
<activity
android:launchMode="singleInstance"
android:name="org.trial.hiv.HIVActivity"
android:label="#string/title_activity_hiv"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="org.trial.hiv.SMSReceiver"
android:exported="true">
<intent-filter android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<service android:name="org.trial.hiv.SMSService" ></service>
<receiver android:name="org.trial.hiv.BootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name="org.trial.hiv.BootUpService" ></service>
</application>
`
And my SMSReceiver.java, which starts a service to perform necessary housekeeping tasks on the message received...
public class SMSReceiver extends BroadcastReceiver
{
public void onReceive(final Context context, Intent intent)
{
Intent smsServiceIntent = new Intent(context, SMSService.class);
smsServiceIntent.setClass(context, SMSService.class);
Bundle bundle = intent.getExtras();
Object pdus[] = (Object[]) bundle.get("pdus");
SmsMessage smsMessage[] = new SmsMessage[pdus.length];
for (int n = 0; n<pdus.length; n++)`
{
smsMessage[n] = SmsMessage.createFromPdu((byte[]) pdus[n]);
}
String sender = smsMessage[0].getOriginatingAddress();
String body = smsMessage[0].getMessageBody();
if (sender.equalsIgnoreCase(activity.number))//incoming number is checked
{
this.abortBroadcast();
smsServiceIntent.putExtra("sender", sender);
smsServiceIntent.putExtra("body", body);
context.startService(smsServiceIntent);
}
}
}
I am using an smsService because I read that the BroadcastReceiver must not to any task for more than 10 seconds though I simply write the message to a SQLiteDatabase, I thought I still use a service.
Could someone point out where I am going wrong, or if I am missing out something critical. My requirement is to always receive all messages from a given number in my app, at any time.
After much debugging and understanding how BroadcastReceivers work in Android, I understand that the broadcast intent needs to be polled for, which I never did and hence the inconsistent behaviour... the following chage in code resolved my issue
do
{
bundle = intent.getExtras();
}
while (bundle == null);
in the onReceive() method of the BroadcastReceiver, and it resolved my issue. I could not find this documented anywhere, even in several SMS App tutorials.

Broadcast Receiver Not working in 4.1.1

I have a broadcast receiver for incoming call.I want to launch a new activity when an incoming call comes.I am aware of the changes that are made from android 3.0,that the broadcast receiver will not work unless user manually starts an application
For that purpose I launch a dummy activity with just a toast message in it.Still the broadcast receiver is not working.
Here is my code
My broadcastreceiver
public class IncomingCallResult extends BroadcastReceiver
{
String TAG="IncomingCallResult";
#Override
public void onReceive(Context arg0, Intent I1)
{
Log.i(TAG,"inside on receive........");
Bundle bundle=I1.getExtras();
String state=bundle.getString(TelephonyManager.EXTRA_STATE);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING))
{
Intent flash_intent=new Intent(arg0,LedFlasher.class);
flash_intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
arg0.startActivity(flash_intent);
}
}
}
manifest file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.blinker"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name=".IncomingCallResult"
android:enabled="true">
<intent-filter
android:priority="214783648"
android:name="android.intent.action.PHONE_STATE">
</intent-filter>
</receiver>
<activity
android:name=".LedFlasher"
android:label="#string/title_activity_incoming_call_result" >
</activity>
<activity
android:name=".Dummy">
<intent-filter >
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
What is wrong with the code?
Please help
As you have already known that the broadcast receiver will not work unless user manually starts an application For that purpose, you should not be surprised that your broadcast receiver will not work until user Manually open your application once. That is to say, you have to make a launcher activity which user is able to click and open it manually.
And what's more, it is better to Open and stay in your application for like 20s since I remember that the change of application configuration will take 10 or 20s to be saved.

Toast android phone with welcome greeting message when a wireless network is available

I am building an android app which once installed helps automating some of my home controls. As the first simple feature of the app, i want the phone to toast me with welcome message whenever i enter my home.
I thought i could implement this by putting in a BroadCastReceiver with action name "android.net.wifi.WIFI_STATE_CHANGED" and i assumed, whenever a new network is available, the broadcast receiver will be notified and i could check the SSID to see if i have arrived home.
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myfirstapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.myfirstapp.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="com.example.myfirstapp.WifiNetworksAvailableBroadcastReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
<activity
android:name="com.example.myfirstapp.WifiTester"
android:label="#string/title_activity_wifi_tester" >
</activity>
</application>
</manifest>
My WifiNetworksAvailableBroadcastReceiver looks like:
public class WifiNetworksAvailableBroadcastReceiver extends BroadcastReceiver {
protected static final String TAG = "MyApp";
#Override
public void onReceive(Context context, Intent intent) {
WifiManager mMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Log.i(TAG, "------");
for(final ScanResult result:mMgr.getScanResults()) {
if(result.SSID.equals("<MY_HOME_WIFI_SSID>")) {
Toast.makeText(context, "Welcome home", Toast.LENGTH_LONG).show();
}
}
Log.i(TAG, "======");
}
}
Now with the app installed. I enter my home but i do not get the toast. I tried running the app in the background but still i did not get the toast. Could anyone give an direction? Is my approach correct?
Try to change the receiver with the event SCAN_RESULTS_AVAILABLE_ACTION.
Your receiver will be called every time a new wifi scan has been done, then you can check if your SSID is present in the list of available ones calling getScanResults() and eventually show the toast.
PS.
Have you registered your receiver?

Categories

Resources