反射 - ClassNotFoundException

时间:2013-02-28 14:38:18

标签: java android reflection

我正试图找到一种以编程方式干净利落地关闭设备的方法。我的应用程序具有root / system权限,因此我不想使用建议in other answers的方法来执行此操作,而是希望“正确”执行此操作,因为系统会...

使用反射,我正在尝试访问类com.android.internal.app.ShutdownThread及其中的关闭方法。

private static final String SHUTDOWN_CLASS = "com.android.internal.app.ShutdownThread";
private static final String SHUTDOWN_METHOD = "shutdown";

Class<?> sdClass;
Method shutdown;
boolean sd;
boolean success = false;

try {
    sdClass = Class.forName(SHUTDOWN_CLASS);
    Object obj = sdClass.newInstance();

    shutdown = sdClass.getDeclaredMethod(SHUTDOWN_METHOD);

    shutdown.setAccessible(true);
    sd = (Boolean) shutdown.invoke(obj, ctx, false);

    success = sd;

} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (NoSuchMethodException e) {
    e.printStackTrace();
} catch (IllegalArgumentException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
} catch (InstantiationException e) {
    e.printStackTrace();
}

我已经看过other answers我需要的状态“确保编译的类文件实际上在类路径上” - 我认为它是(尽管有异常!),但也许我误解了它的含义'类路径'。

我也不确定扩展'Thread'的Class是否也有问题?

我可以使用以下代码重新启动或重新启动到recovery / bootloader:

((PowerManager) ctx.getSystemService(Context.POWER_SERVICE)).reboot(action);

我使用的操作字符串是null,bootloader或recovery。我试着很有希望“关机”,但它没有用。这些显然是发送到内核的消息,但我找不到哪些可以在任何地方使用的参考...

注意:在发布'您不应该以编程方式执行此操作'之前,我的用户已经请求它并且完全了解我的应用程序具有的系统和root权限。这就是他们安装它的原因!

如果有人能够指出我做的事情是不可能的,或者我第一次尝试使用反射我出错了,我很感激。


更新

CommonsWare的评论当然绝对正确,Class路径不再存在。在Jelly Bean源代码中,它现在是com.android.server.power.ShutdownThread

尽我所能,但是使用以下代码无法解决错误的窗口令牌问题。

boolean sd = false;
boolean success = false;

        try {
            Class<?> sdClass = Class.forName("com.android.server.power.ShutdownThread");

            for (Constructor<?> ctor : sdClass.getDeclaredConstructors()) {
                // Log output
            }

            Constructor<?> con = sdClass.getDeclaredConstructors()[0];
            con.setAccessible(true);

            for (Method m : sdClass.getDeclaredMethods()) {

                if (m.getName().matches("shutdown")) {
                    m.setAccessible(true);
                    sd = (Boolean) m.invoke(ctx, ctx, false);
                }
            }

            success = sd;

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
             e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
             e.printStackTrace();
        }

        return success;

我现在得到的错误是:

  

W / System.err(17002):引起:   android.view.WindowManager $ BadTokenException:无法添加窗口   android.view.ViewRootImpl$W@41ae4a10 - 此权限被拒绝   窗口类型

     

W / System.err(17002):at   com.android.server.power.ShutdownThread.beginShutdownSequence(ShutdownThread.java:222)

我认为这是因为我正在从服务执行此操作,而它可能需要从Foreground Activity执行?如果有人有任何线索,我很想知道......

0 个答案:

没有答案