I don't know where is a problem.
Listener doesn't catch onRinging event (so I can decide will I accept or reject incoming calls).
in manifest is this:
<uses-permission android:name="android.permission.USE_SIP" />
in main activity onCreate is this:
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
...
SipManager manager = SipManager.newInstance(this);
Intent i = new Intent();
i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);
in BroadcastReceiver class is this:
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
...
#Override
public void onCallEnded(SipAudioCall call) {
// TODO Auto-generated method stub
super.onCallEnded(call);
}
#Override
public void onRinging(SipAudioCall call, SipProfile caller) {
try {
call.answerCall(30);
call.startAudio();
call.setSpeakerMode(true);
if(call.isMuted()) {
call.toggleMute();
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;
incomingCall = wtActivity.manager.takeAudioCall(intent, listener);
wtActivity.call = incomingCall;
...
I recieve CallEnd event and onChanged (after I end call) but I dont recieve onRinging event.
what could be a problem?
Thnx
EDIT :
I changed it all.
I put new intent filter to receiver like this (bold):
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver">
**<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>**
</receiver>
and I changed BroadcastReceiver inherit class like this (bold one):
#Override
public void onReceive(Context context, Intent intent) {
try {
**PhoneStateListener phoneListener=new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
// TODO Auto-generated method stub
Log.d("DEBUG", "Phone listener....");
String stateString = "N/A";
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
stateString = "Idle";
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
stateString = "Off Hook";
break;
case TelephonyManager.CALL_STATE_RINGING:
stateString = "Ringing";
break;
}
}
};**
WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;
SipSession ses=wtActivity.manager.getSessionFor(intent);
**TelephonyManager telephony = (TelephonyManager) Context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener,PhoneStateListener.LISTEN_CALL_STATE);**
...
Now I get only IDLE state but still there is no ringing.
There is an error in the source code of SipAudioCall class.
To work around this issue:
incomingCall = wtActivity.manager.takeAudioCall(intent, null);
incomingCall.setListener(listener, true);
I have implemented same scenario to accept or reject incoming call in sip demo.
Create your own Activity (IncomingGui.java) with two buttons Accept and Reject.
In BroadcastReciever class call your Activity(IncomingGui.java) on incoming call event.
WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;
incomingCall = wtActivity.manager.takeAudioCall(intent, listener);
showIncomingCallGui(intent, context);
wtActivity.call = incomingCall;
Then define following methods in BroadcastReciever class
public void showIncomingCallGui(Intent intent,Context context) {
Intent incomingCall=new Intent(context,IncomingCallGui.class);
context.startActivity(incomingCall);
}
public static void answerIncomingCall(){
try {
incomingCall.answerCall(30);
incomingCall.startAudio();
incomingCall.setSpeakerMode(true);
if (incomingCall.isMuted()) {
incomingCall.toggleMute();
}
}
catch(Exception e){
System.out.println(e.toString());
}
}
public static void rejectIncomingCall(){
try {
if (incomingCall !=null) {
incomingCall.endCall();
incomingCall.close();
}
}
catch(Exception e){
System.out.println(e.toString());
}
Then in IncomingGui.java define following methods behind "Accept" and "Reject" Buttons.
Now on incoming call you will have your own incoming call activity to accept or reject call.
public void onCallAcceptButton(View view){
IncomingCallReceiver.answerIncomingCall();
}
public void onCallRejectButton(View view){
IncomingCallReceiver.rejectIncomingCall();
this.finish();
}
Related
I have developed an Android app for recording audio when the phone called. I know, I can't record the audio of the caller person but I want to record my voice when I answered the phone or start a call with another person. I can do this on some devices but on some devices when my phone starts to ringing, the voice is recorded but after I answered the phone, I can't record any voice. Or my voice is recorded when I start to call to person but after the person answered me, recording voice is stopped!
I use the below code:
private void startRecord(){
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);*/
mRecorder.setOutputFile(savePath);
}
BroadCastReceiver:
private final PhoneStateListener phoneListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
//Toast.makeText(context,"phoneListener Start",Toast.LENGTH_LONG).show();
try {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING: {
startedCall = true;
//Toast.makeText(context,"CALL_STATE_RINGING",Toast.LENGTH_LONG).show();
if (incomingNumber != null) {
//incoming call
//Toast.makeText(context,"Go to start forground service->ringing",Toast.LENGTH_LONG).show();
startForegroundService(incomingNumber);
}
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {
//Toast.makeText(context,"CALL_STATE_OFFHOOK",Toast.LENGTH_LONG).show();
startedCall = true; // Newly added code
if (incomingNumber != null) {
//Toast.makeText(context,"Go to start forground service->OffHook",Toast.LENGTH_LONG).show();
//outgoing call
startForegroundService(incomingNumber);
}
break;
}
case TelephonyManager.CALL_STATE_IDLE: {
//Toast.makeText(context,"CALL_STATE_IDLE",Toast.LENGTH_LONG).show();
if (startedCall) {
stopForegroundService();
}
break;
}
default: {
}
}
} catch (Exception ex) {
}
}
};
You have to use the AccessibilityService in Android 10 and above.
MainActivity code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 29) {
if (!isAccessibilityServiceEnabled()) {
startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
}
}
}
private boolean isAccessibilityServiceEnabled() {
int accessibilityEnabled = 0;
final String service = getPackageName() + "/" + RecordingAccessibilityService.class.getCanonicalName();
try {
accessibilityEnabled = Settings.Secure.getInt(getApplicationContext().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
} catch (Settings.SettingNotFoundException e) {
}
TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');
if (accessibilityEnabled == 1) {
String settingValue = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (settingValue != null) {
mStringColonSplitter.setString(settingValue);
while (mStringColonSplitter.hasNext()) {
String accessibilityService = mStringColonSplitter.next();
if (accessibilityService.equalsIgnoreCase(service)) {
return true;
}
}
}
}
return false;
}
AccessibilityService code:
public class RecordingAccessibilityService extends AccessibilityService {
#Override
protected void onServiceConnected() {
instance = this;
super.onServiceConnected();
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
PhoneStateListener phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
Toast.makeText(getApplicationContext(), "onServiceConnected", Toast.LENGTH_SHORT).show();
updateNotification();
startRecord();
}
if (state == TelephonyManager.CALL_STATE_IDLE) {
stopRecord();
}
super.onCallStateChanged(state, incomingNumber);
}
};
if (mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
}
Manifest Code:
<service
android:name=".RecordingAccessibilityService"
android:exported="false"
android:label="#string/accessibility_description"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/accessibility_service_config" />
</service>
accessibility service config code:
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowContentChanged|typeWindowStateChanged"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagReportViewIds|flagRetrieveInteractiveWindows"
android:canRetrieveWindowContent="true"
android:description="#string/accessibility_description"
android:label="#string/app_name"
android:notificationTimeout="100" />
also must use BroadcastReceiver:
public class CallBroadcastReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
String numberToCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
// Log.d("CallRecorder", "CallBroadcastReceiver intent has EXTRA_PHONE_NUMBER: " + numberToCall);
}
PhoneListener phoneListener = new PhoneListener(context);
TelephonyManager telephony = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
documentation:
https://developer.android.com/reference/android/accessibilityservice/AccessibilityService
I am working on fetching recent call log as call get disconnected(outgoing , incoming) either answered or unanswered.
I am using Phone state listener to fire broadcast when call get disconnected but it getting fired multiple time for one call why so..??
So Please tell me how to fire receiver only once for one call.
here is my code
public class BroadcastReceiver extends android.content.BroadcastReceiver{
static boolean iscallended= true;
Context mContext;
TelephonyManager telephony;
private static final String TAG = "CustomBroadcastReceiver";
CustomPhoneStateListener customPhoneStateListener;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
mContext = context;
Bundle extras = intent.getExtras();
if (extras != null) {
String state = extras.getString(TelephonyManager.EXTRA_STATE);
Log.w("DEBUG", state);
telephony = (TelephonyManager)context.getSystemService(context.TELEPHONY_SERVICE);
if(customPhoneStateListener==null)
{
customPhoneStateListener = new CustomPhoneStateListener();
telephony.listen(customPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
}
private class CustomPhoneStateListener extends PhoneStateListener
{
private static final String TAG = "CustomPhoneStateListener";
Handler handler=new Handler();
#Override
public void onCallStateChanged(int state, String incomingNumber) {
// TODO Auto-generated method stub
System.out.println(iscallended+ " value of iscancelled ");
switch (state)
{
case TelephonyManager.CALL_STATE_RINGING:
if(!incomingNumber.equalsIgnoreCase(""))
{
//YOUR CODE HERE
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if(iscallended)
{
iscallended = false;
System.out.println("IDLE called");
Toast.makeText(mContext, "IDLE", Toast.LENGTH_SHORT).show();
Intent it = new Intent(mContext,MainActivity.class);
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(it);
}
break;
default:
break;
}
super.onCallStateChanged(state, incomingNumber);
telephony.listen(customPhoneStateListener, PhoneStateListener.LISTEN_NONE);
}
}
}
Here's receiver in manifest
<receiver android:name="com.example.calllogs.BroadcastReceiver">
<intent-filter >
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
Here is your answer :
https://stackoverflow.com/a/5497316/3479012
also specify permission in your manifest to access phone state.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
also have a look at this
http://karanbalkar.com/2014/02/detect-incoming-call-and-call-hangup-event-in-android/
Yes you will get that.
private class MyPhoneStateListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
//Hangup
case TelephonyManager.CALL_STATE_IDLE:
Log.d("IDLE", "Call Idle" + state);
if (isCallEnded) {
isCallEnded = false;
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity());
.setCancelable(false)
.setPositiveButton(getString(R.string.Yes), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// your method
}
})
.setNegativeButton(getString(R.string.No), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alertBuilder.show();
}
break;
//Outgoing
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("OFFHOOK", "Call OffHook" + state);
isCallEnded = true;
break;
//Incoming
case TelephonyManager.CALL_STATE_RINGING:
Log.d("RINGING", "Call Ringing" + state);
break;
}
}
}
The above is sample, when you look at the device log you'll definitely see offhook multiple times as well as IDLE state.
Try to calculate that, it should be okay.
To avoid repetitive triggering, use MyPhoneStateListener as object and check lastCallState. Call makeMyPhoneStateListener from ServiceReceiver.
class MyPhoneStateListener () : PhoneStateListener() {
companion object {
var lastCallState: Int? = null
lateinit var context: Context
fun makeMyPhoneStateListener(_context: Context): MyPhoneStateListener
{
val myPhoneStateListener = MyPhoneStateListener()
context = _context
return myPhoneStateListener
}
}
override fun onCallStateChanged(state: Int, incomingNumber: String) {
when (state) {
TelephonyManager.CALL_STATE_IDLE -> {
if (lastCallState!= TelephonyManager.CALL_STATE_IDLE){
// some code for CALL_STATE_IDLE
lastCallState = TelephonyManager.CALL_STATE_IDLE
}
}
TelephonyManager.CALL_STATE_OFFHOOK -> {
if (lastCallState!= TelephonyManager.CALL_STATE_OFFHOOK) {
// some code for CALL_STATE_OFFHOOK
lastCallState = TelephonyManager.CALL_STATE_OFFHOOK
}
}
TelephonyManager.CALL_STATE_RINGING -> {
if (lastCallState!= TelephonyManager.CALL_STATE_RINGING) {
// some code for CALL_STATE_RINGING
lastCallState = TelephonyManager.CALL_STATE_RINGING
}
}
}
}
I have overcame this problem using this simple trick
In your receiver class
public class Receiver extends BroadcastReceiver {
public static final String TAG = "MADARA";
private static boolean callAnswered = false;
private static boolean callRinging = false;
private static boolean callEnded = false;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.PHONE_STATE")){
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (!callAnswered){
Log.d(TAG, "Call answered");
callAnswered = true;
new Handler(Looper.getMainLooper()).postDelayed(() -> callAnswered = false, 2000);
}
}
else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE)) {
if (!callEnded){
Log.d(TAG, "Call ended");
callEnded = true;
new Handler(Looper.getMainLooper()).postDelayed(() -> callEnded = false, 2000);
}
}
else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
if (!callRinging){
Log.d(TAG, "Call Ringing");
callRinging = true;
new Handler(Looper.getMainLooper()).postDelayed(() -> callRinging = false, 2000);
}
}
}
}
}
you will find the below description in Android Devlopers documnetation here
Broadcast intent action indicating that the call state on the device
has changed.
The EXTRA_STATE extra indicates the new call state. If a receiving app
has Manifest.permission.READ_CALL_LOG permission, a second extra
EXTRA_INCOMING_NUMBER provides the phone number for incoming and
outgoing calls as a String.
If the receiving app has Manifest.permission.READ_CALL_LOG and
Manifest.permission.READ_PHONE_STATE permission, it will receive the
broadcast twice; one with the EXTRA_INCOMING_NUMBER populated with the
phone number, and another with it blank. Due to the nature of
broadcasts, you cannot assume the order in which these broadcasts will
arrive, however you are guaranteed to receive two in this case. Apps
which are interested in the EXTRA_INCOMING_NUMBER can ignore the
broadcasts where EXTRA_INCOMING_NUMBER is not present in the extras
(e.g. where Intent#hasExtra(String) returns false).
Now listener fired twice one for call log permission and the other for phone state permission, only one of them will return with phone number and the other will be Null.
So, you should first check if phone number returen empty or not like this
String stateString = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String savedNumber = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Now You should first check if savedNumber is null or not
Here is full onReceive method
private static String savedNumber;
int state;
Context ctx;
#Override
public void onReceive(Context context, #NonNull Intent intent) {
Log.d("TAG101", "onReceive: " + intent.getAction().toString());
ctx = context;
state = -1;
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
} else {
String stateString = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
savedNumber = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
if(savedNumber != null) {
if (stateString.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
state = TelephonyManager.CALL_STATE_OFFHOOK;
} else if (stateString.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
state = TelephonyManager.CALL_STATE_IDLE;
if (state == 0) {
onCallEnded();
}
} else if (stateString.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
state = TelephonyManager.CALL_STATE_RINGING;
}
}
}
}
I am working on a app that runs in the background and listens to incoming calls.
For this I have created a service which calls TelephonyManager.listen in the onHandleIntent method.
Unfortunately although the constructor of the phonestatelistener is invoked, its onPhoneStateChanged method is not getting invoked.
Making the same call from a activity works fine. I am confused what the issue might be. I have searched many similar posts but none of them have answered my question satisfactorily. Hence I am posting this question.
Following is my service and phonelistener implementation:
public class PhoneListenersService extends IntentService{
TelephonyManager tm;
CallStateListener callstatelistener;
public PhoneListenersService() {
super("PhoneListenersService");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
int count=0;
do
{
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
TelephonyMgr.listen(new TeleListener(), PhoneStateListener.LISTEN_CALL_STATE);
Log.d("Count", ""+count++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
while(count<100);
}
class TeleListener extends PhoneStateListener {
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
// CALL_STATE_IDLE;
Toast.makeText(getApplicationContext(), "CALL_STATE_IDLE",
Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// CALL_STATE_OFFHOOK;
Toast.makeText(getApplicationContext(), "CALL_STATE_OFFHOOK",
Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_RINGING:
// CALL_STATE_RINGING
Toast.makeText(getApplicationContext(), incomingNumber,
Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), "CALL_STATE_RINGING",
Toast.LENGTH_LONG).show();
break;
default:
break;
}
}
}
}
Please help me.
Thanks!
Left with no option, I have changed my approach. I use Broadcast Receiver with Intent Service to listen for incoming calls. Following is the code if it helps someone:-
public class PhoneListenersService extends IntentService{
TelephonyManager tm;
BroadcastReceiver receiver;
IntentFilter filter;
public PhoneListenersService() {
super("PhoneListenersService");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
//Intent
Filter filter=new IntentFilter();
filter.addAction("android.intent.action.PHONE_STATE");
//Create instance of BroadcastReceiver
receiver=new BroadcastReceiver()
{
#Override
public void onReceive(Context arg0, Intent intent) {
// TODO Auto-generated method stub
Bundle bundle = intent.getExtras();
if (bundle == null)
return;
// Incoming call
String state =
bundle.getString(TelephonyManager.EXTRA_STATE);
if ((state != null) &&
(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)))
{
phoneNumber =
bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
//if phoneNumber is not blank get location details
if(!phoneNumber.isEmpty())
{
//Do work here
}
}
}
};
registerReceiver(receiver, filter);
} }
Regards.
I am trying to display an alert in a specific Activity when the charging status changes.
this is my receiver class:
public class BatteryChargeReceiver extends BroadcastReceiver {
private String TAG = "receiver";
private ChargeReceiverCallback callback;
public BatteryChargeReceiver(ChargeReceiverCallback callback) {
this.callback =callback;
Log.v(TAG,"Inside Constructor (Callback)");
}
public interface ChargeReceiverCallback {
public void onReceive(Intent intent);
}
#Override
public void onReceive(Context context, Intent intent) {
callback.onReceive(intent);
}
}
And below is how I instantiate it from my MainActivity's onResume. MainActivity implements my interface and overrides onReceive(intent). I found out that at no stage does intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1) return anything else then -1.
BatteryChargeReceiver batteryReceiver = new BatteryChargeReceiver(this);
IntentFilter filterPower = new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED");
registerReceiver(batteryReceiver, filterPower);
Intent.ACTION_POWER_CONNECTED not delivering current plugged-in state - this is probably a change in how API works, but I could not locate any mention of such change in docs.
The broadcast Intent.ACTION_POWER_CONNECTED was never meant to receive current plugged-in type, but it merely lets the receiving end of power connection (ref.). In fact, BatteryService.java broadcasts plain intent without any extra values (lines 410~412 as of this writing):
Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
However, following code with
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
worked on Nexus 5:
public class MainActivity extends Activity {
private static final String TAG = "PowerReceiver";
private final BroadcastReceiver mPowerReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
Log.d(TAG, "Power connected");
checkPluggedState(context, intent);
} else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
Toast.makeText(context, "Power disconnected", Toast.LENGTH_SHORT).show();
} else {
Log.wtf(TAG, "Unknown action: " + action);
}
}
};
private void checkPluggedState(Context context, Intent intent) {
Intent chargingIntent = registerReceiver(null, new IntentFilter(
Intent.ACTION_BATTERY_CHANGED));
final int pluggedState = chargingIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
final String msg;
switch (pluggedState) {
case 0:
msg = "The device is running on battery";
break;
case BatteryManager.BATTERY_PLUGGED_AC:
msg = "Plugged into AC charger";
break;
case BatteryManager.BATTERY_PLUGGED_USB:
msg = "Plugged into USB charger";
break;
case BatteryManager.BATTERY_PLUGGED_WIRELESS:
msg = "Plugged into wireless charger";
break;
default:
msg = "Unknown state: " + pluggedState;
}
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
registerReceiver(mPowerReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mPowerReceiver);
}
}
Hope this helps.
According to The docs, EXTRA_STATUS is for ACTION_BATTERY_CHANGED
I created PhoneStateListener in a Service. Toast messages work fine, but I want to run another Activity on incoming call. But it won't start. What is wrong with this class? Here's a code of main Activity, DialogAct is an empty Activity with layout.
public class GSMListenerService extends Service {
private TelephonyManager tm;
#Override
public void onCreate() {
super.onCreate();
tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
tm.listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
private PhoneStateListener mPhoneListener = new PhoneStateListener() {
public void onCallStateChanged(int state, String incomingNumber) {
try {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
Intent i = new Intent(GSMListenerService.this,DialogAct.class);
startActivity(i);
Toast.makeText(GSMListenerService.this, "CALL_STATE_RINGING: ", Toast.LENGTH_SHORT).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Toast.makeText(GSMListenerService.this, "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT).show();
break;
case TelephonyManager.CALL_STATE_IDLE:
Toast.makeText(GSMListenerService.this, "CALL_STATE_IDLE", Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(GSMListenerService.this, "default", Toast.LENGTH_SHORT).show();
Log.i("Default", "Unknown phone state=" + state);
}
} catch (Exception e) {
Log.i("Exception", "PhoneStateListener() e = " + e);
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Use FLAG_ACTIVITY_NEW_TASK flag.
Intent intent = new Intent(GSMListenerService.this, DialogAct.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);