2011-04-18

[Android]低レベルなレイヤーを使うには

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とかだとうまくいく。

0 件のコメント:

コメントを投稿

Blogger Syntax Highliter