call activity onCallStateChange from service - android

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);

Related

Not work Every time PhoneStateListener Android

I have Developing Application of Full Caller Id. In that dynamic screen call at the time of Incoming call / After Missed Call. Now this is work one time. When i received call. Than after it is not work or Not call any dynamic screen at the time Incoming call/ Missed call.
I have very confuse about my problem.
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.v("idle state", "CALL_STATE_IDLE");
// CALL_STATE_IDLE;
if(ring == true && callReceived == true && CheckMissCall.isReject == true)
{
Intent inter = new Intent(c, callLog.class);
inter.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
c.startActivity(inter);
}
if (ring == true && callReceived == false && CheckMissCall.isRunning== false) {
Log.v("missed call", "Missed call from : " + incomingNumber);
if(CheckMissCall.isShown)
{
c.stopService(new Intent(c, Unlock_hud.class));
}
flag = true;
if (prefs.getBoolean("main_state", true))
{
Intent inter = new Intent(c, MissCall.class);
inter.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
inter.putExtra("CellNumber", incomingNumber);
c.startActivity(inter);
}
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// CALL_STATE_OFFHOOK;
callReceived = true;
Log.v("call received", "CALL_STATE_OFFHOOK " + incomingNumber);
break;
case TelephonyManager.CALL_STATE_RINGING:
ring = true;
// CALL_STATE_RINGING
Log.v("call ringing", "CALL_STATE_RINGING " + incomingNumber);
Log.d("flags", "flags: " + flag);
if (flag) {
//cut = true;
//flag = false;
CheckMissCall call = new CheckMissCall(c);
call.setName(incomingNumber);
call.setNumber4Sms(incomingNumber);
call.setContactPhoto();
Log.d("main", "state ringing");
//prefs = PreferenceManager.getDefaultSharedPreferences(c);
if (!prefs.getBoolean("main_state", false)) {
return;
}
/* if (!isScreenOn && CheckMissCall.isRunning) {
return;
}*/
if (CheckMissCall.isRunning) {
return;
}
else {
Log.d("main", "EEEEEEEEEEEEEEEE: Unlock hud");
Intent in = new Intent(c, Unlock_hud.class);
in.setFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
c.startService(in);
// c.stopService(new Intent(c, Unlock_hud.class));
}
}
break;
}
this is because when any call comes your app goes into background, while for the first time when you receive call your MyPhoneStateListener listens for the call and it ends..
now do one thing.. Run your code in service it will run in background and it will call your dynamic screen
in your main activity start service for this i have used toggle button(to enable or disable service)
tgl_switch.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(tgl_switch.isChecked()){
startService(new Intent(getApplicationContext(),LogsService.class));
Toast.makeText(getApplicationContext(), "Call Logger Active",
Toast.LENGTH_SHORT).show();
}else{
stopService(new Intent(getApplicationContext(),LogsService.class));
Toast.makeText(getApplicationContext(), "Call Logger Deactive",
Toast.LENGTH_SHORT).show();
}
}});
for example i did this
public class LogsService extends Service {
String name;
String phNumber;
String callType;
String callDate;
Date callDayTime;
String callDuration;
String dir ;
String fileName;
boolean wasRinging=false, wasoffHook=false, wasidle=false;
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(final 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
Log.d("ring ", "Detected");
wasRinging = true;
// 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_OFFHOOK)){
wasoffHook=true;
// Toast.makeText(context, "hang up", Toast.LENGTH_LONG).show();
}
else if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_IDLE)) {
// This code will execute when the call is disconnected
wasidle=true;
// Toast.makeText(context, "IDLE STATE", Toast.LENGTH_LONG).show();
if((wasRinging && wasoffHook && wasidle)){
// this is received call event
startActivity(new Intent(getApplicationContext(), Incoming.class));
} else if(wasRinging && wasidle){
// this is missed call event
startActivity(new Intent(getApplicationContext(), MissCall.class));
}
wasidle = false;
wasoffHook = false;
wasRinging=false;
}
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
IntentFilter filter = new IntentFilter();
filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(receiver);
}
}
i used this code to get details of last call you can modify it in your way

