ChuongPham
ChuongPham

Reputation: 4801

Android Reflection Method Error

I'm trying to figure out Reflection with this Android class:

Class<?> c = Class.forName("com.android.internal.widget.LockPatternUtils");
Method method = c.getDeclaredMethod("getKeyguardStoredPasswordQuality");
method.setAccessible(true);
Object object = method.invoke(c); // Error with this line
result = object.toString());

The method getKeyguardStoredPasswordQuality is declared as (no parameters):

public int getKeyguardStoredPasswordQuality() {
    // codes here
}

The error I got is:

Exception: java.lang.IllegalArgumentException: expected receiver of type com.android.internal.widget.LockPatternUtils, but got java.lang.Class<com.android.internal.widget.LockPatternUtils>

How do I declare com.android.internal.widget.LockPatternUtils as a receiver?

Upvotes: 6

Views: 8882

Answers (2)

ChuongPham
ChuongPham

Reputation: 4801

Never mind, I've figured it out. I've adapted the codes below based on this tutorial.

In case anyone is interested in the solution, here it is:

Class<?> c = Class.forName("com.android.internal.widget.LockPatternUtils");
Constructor<?>[] constructors = c.getDeclaredConstructors();
Constructor<?> constructor = null;
for (int i = 0; i < constructors.length; i++) {
   constructor = constructors[i];
   if (constructor.getGenericParameterTypes().length == 0)
      break;
}
constructor.setAccessible(true);
Object clazz = constructor.newInstance(context, true);
Method method = clazz.getClass().getDeclaredMethod("getKeyguardStoredPasswordQuality");
Object object = method.invoke(clazz);
result = object.toString();

The above solution requires that the public constructor of LockPatternUtils.java class to be defined as:

public LockPatternUtils(Context context) {...}

If the constructor changes in the future (after 2013), the solution will need to be amended.

Note: The above is an exercise for me to understand the usage of Reflection. However, using Reflection in Android production apps should be used sparingly and when absolutely needed.

Upvotes: 1

Keppil
Keppil

Reputation: 46209

You are passing the class to #invoke() instead of an instance of LockPatternUtils.

You can create an instance using #newInstance().

Upvotes: 14

Related Questions