I have this program that will try to monitor incoming SMS messages. But when I tried to run my program in the emulator and I tried to send a SMS message, it works. But when I installed my program in my phone, its not working.
What is the problem?
And I want to run the program at the backend as well. How to do that?
BTW, below are the whole codes for this sample app.
Thanks
RJ
import java.io.BufferedWriter;
import java.io.FileWriter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
public class MySMSMonitor extends BroadcastReceiver
{
private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
#Override
public void onReceive(Context context, Intent intent)
{
if(intent!=null &&
intent.getAction()!=null &&
ACTION.compareToIgnoreCase(intent.getAction())==0)
{
Object[]pduArray= (Object[]) intent.getExtras().get("pdus");
SmsMessage[] messages = new SmsMessage[pduArray.length];
for (int i = 0; i<pduArray.length; i++) {
messages[i] = SmsMessage.createFromPdu ((byte[])pduArray [i]);
}
Log.d("MySMSMonitor","SMS Message Received.");
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="spy.Frandy.com"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="6" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".TelephonyDemo"
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=".MySMSMonitor"> <intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter>
</receiver>
</application>
</manifest>
import android.app.Activity;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class TelephonyDemo extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button sendBtn = (Button)findViewById(R.id.sendSmsBtn);
sendBtn.setOnClickListener(new OnClickListener(){
#Override public void onClick(View view) {
EditText addrTxt = (EditText)TelephonyDemo.this.findViewById(R.id.addrEditText);
EditText msgTxt = (EditText)TelephonyDemo.this.findViewById(R.id.msgEditText);
try {
sendSmsMessage(
addrTxt.getText().toString(),msgTxt.getText().toString());
Toast.makeText(TelephonyDemo.this, "SMS Sent",
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(TelephonyDemo.this, "Failed to send SMS", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}});
}
#Override
protected void onDestroy() {
super.onDestroy();
}
private void sendSmsMessage(String address,String message)throws Exception {
SmsManager smsMgr = SmsManager.getDefault();
smsMgr.sendTextMessage(address, null, message, null, null);
}
}
I would simply insist you to use ContentObserver and register content://sms Uri and fetch the type of the SMS using
cusor.getString(cusor.getColumnIndex("type")); // 1 = SMS Received
// 2 = SMS Sent
Further you can easily get the required data from the cursor that you fetched. Here is a blog for the same.
I'm going to assume with the little detail you have provided that the reason it works on a emulator and not your actual phone; may be another conflicting app intercepting the messages before they are broadcasted to your app.
try adding android:priority="1000" to your intent-filter of your receiver in your apps manifest
(a thousand being whatever number you feel necessary, could be higher if needed)
<intent-filter android:priority="1000" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
more info on - intent-filter priority
Try This:
<receiver android:name=".MySMSMonitor"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="2">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Related
I am trying to display toast on incoming call received. but i am not getting any display. I have mention the receiver inside the manifest file which also contains permission required for phone calls.
the following is code that i have used.
// inside IncomingCall broadcastreceiver
package com.example.shailesh.callbroadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
public class IncomingCall extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
// This code will execute when the phone has an incoming call
// get the phone number
String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Toast.makeText(context, "Call from:" +incomingNumber, Toast.LENGTH_LONG).show();
} else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_IDLE)
|| intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_OFFHOOK)) {
// This code will execute when the call is disconnected
Toast.makeText(context, "Detected call hangup event", Toast.LENGTH_LONG).show();
}
}
}
And i have specify in menifest file as follows :
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></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>
<receiver android:name=".IncomingCall" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
what else i have to include in order to get toast display on incoming call received.
i Have also included following code in my MainActivity
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent i = new Intent(getApplicationContext(),IncomingCall.class);
startService(i);
}
}
is class IncomingCall a service ? if not then why you are firing an intent to start service.
I am trying to write an app that would perform following operations:
once the user unlock the phone he has 10 seconds to scan an NFC tag in order to start camera app. and the NFC tag will have a mime type of
application/com.testformat.nfcdemo
To detect screen unlock, I used a broadcast receiver to detected User present.
And this works fine.
And I started a CountdownTimer inside the broadcast receiver for 10 seconds.
And the NFC detection part did not work, I could use some help here! thank you all!
My activity:
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
public class DisplayActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
}
}
Manifest xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.nfc"
android:versionCode="1"
android:versionName="1.0" >
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<uses-permission android:name="android.permission.NFC" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="19" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity
android:name=".DisplayActivity"
android:label="#string/activity_title" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".ScreenStateReceiver">
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/com.testformat.nfcdemo" />
</intent-filter>
</receiver>
</application>
</manifest>
Receiver:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.os.CountDownTimer;
import android.widget.Toast;
public class ScreenStateReceiver extends BroadcastReceiver {
private boolean countdown_end = false;
NfcAdapter mNfcAdapter;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
CharSequence text = context.getResources().getString(R.string.unlock_message);
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
startCountdown(10000);
if (intent.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
if (!countdown_end) {
text = context.getResources().getString(R.string.nfc_detected);
Toast nfc_toast = Toast.makeText(context, text, duration);
toast.show();
}
}else if ( intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)){
if (!countdown_end) {
text = context.getResources().getString(R.string.nfc_detected);
Toast nfc_toast = Toast.makeText(context, text, duration);
toast.show();
}
}
}
}
private void startCountdown(long milliseconds){
new CountDownTimer(milliseconds, 1000) {
#Override
public void onTick(long l) {
}
public void onFinish() {
countdown_end=true;
}
}.start();
}
}
can broadcast receiver handle ACTION_NDEF_DISCOVERED?
No. That is an activity action, used with startActivity(). It is not broadcast and therefore cannot be picked up by a BroadcastReceiver.
I am stuck for more than 6 hours, I have gone through every possible helpful post but no luck
The onReceive() method of BroadcastReceiver is not getting fired.
Below is the code of my MainAcitivty, Manifest and BroadCastReceiver.
This is code of my mainactivity
package com.example.luckydraw;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.SmsManager;
import android.util.Log;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
This is My broadcast reciever
package com.example.luckydraw;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class Smsrcv extends BroadcastReceiver {
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private static final String TAG = "Smsrcv";
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "I re", Toast.LENGTH_LONG).show();
Log.i(TAG, "Intent recieved: " + intent.getAction());
String message="test message";
String PhoneNumber="03214304743";
SmsManager.getDefault().sendTextMessage(PhoneNumber, null, message, null, null);
if (intent.getAction() == SMS_RECEIVED) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[])bundle.get("pdus");
final SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
}
if (messages.length > -1) {
Log.i(TAG, "Message recieved: " + messages[0].getMessageBody());
}
}
}
}
}
And finally this is my manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.luckydraw"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".Smsrcv"
android:enabled="true"
android:exported="true"
>
<intent-filter android:priority="1000" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
There are certain messaging applications e.g. GO SMS PRO etc which have broadcast recievers' intent fiters like
<intent-filter android:priority="2147483647" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
Here android:priority is 2147483647
This wasnt letting my app to catch System's broadcast !!
If you want to check all messaging applications' priorities on your device
use this
Intent intent = new Intent("android.provider.Telephony.SMS_RECEIVED");
List<ResolveInfo> infos = getPackageManager().queryBroadcastReceivers(intent, 0);
for (ResolveInfo info : infos) {
System.out.println("Receiver name:" + info.activityInfo.name + "; priority=" + info.priority);
}
SOLUTION
You should uninstall those with priority > 1000, to make your app work..
Here I am trying to read the message and toast it I have seen various examples where there is a separate class that extends BroadcastReceiver but they have not mentioned how to start this class(do we use startactivity() or somthing else). I have posted the code that I dowladed through a link from O'Reilly's cookbook. I've tried to sms from ddms but it doesn't show toast of message. Any help is appreciated as this is my first time with BroadcastReceiver.
invitationSMSreciever.java
package com.SMS;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.sax.StartElementListener;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class invitationSMSreciever extends BroadcastReceiver {
final String TAG = "BombDefusalApp";
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String message = "";
if (bundle != null) {
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]);
message = msgs[i].getMessageBody();
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
if (msgs[i].getMessageBody().equalsIgnoreCase("Invite")) {
// Intent myIntent = new Intent(MainMenu.this,
// com.bombdefusal.ReceivedSMSActivity.class);
Intent myIntent = new Intent();
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
myIntent.setAction("com.example.helloandroid.INVITE");
context.startActivity(myIntent);
}
}
}
}
}
MainMenu
package com.SMS;
import com.SMS.R;
import android.app.Activity;
import android.os.Bundle;
public class MainMenu extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
ReceivedSMSActivity
package com.SMS;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import com.SMS.R;
public class ReceivedSMSActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent ("com.android.PLAY"));
setContentView(R.layout.invite);
}
public boolean onKeyDown(int keyCode, KeyEvent service) {
stopService(new Intent("com.bombdefusal.START_AUDIO_SERVICE"));
finish();
return true;
}
}
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.SMS" android:versionCode="1" android:versionName="1.0">
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainMenu" android:label="#string/app_name">
<intent-filter>
<action android:name="com.SMS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.SMS.ReceivedSMSActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="com.example.helloandroid.INVITE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<receiver android:name="com.SMS.invitationSMSreciever"
android:enabled="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
</application>
</manifest>
You have two options to do this:
Register you broadcast receiver statically in the AndroidManifest file. Thus, it will be called automatically.
Register you broadcast receiver dynamically in your code using registerReceiver() method. In this case, this method should be paired with unregisterReceiver() where you unregister your receiver.
Usually, if broadcast receiver is implemented as a separate class then it usually registered statically in AndroidManifest file. I guess in you case you should just add the following lines to your file:
<receiver android:name=".invitationSMSreciever" android:exported="true" >
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
So in my Android app, I've been testing how to detect an incoming and outgoing call. I got it to work by building a class that extends a BroadcastReceiver, but in that class if I call another class it crashes. For example MyClass mc = new MyClass(); mc.functionname();
My actual app is running a looping sound clip. I want to pause that sound clip when an incoming or outgoing call is made. The soundclip is played in a class that extends Activity. How do I do this?
This is what I have for the BroadcastReceiver class and my manifest.
package com.anthony.phone;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
public class inComingReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Bundle bundle = intent.getExtras();
if(null == bundle)
return;
Log.i("MYTAG",bundle.toString());
String state = bundle.getString(TelephonyManager.EXTRA_STATE);
Log.i("MYTAG","State: "+ state);
if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING))
{
String phonenumber = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.i("MYTAG",":) Incomng Number: " + phonenumber);
String info = "Detect Calls sample application\nIncoming number: " + phonenumber;
Toast.makeText(context, info, Toast.LENGTH_LONG).show();
}
}
}
and my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.anthony.phone"
android:versionCode="1"
android:versionName="1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".CallTActivity"
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.anthony.phone.inComingReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
</application>
</manifest>
i had also this kind of problem. i solved by calling activity from broadcast receiver And writing my class code in particular Activity. As mentioned below
Intent i = new Intent(context,newActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
i hope it will help you to solve your query.
ask me if you further have any doubt.