I am using this method to end a call in android
public boolean killCall(Context context) {
try {
// Get the boring old TelephonyManager
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// Get the getITelephony() method
Class classTelephony = Class.forName(telephonyManager.getClass().getName());
Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony");
// Ignore that the method is supposed to be private
methodGetITelephony.setAccessible(true);
// Invoke getITelephony() to get the ITelephony interface
Object telephonyInterface = methodGetITelephony.invoke(telephonyManager);
// Get the endCall method from ITelephony
Class telephonyInterfaceClass =
Class.forName(telephonyInterface.getClass().getName());
Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall");
// Invoke endCall()
methodEndCall.invoke(telephonyInterface);
} catch (Exception ex) { // Many things can go wrong with reflection calls
Log.d(TAG, "PhoneStateReceiver **" + ex.getCause().getStackTrace());
return false;
}
return true;
}
This does work before Oreo but does not working on android oreo any idea what is missing.
Best Regards: Ali
I do your code and follow the explain:
End call in android programmatically
add the following permission
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
then it's working very well, my code is running on android oreo version.
Related
I use the following code to handle incoming calls from within a service. It works perfectly when i invode the endCall method (My phone's Android Version is ICS). But when I invoke the answerRingingCall method i get an exception for not having permission to modify phone state. I know that Google revoked this permission at one point but since i can invoke the end call method what is the explanation for not being able to invoke the answer call method as well? I mean..both methods modify the phone's state, so what's up? Is there a way to fix this?
try {
TelephonyManager tm = (TelephonyManager)getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
Object telephonyService = m.invoke(tm); // Get the internal ITelephony object
c = Class.forName(telephonyService.getClass().getName()); // Get its class
m = c.getDeclaredMethod("endCall"); // Get the "endCall()" method
m.setAccessible(true); // Make it accessible
m.invoke(telephonyService); // invoke endCall()
}
catch (Exception e) {
Log.w("exception",e);
}
If I had to guess, I'd say in your OEM version of com.android.phone.PhoneInterfaceManager inside the Phone.apk the endCall function doesn't call enforceCallPermission(); before sending the request to end the call.
Where as in the answerRingingCall function calls enforceCallPermission();
You could try a hack where you get access the the private method, on the ITelephony object, sendRequestAsync set accessible to true, and then call it with 4 as the input param, aka CMD_ANSWER_RINGING_CALL.
This would avoid the permissions check.
public int tether(String iface) {
try {
return mService.tether(iface);
} catch (RemoteException e) {
return TETHER_ERROR_SERVICE_UNAVAIL;
}
}
This method simply returns an mService object which is an IConnectivityMananger interface object. The tether() method is declared in this interface. However, the ConnectivityManager does not implement IConnectivityManager interface. So there has to be a class where this tether()method is implemented, but I am unable to find such a class. Any help in this regard is welcome
IConnectivityManager is a remote interface. It is defined in IConnectivityManager.aidl. The tether() method is a part of the remote interface. When mService.tether() is called, this calls a remote method in the connectivity manager service (which is running in a remote process).
I want to pass a Listener through a System Service in Android. I created my Listener Interface using AIDL.
Content of IStatusBarLostFocusCallback.aidl:
package com.android.internal.statusbar;
interface IStatusBarLostFocusCallback {
void onLostFocus();
}
then I extended Androids IStatusBarService.aidl with following Function:
void setStatusBarLostFocusCallback(in IStatusBarLostFocusCallback listener);
and also imported my Interface (in the same directory)
import com.android.internal.statusbar.IStatusBarLostFocusCallback;
In Androids StatusBarManagerService, I extended this Interface since I read to do this in this Thread: Android remote service callbacks like this:
public interface StatusBarLostFocusCallback extends IStatusBarLostFocusCallback {
public void onLostFocus();
}
Now I want to set the Listener with the setStatusBarLostFocusCallback which is defined in IStatusBarService.aidl and implemented in StatusBarManagerService.java.
However, when I try to compile the Framework, I get the following Error
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/statusbar/IStatusBarService.java:287: cannot find symbol
symbol : class IStatusBarLostFocusCallback
location: package com.android.internal.statusbar
com.android.internal.statusbar.IStatusBarLostFocusCallback _arg0;
What have I missed. Do I have to write a .java for the IStatusBarLostFocusCallback? If so, what should be in there?
you try as described like this ?
If yes, and this didn't work, you may implement methods from aidl like this, for example:
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Class aClass = Class.forName(telephonyManager.getClass().getName());
Method method = aClass.getDeclaredMethod("getITelephony");
method.setAccessible(true);
ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager);
telephonyService.endCall();
I managed it now. I forgot to add my AIDL to the Build in /frameworks/base/Android.mk (I did forget to mention I am building the Source).
I now no longer extend the Interface but implement it like this:
mBarService.setStatusBarLostFocusCallback(new IStatusBarLostFocusCallback.Stub(){
public void onLostFocus(){
mHasStatusbarFocus = false;
}
});
In some cases I don't want listen to state of my phone.
How to destroy object of PhoneStateListener class?
I create object this way
try {
phoneCallListener = new WnetPlayerPhoneCallListener();
TelephonyManager mTM = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(phoneCallListener, PhoneStateListener.LISTEN_CALL_STATE);
} catch(Exception e) {
Log.e("PhoneCallListener", "Exception: "+e.toString());
}
In the documentation it states to pass the listener object and flag LISTEN_NONE to unregister a listener.
Per this answer, you should keep a reference to TelephonyManager and WnetPlayerPhoneCallListener, and set it to disabled, like so:
mTm.listen(phoneCallListener, PhoneStateListener.LISTEN_NONE);
Why they don't just have standard addListener() and removeListener() methods, I don't know, but this seems to be the accepted method for solving your problem.
There is a "SIM card lock" option in android "setting/Location & security settings" page.
It's necessary to input a PIN code after booting if the option is set.
Is there any programmatic method to detect if PIN is required ? (not current sim state but the setting option value ex: true/false)
You can use the following class:
TelephonyManager
http://developer.android.com/reference/android/telephony/TelephonyManager.html
You do not instantiate this class directly; instead, you retrieve a reference to an instance through Context.getSystemService(Context.TELEPHONY_SERVICE)
TelephonyManager manager = (TelephonyManager) Context.getSystemService(Context.TELEPHONY_SERVICE);
int state = manager.getSimState();
if(state == TelephonyManager.SIM_STATE_PIN_REQUIRED || state == TelephonyManager.SIM_STATE_PUK_REQUIRED)
{
//PIN/PUK is required
}
Following the comments, this is the final version:
TelephonyManager tm =
(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
Class clazz = Class.forName(tm.getClass().getName());
Method m = clazz.getDeclaredMethod("getITelephony");
m.setAccessible(true);
ITelephony it = (ITelephony) m.invoke(tm);
if(it.isSimPinEnabled())
{
//This should work;
}
As getSimLockEnabled always returns false for me, i had to find another way to do it.
See https://stackoverflow.com/a/12748638/314089 for the answer.