SDKにはなくとも、本来のソースにある便利メソッドを使いたい(キリッ
という訳で昨日、ハックにつかったソースコード
リフレクションの実装が多数なので、正直オススメできないかも^^;
これを使えば、SDKからは隠されている特殊なメソッドが実行出来る(ぉpackage com.android;
import java.lang.reflect.Method;
import android.os.IBinder;
import android.util.Log;
/**
* システムサービスのインターフェイスを取得するクラス.
*/
final class GetSystemServiceInterface {
/**
* サービスマネージャーのクラス名.
*/
private static final String SERVICE_MANAGER = "android.os.ServiceManager";
/**
* サービス取得メソッド名.
*/
private static final String GET_SERVICE_METHOD = "getService";
/**
* インターフェイス取得メソッド名.
*/
private static final String AS_INTERFACE = "asInterface";
/**
* サービスのインターフェイスを取得する.
*
* @param serviceName
* サービス名
* @param binderType
* ローカルインターフェイス・スタブのクラス名
* @return サービスのインターフェイス
*/
public static final synchronized Object getServiceStub(String serviceName,
String binderType) {
try {
return getServiceStubInternal(serviceName, binderType);
} catch (Exception e) {
Log.e("ServiceLocator", "", e);
return null;
}
}
private static final Method getDeclaredMethod(Class owner,
String methodName, Class... parameterTypes)
throws SecurityException, NoSuchMethodException {
Method m = owner.getDeclaredMethod(methodName, parameterTypes);
if (!m.isAccessible()) {
m.setAccessible(true);
}
return m;
}
private static final Method getAsInterfaceMethod(Class stub)
throws SecurityException, NoSuchMethodException {
return getDeclaredMethod(stub, AS_INTERFACE, IBinder.class);
}
private static final Object getServiceStubInternal(String serviceName,
String binderType) throws Exception {
Class serviceManager =
GetSystemServiceInterface.class.getClassLoader().loadClass(SERVICE_MANAGER);
Method method = getDeclaredMethod(serviceManager,
GET_SERVICE_METHOD, String.class);
Object binder = method.invoke(null, serviceName);
Class stub =
GetSystemServiceInterface.class.getClassLoader().loadClass(binderType);
Method method2 = getAsInterfaceMethod(stub);
Object service = method2.invoke(null, binder);
return service;
}
}
上のクラスを使うには以下のようにする
ここでは、device_policyをサービス名、
"android.app.admin.IDevicePolicyManager$Stub"をサービスのインターフェースにしている
上記は必要に応じて適宜変更するObject devicepolicyManager = GetSystemServiceInterface.getServiceStub("device_policy",
"android.app.admin.IDevicePolicyManager$Stub");
取得したオブジェクトからリフレクションを使った実行
ここではDevicePolicyManagerのwipeDataメソッドを実行しているClass type = devicepolicyManager.getClass();
Method wipeMethod = type.getMethod("wipeData", int.class);
if (!wipeMethod.isAccessible()) {
wipeMethod.setAccessible(true);
}
wipeMethod.invoke(devicepolicyManager, new Object[]{new Integer(0)});
最もセキュリティエラーでしたが^^;
しかし、Notificationとかだとうまくいく。
2011-04-18
[Android]低レベルなレイヤーを使うには
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