Intercept Phone Calls to display contact Info - android

This question is more of a "is it possible" question.
Is it possible for Android to use a different contact list from an application when displaying the identity of an incoming caller?
So for example, if a person calls and their identity is in the apps contact list, but NOT in the internal devices contact list, i want to make the id found in the apps contact list show up on the caller id of the incoming call.
Any insight would be appreciated!

I found the solution I was looking for. I ended up just using a notification to display who was calling. I hope this helps someone else out there looking for a nice solution!
StateListener yourListener = new StateListener();
TelephonyManager yourmanager =(TelephonyManager)getSystemService(TELEPHONY_SERVICE);
yourmanager.listen(yourListener, PhoneStateListener.LISTEN_CALL_STATE);
class StateListener extends PhoneStateListener{
#Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
//do what you want with the incoming number here:
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
case TelephonyManager.CALL_STATE_IDLE:
break;
}
};
public void onDestroy() {
}
}

I think it's possible with broadcast receiver. Here some similar question Call block, Taking complete control of phone, is it possible and another open source app called Intent Intercept. I give you call blocking link so you can catch number, direct to your app and block normal dialer

Related

Why is the IncomingNumber always empty?

I'm totally new to mobile programming and to Xamarin or Xamarin.Forms. So I thought about starting small and trying a first app that is showing the phone number of an incoming call (just to know how to get this information into my app).
After a lot of trying and searching the net and not finding appropriate answers, I managed to at least be able to hit break points when there's an incoming call.
For that I created a class called StateListener in the Android specific project of my Xamarin.Forms solution. This class looks like that:
public class StateListener : PhoneStateListener
{
public override void OnCallStateChanged(CallState state, string incomingNumber)
{
base.OnCallStateChanged(state, incomingNumber);
switch (state)
{
case CallState.Ringing:
break; // <== set break point here
case CallState.Offhook:
break;
case CallState.Idle:
break;
}
}
}
And I instantiated this class in my MainActivity's OnCreate method like this:
StateListener phoneStateListener = new StateListener();
TelephonyManager telephonyManager = (TelephonyManager)GetSystemService(Context.TelephonyService);
telephonyManager.Listen(phoneStateListener, PhoneStateListenerFlags.CallState);
Now, when I run my little solution then the break point (see comment in code) is hit, but unfortunately the incomingNumber of the OnCallStateChanged method is always empty.
Following the unsatisfying documentation about the OnCallStateChanged method I set the needed Permission.ReadPhoneState permission in the manifest file, but that didn't help.
Maybe you can?
As doc says:
If application does not have READ_CALL_LOG permission or carrier
privileges (see TelephonyManager.hasCarrierPrivileges()), an empty
string will be passed as an argument.
so please check your application permissions.
It seems that once you emulated your app you have to set any new permissions manually inside the emulated Android, your app won't ask for it, since it's already installed.
After I gave my app the "Phone" permissions inside the emulated Android and restarted my app, I got the incomingNumber.

Xamarin Forms How to know when a call is currently taking place

I am writing some code for a Xamarin Forms Android app which dials a phone number but I don't want to dial the number if the user is currently on a call(whether incoming or outgoing, it doesn't make a difference). I have researched a lot about the phone state but I can't find what I am looking for, unless I am applying it incorrectly. What I need is something like this:
if (NoCurrentCallIsTakingPlace)
{
var uri = Android.Net.Uri.Parse(string.Format("tel:{0}", PhoneNumber));
var intent = new Intent(Intent.ActionCall, uri);
Xamarin.Forms.Forms.Context.StartActivity(CurrentIntent);
}
The code to dial the number works but it's the the conditional statement/code to check the phone state that I am having a problem with. Please could someone help. Apologies if your need more info. Please let me know and I will provide it. Thank you.
Well in native android you have the telephony manager to check what is the state of your device:
It has three states:
Idle: when it's idle there is no call
Offhook: when Off-hook it is in call
Ringing: when Ringing
var telephonyManagerService = (TelephonyManager)Xamarin.Forms.Forms.Context.GetSystemService(TelephonyService);
var getCurrentState = telephonyManagerService?.CallState;
switch (getCurrentState)
{
case CallState.Idle:
//No call
break;
case CallState.Ringing:
//Ringing
break;
case CallState.Offhook:
//On call
break;
default:
break;
}
Revert in case of queries

Using fetchUuidsWithSdp() to prevent friendly name caching

