THE RAKE 1

Trying to get the returned boolean value from the abstract getIccLockEnabled() method. The method is located in the abstract IccCard interface of the com.android.internal.telephony package. I do this:

 Class cls = Class.forName("com.android.internal.telephony.IccCard"); Method method = cls.getMethod("getIccLockEnabled"); boolean value = method.invoke(cls); Log.i("ICC_LOCK_STATUS", value ? "Заблокировано" : "Разблокировано"); 

Log:

 java.lang.IllegalArgumentException: Expected receiver of type com.android.internal.telephony.IccCard, but got java.lang.Class<com.android.internal.telephony.IccCard> 

IccCard source code

.

THE RAKE 2

In connection with the answer and comments, I realized that I need to find a class that will inherit from IccCard and I found it - this is IccCardProxy . New code:

 Class iccCard = Class.forName("com.android.internal.telephony.IccCard"); Class proxy = Class.forName("com.android.internal.telephony.uicc.IccCardProxy"); Method method = iccCard.getMethod("getIccLockEnabled"); boolean value = method.invoke(proxy.newInstance()); Log.i("ICC_LOCK_STATUS", value ? "Заблокировано" : "Разблокировано"); 

Log:

 java.lang.InstantiationException: class com.android.internal.telephony.uicc.IccCardProxy has no zero argument constructor 

IccCardProxy source code

.

THE RAKE 3

I looked at what the IccCardProxy class constructor looks like - it accepts android.content.Context , com.android.internal.telephony.CommandsInterface and int . New code:

 Class iccCard = Class.forName("com.android.internal.telephony.IccCard"); Class proxy = Class.forName("com.android.internal.telephony.uicc.IccCardProxy"); Class commandsBoss = Class.forName("com.android.internal.telephony.CommandsInterface"); Method method = iccCard.getMethod("getIccLockEnabled"); Constructor ctr = proxy.getConstructor(new Class[]{android.content.Context.class, commandsBoss, int.class}); boolean value = method.invoke(ctr.newInstance(MainActivity.this, commandsBoss.newInstance(), 4)); Log.i("ICC_LOCK_STATUS", value ? "Заблокировано" : "Разблокировано"); 

Log:

 java.lang.InstantiationException: interface com.android.internal.telephony.CommandsInterface cannot be instantiated 

Since CommandsInterface , like IccCard , is an interface, I need to find a class that inherits it in order to get it

Source CommandsInterface

.

THE RAKE 4

A class that inherits from CommandsInterface found. This is RIL (Radio Interface Layer) . New code

 Class iccCard = Class.forName("com.android.internal.telephony.IccCard"); Class proxy = Class.forName("com.android.internal.telephony.uicc.IccCardProxy"); Class commandsBoss = Class.forName("com.android.internal.telephony.CommandsInterface"); Class ril = Class.forName("com.android.internal.telephony.RIL"); Method method = iccCard.getMethod("getIccLockEnabled"); Constructor ctr = proxy.getConstructor(new Class[]{android.content.Context.class, commandsBoss, int.class}); boolean value = method.invoke(ctr.newInstance(MainActivity.this, ril.newInstance(), 4)); Log.i("ICC_LOCK_STATUS", value ? "Заблокировано" : "Разблокировано"); 

Log:

 java.lang.InstantiationException: class com.android.internal.telephony.RIL has no zero argument constructor 

RIL source code

.

THE RAKE 5

He derived the number of constructors in the RIL class - 2. The types of the parameters of the first constructor are android.content.Context , int , int . The second is android.content.Context , int , int , java.lang.Integer . I decided to pass the parameters to the first constructor. New code

 Class iccCard = Class.forName("com.android.internal.telephony.IccCard"); Class proxy = Class.forName("com.android.internal.telephony.uicc.IccCardProxy"); Class commandsBoss = Class.forName("com.android.internal.telephony.CommandsInterface"); Class ril = Class.forName("com.android.internal.telephony.RIL"); Method method = iccCard.getMethod("getIccLockEnabled"); Constructor ctr = proxy.getConstructor(new Class[]{android.content.Context.class, commandsBoss, int.class}); Constructor ril_constructor = ril.getConstructor(new Class[]{android.content.Context.class, int.class, int.class}); boolean value = method.invoke(ctr.newInstance(MainActivity.this, (ril_constructor.newInstance(MainActivity.this, 4, 6)), 4)); Log.i("ICC_LOCK_STATUS", value ? "Заблокировано" : "Разблокировано"); 

Log:

 java.lang.reflect.InvocationTargetException 

I think that you need to send parameters to both designers. How to do it? Or a mistake in something else? Help, I'm specifically confused, I need to pass an object of type CommandsInterface to the method, and I'm trying to send it to an instance from the parameters of the RIL constructor. But I don’t understand what’s wrong, I’ve almost “hacked” this system. It feels like Google has left the opportunity to do this, but he mocked :)

.

THE RAKE 6

In connection with updating the response, I realized that there is a UiccController class with getInstance() and getUiccCard , it seems to have done right, but there was a log

 class ... has no zero argument constructor 

And, deriving the number of designers, I get 0. New code:

 Class iccCard = Class.forName("com.android.internal.telephony.IccCard"); Class uiccController = Class.forName("com.android.internal.telephony.uicc.UiccController"); Method getInstance = uiccController.getMethod("getInstance"); Method getUiccCard = uiccController.getMethod("getUiccCard"); Constructor[] uicc_constructor = uiccController.getConstructors(); log(""+uicc_constructor.length); 

