I would like to retrieve the incoming call's phonenumber and do something with it like the do
in http://blog.whitepages.com/2009/02/27/caller-id-by-whitepages-a-new-android-app-that-puts-telemarketers-on-alert/
Could you please help me because I can't find any information about this.
Where do i start and how do i get hold of the phonenumber?
Ok so currently my code looks like below. When I place the call the CustomBroadcastReceiver catches it and the log message is printed out. I can retrieve the telephone number from the bundle. But! I can't get hte CustomPhoneStateListener to work. As you can see I have registered my customPhoneState listener to the receiver but the log message never get's printed out from the CustomPhoneStateListener class. What am I my missing here?
Is my thinking correct?
<receiver android:name=".CustomBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="5" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
public class CustomPhoneStateListener extends PhoneStateListener {
private static final String TAG = "CustomPhoneStateListener";
public void onCallStateChange(int state, String incomingNumber){
Log.v(TAG, "WE ARE INSIDE!!!!!!!!!!!");
Log.v(TAG, incomingNumber);
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "RINGING");
break;
}
}
public class CustomBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "CustomBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "WE ARE INSIDE!!!!!!!!!!!");
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
Bundle bundle = intent.getExtras();
String phoneNr= bundle.getString("incoming_number");
Log.v(TAG, "phoneNr: "+phoneNr);
}
Use PhoneStateListener. It has an onCallStateChanged handler; one of the supplied arguments you'll get is a String containing the incoming phone number.
Your overridden method in CustomPhoneStateListener should be called onCallStateChanged() (and not onCallStateChange()).
This would have been spotted by the Java compiler if you would have had the #Override annotation, like you have for onReceive().
The above answers are out-od-dated now. There are valid for Android 7 and lower.
For android 9 and higher you have to add another permission in the Androidmanifest.xml with the permission
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
without the phone number will be null. For Android 8 I am not sure.
PhoneStateReciever.java
package com.incomingcalls;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
public class PhoneStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
System.out.println("Receiver start");
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.e("Incoming Number", "Number is ," + incomingNumber);
Log.e("State", "State is ," + state);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
Toast.makeText(context,"Incoming Call State",Toast.LENGTH_SHORT).show();
Toast.makeText(context,"Ringing State Number is -"+incomingNumber,Toast.LENGTH_SHORT).show();
}
if ((state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))){
Toast.makeText(context,"Call Received State",Toast.LENGTH_SHORT).show();
}
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
Toast.makeText(context,"Call Idle State",Toast.LENGTH_SHORT).show();
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
AnroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.incomingcalls">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<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"
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=".PhoneStateReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
</manifest>
Related
I am working on an app that will use a BroadcastReceiver to pick up certain SMS messages that meet certain criteria. It's a long way short of finished, mainly because it seems that the BroadcastReceiver isn't working. I've tried to use a toast to check if it's working but I get no result. So either:
The BroadcastReceiver is not working
My method of testing is wrong
Or both
The AndroidManifest.xml file is
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.alert6">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_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/Theme.Alert6">
<activity
android:name=".SendResponseActivity"
android:parentActivityName=".ReceiveAlertActivity">
</activity>
<activity
android:name=".ReceiveAlertActivity"
android:parentActivityName=".MainActivity">
</activity>
<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=".SmsBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="999" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
And this is the SmsBroadcastReceiver java file
package com.example.alert6;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.provider.Telephony;
import android.telephony.SmsMessage;
import android.widget.Toast;
public class SmsBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"SMS Is Being Received",Toast.LENGTH_LONG).show();
if (intent.getAction().equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
String smsSender = "";
String smsBody = "";
for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
smsSender = smsMessage.getOriginatingAddress();
smsBody = smsMessage.getMessageBody();
}
if (smsSender.equals("+420775367297")) {
if (smsBody.contains("Test")) {
// I haven't done this bit yet
}
}
}
}
}
When I send a SMS to the test device I would expect a toast message saying "SMS Is Being Received". Instead the app disappears from the screen and my default SMS app appears instead. What am I doing wrong?
Since Android API 23 you need set permission not only in manifest class, but also set permisson manually. You should set it in app's settings, or you should make permission reqeust from your code. This is what you need add in your main activity's file:
// constant for request code
private final int MY_PERMISSIONS_REQUEST_SMS_RECEIVE = 10; // any number which you want
//function for permission request
#RequiresApi(api = Build.VERSION_CODES.M)
public void checkPermission() {
if ((ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED)) {
requestPermissions(new String[]{Manifest.permission.RECEIVE_SMS}, MY_PERMISSIONS_REQUEST_SMS_RECEIVE);
}
}
Also you need call this function somewhere. For example you can make it in onCreate().
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkPermission();
}
//do something else
}
After a huge amount of fiddling and testing, I came to the conclusion that the broadcast receiver is not working. Probably due to Android's limitations on "dangerous" permissions. I don't think this thread has any life left in it, but I will continue to try to persuade my Android app to work with the necessary permissions.
I want to implement getting incoming call events in background and foreground. So I've created BroadcastReceiver for that purpose, but onReceive() method doesn't fired after I got/getting/finished incoming call.
I've tryed tons of tutorial, but nothing helped me:(
Please help.
MANIFEST
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="yakiv.bondar.dev.incomeoutcomecalltest">
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<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>
Broadcast receiver
public class IncomingCall extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("tag", "AAAAAAAAAAAAAAAAAAAAAA");
MyPhoneStateListener phoneListener=new MyPhoneStateListener();
TelephonyManager telephony = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
public class MyPhoneStateListener extends PhoneStateListener {
public void onCallStateChanged(int state,String incomingNumber){
switch(state){
case TelephonyManager.CALL_STATE_IDLE:
Log.d("tag", "IDLE");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("tag", "OFFHOOK");
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d("tag", "RINGING");
break;
}
}
}
}
Main Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
You have missed calling registerReciever(intent,intentFilter) in your Activity. Register your activity in onResume() and call unregisterReciever(intent) in your onPause() method.
NOTE:
Also check if you have given appropriate permissions in your manifest and also note that even if you have declared your required permissions you have to handle certain permissions in runtime in Android 6.0 and above. Check here for handling permissions at runtime for Marshmallow and above.
In MainActivity:
IncomingCall mBroadcastReceiver = new IncomingCall();
In onResume:
IntentFilter filter = new IntentFilter();
this.registerReceiver(mBroadcastReceiver , filter);
In onPause:
this.unregisterReceiver(mBroadcastReceiver );
1) Make sure your app has the permissions to READ_PHONE_STATE
2) you do not need to registerReceiver( BroadcastReceiver, IntentFilter) since you have it in your Manifest
3)MAke sure the notification are turned on for your App (Check Settings--> Application Manager --> your app --> Notifications)
4) I would try testing without "break" in the switch statements
5) try with Toast instead of Log. Toast.makeText( Context, String , Toast.LENGTH_SHORT).show();
Everyboday. I am trying to log some information such as phonenumber, calling time and so on during calling state in android. I was tried to build with some codes following as below:
package com.test.dialuplog;
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 IncomingBroadcastReceiver extends BroadcastReceiver {
String mPhoneNumber;
public static IncomingBroadcastReceiver pThis;
#Override
public void onReceive(Context context, Intent intent) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(new CustomPhoneStateListener(context), PhoneStateListener.LISTEN_CALL_STATE);
}
public class CustomPhoneStateListener extends PhoneStateListener {
//private static final String TAG = "PhoneStateChanged";
Context context; //Context to make Toast if required
public CustomPhoneStateListener(Context context) {
super();
this.context = context;
}
#Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
//when Idle i.e no call
Toast.makeText(context, "Phone state Idle", Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//when Off hook i.e in call
//Make intent and start your service here
Toast.makeText(context, "Phone state Off hook", Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_RINGING:
//when Ringing
Toast.makeText(context, "Phone state Ringing", Toast.LENGTH_LONG).show();
break;
default:
break;
}
}
}
}
And also I wrote some codes in AndroidManifest.xml like this:
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen">
<receiver android:name=".IncomingBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
<activity
android:name=".SplashActivity"
android:configChanges="orientation"
android:screenOrientation="portrait"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
After coded, I called to my phone with different one.
But nothing happened, This codes are followed from open source, but nothing happened. Are there anybody who has already experienced? If it is, Please teach me what I wrong. Thank you.
I am trying to detect Incoming call using Broadcast Listener.Since I received one fault in my app when someone calls, my app still plays the song. So I want to pause song during Incoming Call. But I am not receiving any response.
Here is the complete code So that you all can understand where am I messing.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<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">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
IncomingCall.java
package com.example.suraj.freewee;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
public class IncomingCall extends BroadcastReceiver {
private String LOG_TAG = getClass().getSimpleName();
TelephonyManager telephonyManager;
Context context;
#Override
public void onReceive(Context context, Intent intent) {
try {
this.context = context;
telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
MyPhoneStateListener phoneListener = new MyPhoneStateListener();
telephonyManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
Log.e(LOG_TAG, "inside on receive");
} catch (Exception e) {
e.printStackTrace();
Log.e(LOG_TAG, e.toString());
}
}
private class MyPhoneStateListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
Log.e(LOG_TAG, "Number : " + incomingNumber);
try {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING: {
//PAUSE
SongsAdapter.player.pause();
Log.e(getClass().getSimpleName(), "call ringing");
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {
SongsAdapter.player.pause();
Log.e(getClass().getSimpleName(), "call offhook");
break;
}
case TelephonyManager.CALL_STATE_IDLE: {
//PLAY
SongsAdapter.player.start();
Log.e(getClass().getSimpleName(), "call idle");
break;
}
default: {
}
}
} catch (Exception ex) {
Log.e(getClass().getSimpleName(), "Error: " + ex.toString());
}
}
}
}
In logcat no log errors are shown
So why is this giving me such behaviour. thanks in advance
You're registering listener inside onReceive. That's pointless. As
Android documentation states:
A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this function, the system considers the object to be finished and no longer active.
It should be enough to get EXTRA_STATE from Intent in onReceive and do your switch there.
If you're still not getting anything logged trim it to minimal case - leave only Log statement inside onReceive. Does it work? AFAIK there are two cases when app won't receive broadcast - If it was never started or if it was force stopped.
try editing onReceive() as below
public void onReceive(Context context, Intent intent)
{
TelephonyManager phoneManager =
(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(phoneManager.getCallState() == TelephonyManager.CALL_STATE_RINGING)
{
string fromNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.i(TAG, "u have a call from a number " + fromNumber);
}
}
Now call to ur number and see the number in logs
I want to get call details(mobile number, call duration, date, time etc) of dialed mobile no after disconnecting call.
What I did so far:
I create a Broadcast Receiver to detect the call disconnect event. After getting call details I fetch the latest dialed no from call log and store in SQLite database.
What the problem is:
When I dial any no from device and disconnect that, onReceive() method called twice. Same record is inserted twice. I have checked it by printing Logs also.
I searched this issue on Google and got some solution like " use sendBroadcast() only once, register broadcast receiver only once etc". But I am not calling sendBroadcast()anywhere, neither I am registering it twice.
I am new to Android so please suggest what am I doing wrong?
Broadcast Receiver:
public class CallReceiver extends BroadcastReceiver {
ContentResolver contentResolver;
Context context;
boolean is_network_roaming = false;
TelephonyManager tm = null;
AppInfo appInfo = null;
ContactHelper contactHelper;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String TAG = getClass().getSimpleName();
this.context = context;
tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
appInfo = new AppInfo(context);
contactHelper = new ContactHelper(context);
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
is_network_roaming = tm.isNetworkRoaming();
/* Method for getting call details from call log */
getAllCallLogs();
}
}
Manifest File:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.callduration"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_logo"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.callduration.Splash"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.NoTitleBar"
android:windowSoftInputMode="adjustPan|adjustResize|stateHidden" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.callduration.MainActivity" >
</activity>
<activity android:name="com.callduration.CallHistory" >
</activity>
<receiver android:name="com.callduration.receivers.CallReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
</manifest>
The sequence of state changes when dialing a call is:
CALL_STATE_OFFHOOK--->ACTION_NEW_OUTGOING_CALL-->...{call answered or not
answered}.........--> CALL_STATE_OFFHOOK-->CALL_STATE_IDLE
As per the above states, your onReceive is supposed to start twice, once when call is initiated and second when call is disconnected. To achieve what you need i.e you want to log the events of a single call session. You can use the below code,
int state=intent.getStringExtra(TelephonyManager.EXTRA_STATE)
Boolean singlecallstate=false;
switch (state) {
case TelephonyManager.ACTION_NEW_OUTGOING_CALL:
singlecallstate=true;
//any other code you want
case TelephonyManager.CALL_STATE_IDLE:
if(singlecallstate){
getAllCallLogs();
singlecallstate=false;
}