DEFINITION:
My non-android device (NAD) is a Bluetooth device who loops its name from 60 to 0 and resets in an infinite fashion.
OBJECTIVE:
What I'm trying is to do is to have my android device as closely as possible detect that countdown and initiate an alarm as close to that of the NAD counter as possible.
I'm doing this by getting the native BluetoothAdapter of my device to startDiscovery() manually by tying the function to onscreen buttons and keeping an eye on the toasts I set through my BroadcastReceiver, which updates onscreen Textviews Which enables me to monitor what my device is receiving in real-time
REQUIREMENT:
System & resource efficiency is not a concern in this context.
PROBLEM:(Keep an eye out for PART 1 and PART 2 in the code)
I'm not sure how using fetchUuidsWithSdp() is helping me since the TextView it's updating remains empty and the Textview getting populated by the EXTRA_NAME extra from intent returning action ACTION_NAME_CHANGED is the cached, initial discovery name (ie. my application is not reading a name after initial discovery).
my code can be found below
Sorry for any newbie mistakes,I'm trying my best :)
public class BTBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
//pulling the action name from the broadcasted intent
String action = intent.getAction();
if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
sToaster("StartedD");//show toast that Discovery has started
}
else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
sToaster("EndedD");//show toast signifying end of discovery
/*
if(notfound){
mBTAdapter.startDiscovery();
}*/
}
else if(BluetoothDevice.ACTION_FOUND.equals(action)){
//when a device is found
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//make sure it's indeed my NAD device by checking MAC address
if(device.getAddress().equals(MACAddress)){
if(notfound){
//show device name on screen
sToaster("FOUND DEvice");
notfound = false;
NAD = device;
NameShower.setText(device.getName());
}
else{
//do nothing if it's the second time the device is found
}
}
}
else if(BluetoothDevice.ACTION_NAME_CHANGED.equals(action)){
//name changed
BluetoothDevice foundDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//make sure it's indeed my NAD device
if(foundDevice.equals(NAD)){
sToaster("Name Change!"); //show on screen that the name change intent has been caught
//PART1
//to prevent caching of the old device name StackOverflow article
//advised using this function i don't totally understand yet
//NAD.fetchUuidsWithSdp();
//either commented or not commented the outcome is the same (no refresh of the name)
//PART2
//tried showing the new name two different ways below, neither of which are effective
//by inspecting the TextViews on-screen
NameShower.setText(foundDevice.getName());
EventView.setText(intent.getStringExtra(BluetoothDevice.EXTRA_NAME));
}
}
}
};
I have worked on a bluetooth project and what I perceived was that the discovery process should be in an Intent which can be left registered in the background. And to discover the devices in range, you just need to invoke the BTDevice.startDiscovery() to search them.
Generally the startDiscovery() drains battery if enabled continuously.
If you want, I can edit this post to share a snipet that I used to scan for devices.
Hope this helps !

Android multiplayer bluetooth

I'm trying to develop a simple multiplayer game using bluetooth with Eclipse
The game is already working in single player mode (using AndEngine), but now I need to send information
between devices.
The part that concerns establishing connection between devices,and link them
is already working, and I can send messages between devices, but now I need to
start the game on "the other" device, so I think that the solution is sending an Intent
using Bluetooth, but I'm not sure if this is possible or not.
So, how can I start the game in both devices at the same time? (I don't want the game in real time, I just want to compare the number of coins that each player gets).
Thank you very much!
If you see the "Uno" game, you'll get some idea. There, they aren't using Bluetooth, but WiFi.
From that I learned, and some other bluetooth games that you wait for Connection successful.
If you're using BluetoothChat application as the reference, then use your Handler as your event generator to start your game.
// The Handler that gets information back from the BluetoothChatService
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothChatService.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));
mConversationArrayAdapter.clear();
// DO YOUR ACTIVITY HERE .. ..
// May Be like ... Intent intent = new Intent( ... )
break;

Android detecting when lines have been connected during an outgoing call

Just a quick background I'm Running CM7 on a rooted Nexus one.
I am trying to detect when an outgoing call is actually connected: has stopped ringing and the person you are calling has answered. Looking through the forums this seems to be a tough and perhaps unanswered question. I'd really appreciate any insight into this.
In my searching the best I could find was in:
Android : How to get a state that the outgoing call has been answered?
#PattabiRaman said: "instead of detecting the outgoing call connection state, it is easy to get the duration of the last dialed call."
Does he mean that one should get the duration of the last dialed call as the call is in progress? And when that duration goes over 0 then you know?
The class com.android.internal.telephony.CallManager should have information about when the call actually is answered. It has a public static method getInstance() which returns the CallManager instance, and a public method getActiveFgCallState() which returns the current call state as a Call.State enum.
So in theory something like this might work:
Method getFgState = null;
Object cm = null;
try {
Class cmDesc = Class.forName("com.android.internal.telephony.CallManager");
Method getCM = cmDesc.getMethod("getInstance");
getFgState = cmDesc.getMethod("getActiveFgCallState");
cm = getCM.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
And then repeatedly poll the state:
Object state = getFgState.invoke(cm);
if (state.toString().equals("IDLE")) {
...
} else if (state.toString().equals("ACTIVE")) {
// If the previous state wasn't "ACTIVE" then the
// call has been established.
}
I haven't verified that this actually works. And even if it does you'll have to keep in mind that the API could change, since this isn't something that app developers are supposed to rely on.
I have looked into the code.
It will always give null unless you instantiate a Phone object and set it as default Phone.
But instantiating it needs some System permissions allowed only to system aps.
By using this method:
com.android.internal.telephony.PhoneFactory# public static void makeDefaultPhones(Context context) {
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.4_r1.2/com/android/internal/telephony/PhoneFactory.java

Categories

Resources