.

THE RAKE 7

It turns out on the model under test (for which the application is being made) the constructor of the UiccController class with the access modifier private . This means that you need to use the getDeclaredConstructor() method. Now it returns the number of constructors - 1. I found out the types of parameters for this constructor - android.content.Context [Lcom.android.internal.telephony.CommandsInterface; The context is clear, but what about CommandsInterface ? I'm trying to do it like this

 Class iccCard = Class.forName("com.android.internal.telephony.IccCard"); Class uiccController = Class.forName("com.android.internal.telephony.uicc.UiccController"); Class commandsInterface = Class.forName("com.android.internal.telephony.CommandsInterface"); Method getInstance = uiccController.getMethod("getInstance"); Method getUiccCard = uiccController.getMethod("getUiccCard"); Constructor uicc_constructor = uiccController.getDeclaredConstructor(new Class[]{android.content.Context.class, commandsInterface}); 

In theory, everything is correct, in the body of the constructor I put the context and the CommandsInterface class. But, I get this log:

 java.lang.NoSuchMethodException: <init> [class android.content.Context, interface com.android.internal.telephony.CommandsInterface] 

What's wrong? I am strained by the letter L in front of the second parameter of the constructor. Is that the case? What kind of L ?

.

THE RAKE 8

New code, final. Almost all!

 Class uiccController = Class.forName("com.android.internal.telephony.uicc.UiccController"); log("Класс найден"); Method getInstance = uiccController.getMethod("getInstance"); log("Метод найден"); Object instance = getInstance.invoke(null); log("instance взят"); Method getCard = instance.getClass().getMethod("getUiccCard"); log("Метод найден"); Object card = getCard.invoke(instance); log("принято"); Method getLockEnabled = card.getClass().getMethod("getIccLockEnabled"); log("выполняем метод"); boolean result = (Boolean) getLockEnabled.invoke(card); log("принят отаювет!"); log(result?"true":"false"); 

Log: InvocationTargetException . The third line is not executed.

 Object instance = getInstance.invoke(null); 

Closed due to the fact that off-topic participants Pavel Mayorov , Alexey Shimansky , αλεχολυτ , ߊߚߤߘ , Mikhail Vaysman 17 Apr '17 at 0:08 .

  • Most likely, this question does not correspond to the subject of Stack Overflow in Russian, according to the rules described in the certificate .
If the question can be reformulated according to the rules set out in the certificate , edit it .

  • Updated the answer. See section update2 - Andrew Bystrov
  • 9
    Well, you ask a question, and then supplement it with new questions. Will not work. The purpose of the questions on StackOverflow is not the delivery of your project, but the answer to the question. If you need new information during the implementation process, please accept this answer and ask a new question. - VladD
  • one
    Vlad writes quite right. There is no need to fundamentally change the formulation of the question, because this makes these answers already outdated and inappropriate to the question. If you have been given an answer that led to the solution of the originally formulated problem, then it is good to accept this answer. If you used the answer, move on and encounter a new problem that you cannot solve, be sure to formulate a new question. You can give a link to this question as a context and leave the author a comment with a request to look at the new question. - Nick Volynkin
  • four
    This question should be closed, because it is 7 different questions, and not one. - Pavel Mayorov

1 answer 1

 Method method = cls.getMethod("getIccLockEnabled"); boolean value = method.invoke(cls); 

This will call the getIccLockEnabled method on the cls getIccLockEnabled .

cls is an object of type Class<?> , not an object of type IccCard , so you have an error.

You can get an instance of the desired object from cls calling the newInstance() method, but you will get an InstantiationException because Cannot get an instance of an abstract class or interface.

PS on a subject - you can. Here is an example.

Abstract class

 public abstract class MyAbstractClass { public abstract boolean someMethod(); } 

Its implementation

 public class MyAbstractClassImpl extends MyAbstractClass { public MyAbstractClassImpl() { } @Override public boolean someMethod() { return true; } } 

And test class

 public class Test { public static void main(String[] args) throws Exception { Class<MyAbstractClass> aClass = MyAbstractClass.class; Method someMethod = aClass.getMethod("someMethod"); MyAbstractClassImpl myAbstractClassInstance = MyAbstractClassImpl.class.newInstance(); boolean invoke = (boolean) someMethod.invoke(myAbstractClassInstance); System.out.println(invoke); // в консоле выводит true } } 

UPDATE

I read some javadoc here for your IccCard interface. It is written there

@Deprecated use UiccController.getUiccCard instead.

There is a wonderful class UiccController , in which there are 2 methods: getInstance () and getUiccCard () , which returns the desired interface.

Therefore, all that had to be done was

 com.android.internal.telephony.uicc.UiccController.getInstance().getUiccCard().getIccLockEnabled() 

UPDATE2

About rake7 . You do not need to take constructors from UiccController , you just need to retrieve the instance of the class using getInstance() . If you want to do through reflection, you need to do so.

 Class uiccController = Class.forName("com.android.internal.telephony.uicc.UiccController"); Method getInstance = uiccController.getMethod("getInstance"); Object instance = getInstance.invoke(null); Method getCard = instance.getClass().getMethod("getUiccCard"); Object card = getCard.invoke(instance); Method getLockEnabled = card.getClass().getMethod("getIccLockEnabled"); boolean result = (Boolean) getLockEnabled.invoke(card); 
  • Comments are not intended for extended discussion; conversation moved to chat . - Nicolas Chabanovsky