TelephonyManager
which gave us information about the telephony services. This class provides various methods to access the telephony states and services. Now let’s see how to use telephony manager to know the incoming call states. Applications need to register a listener to receive notification on call states.Initializing a TelephonyManager object
TelephonyManager
instance needs to be instantiated through call getSystemService(Context.TELEPHONY_SERVICE)
. getSystemService()
method returns handle to system level service, by which we get access for handling telephony features of the device
(here is TELEPHONY_SERVICE
):
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
In order to listen call states changed, we must use PhoneStateListener
and overriding onCallStateChanged()
method.There are 3 phone call states that declared in
TelephonyManager
:CALL_STATE_IDLE
: No phone call exists or a phone call has just finished.CALL_STATE_OFFHOOK
:At least one call exists that is dialing, active, or on hold, and no calls are ringing or waiting.CALL_STATE_RINGING
: A new call arrived and is ringing or waiting. In the latter case, another call is already active.
TelephonyManager
with PhoneStateListener
through call:
telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
Full Service code
Service
, so the application can still work in background.
PhoneCallStatesService.java
package info.devexchanges.phonecallstates;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;
public class PhoneCallStatesService extends Service {
private TelephonyManager telephonyManager;
private PhoneStateListener listener;
private boolean isOnCall;
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
isOnCall = false;
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Create a new PhoneStateListener
listener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
if (isOnCall) {
showToast("Call state: idle");
isOnCall = false;
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
showToast("Call state: offhook");
isOnCall = true;
break;
case TelephonyManager.CALL_STATE_RINGING:
showToast("call state: ringing");
break;
}
}
};
// Register the listener with the telephony manager
telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
return 1;
}
private void showToast(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy() {
}
}
Designing a simple Activity
activity_main.xml
Start and stop our service when clicking corresponding button in Java code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="info.devexchanges.phonecallstates.MainActivity">
<Button
android:id="@+id/btn_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Start Service" />
<Button
android:id="@+id/btn_stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/btn_start"
android:text="Stop Service" />
</RelativeLayout>
MainActivity.java
package info.devexchanges.phonecallstates;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View btnStart = findViewById(R.id.btn_start);
View btnStop = findViewById(R.id.btn_stop);
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, PhoneCallStatesService.class);
startService(i);
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
stopService(new Intent(MainActivity.this, PhoneCallStatesService.class));
}
});
}
}
Adding permission in AndroidManifest
READ_PHONE_STATE
permission and declaring your Service
class in AndroidManifest.xml
:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.devexchanges.phonecallstates">
<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>
<service android:name=".PhoneCallStatesService" />
</application>
</manifest>
Running application
On phoning:
When the call finished:
Conclusions
TelephonyManager
document to deep understanding the telephony service - the main feature of Android phone. Finally, you can get full project code from @Github.