Android PhoneStateListener onPhoneStateChanged method not invoked from service

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.

Why my service can't be destroyed

Sorry for my English.
I have one Activity that call one service and i want to stop this service from that Activity.
I try to use stopService(getApplicationContext(), TempService.class) And it doesn't worked.
Here is my service code
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Debug", "Service start");
mgr = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
temp = mgr.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
mgr.registerListener(this, temp, SensorManager.SENSOR_DELAY_FASTEST);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onDestroy() {
Log.d("DEBUG", "on destroy");
notificationManager.cancel(0);
super.onDestroy();
}
And in my Activity : boolean t always return false value.
I have no idea.
private void processStopService(final String tag) {
Intent intent = new Intent(getApplicationContext(), TempService.class);
intent.addCategory(tag);
boolean t = stopService(intent);
if (t)
{
Log.e("DEBUG", "TRUE");
}
else
Log.e("DEBUG", "FALSE");
}
Do not use categories with services. Delete the addCategory() call on your Intent.

Play TTS over BlueTooth

I have a little app where I want to be able to send TTS audio to speaker or bluetooth headset if connected. It is working fine in the speaker phone mode, but no luck with BT. Any idea how this could be addressed? Code snippet is below:'
private void speak(String s){
HashMap<String, String> hash = new HashMap<String, String>();
hash.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_SYSTEM));
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
tts.speak(s, TextToSpeech.QUEUE_ADD, hash);
}
'
Use my answer at Using the Android RecognizerIntent with a bluetooth headset
In your activity that you declare private void speak(String s) add the a class member
BluetoothHeadsetUtils mBluetoothHelper;
TelephonyManager mTelManager;
MyPhoneStateListener mPhoneStateListener = new MyPhoneStateListener();
On this same activity onCreate() add
#Override
public void onCreate()
{
mBluetoothHelper = new BluetoothHeadsetUtils(this);
mTelManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
mTelManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
And onResume() and onPause of the activity add
#Override
onResume()
{
mBluetoothHelper.start();
}
#Override
onPause()
{
mBluetoothHelper.stop();
}
You can define your speak(String s) as
public void speak(String s, String utteranceId) // utteranceId can be an empty string
{
HashMap<String, String> myHashRender = new HashMap<String, String>();
myHashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId);
if (mBluetoothHelper.isOnHeadsetSco())
{
myHashRender.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
String.valueOf(AudioManager.STREAM_VOICE_CALL));
}
tts.speak(s, TextToSpeech.QUEUE_ADD, myHashRender);
}
Instead of broadcast receiver use phone state listener
protected class MyPhoneStateListener extends PhoneStateListener
{
#Override
public void onCallStateChanged(int state, String incomingNumber)
{
switch (state)
{
case TelephonyManager.CALL_STATE_RINGING:
mAudioManager.setStreamMute(AudioManager.STREAM_RING, true);
speak("whatever you want here", "ringing"); //$NON-NLS-1$
Log.d(TAG, "ringing cancel recognizer"); //$NON-NLS-1$
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "offhook cancel recognizer"); //$NON-NLS-1$
break;
case TelephonyManager.CALL_STATE_IDLE:
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
}
mBluetoothHelper.start();
}
}).start();
Log.d(TAG, "call state idle"); //$NON-NLS-1$
}
}
}
In your activity or service add implement OnUtteranceCompletedListener and add the code below
#Override
public void onUtteranceCompleted(String utteranceId)
{
if (utteranceId.equals("ringing"))
{
mAudioManager.setStreamMute(AudioManager.STREAM_RING, false);
mBluetoothHelper.stop();
}
}

No ringing event on incoming calls

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();
}

Categories

Resources