android 反射调用API中@hide的方法失败,请大神指教

时间:2022-09-14 19:38:07
代码如下:
public Bitmap screenshot(int widht, int height) {
Class cl;
Bitmap shot = null;
try {
cl = Class.forName("android.view.Surface");
Object invoker = cl.newInstance(); 
Method screenShot = cl.getMethod("screenshot",new Class[]{int.class, int.class});
// screenShot.setAccessible(true);
Object result = screenShot.invoke(invoker, new Object[]{widht,height});
shot = (Bitmap) result;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();

return shot;
}

调用方法如下:android.view.Surface
    /**
     * Like {@link #screenshot(int, int, int, int)} but includes all
     * Surfaces in the screenshot.
     *
     * @hide
     */
    public static Bitmap screenshot(int width, int height) {
        // TODO: should take the display as a parameter
        IBinder displayToken = getBuiltInDisplay(BUILT_IN_DISPLAY_ID_MAIN);
        return nativeScreenshot(displayToken, width, height, 0, 0, true);
    }

报错信息:
04-03 10:17:19.732: W/System.err(28374): java.lang.NoSuchMethodException: screenshot [int, int]
04-03 10:17:19.733: W/System.err(28374):    at java.lang.Class.getConstructorOrMethod(Class.java:472)
04-03 10:17:19.733: W/System.err(28374):    at java.lang.Class.getMethod(Class.java:864)

9 个解决方案

#1


我也刚用了反射方法,调用screenshot,但是只是在个别的机子上可以用。

#2


再补一句,而且,在Manifest文件中,要写 android.uid.sytem。

#3


引用 1 楼 aihujianfei 的回复:
我也刚用了反射方法,调用screenshot,但是只是在个别的机子上可以用。


我的机器不可以使用,这是什么原因,是否是手机制造商封住了?
确认在个别机子上可以使用吗,那样也许还会有解决办法的

#4


既然再API里hide了而没有开放出来,说明google可能随时在后面版本的API里删掉这个方法。
你要看下不可以用的机器系统版本,API里应已经删掉了。
所以catch到NoSuchMethodException也是正常的,catch后换一种处理方式,这算是处理兼容了,不意外。

很多为了兼容会case不同的os版本写不同的代码,有时候这也是难免的。

最后也可能实在处理不了了,也要给个友好的提示,系统不支持之类的。e.printStackTrace()肯定不是解决之道。

#5


引用 4 楼 zyongsheng83 的回复:
既然再API里hide了而没有开放出来,说明google可能随时在后面版本的API里删掉这个方法。
你要看下不可以用的机器系统版本,API里应已经删掉了。
所以catch到NoSuchMethodException也是正常的,catch后换一种处理方式,这算是处理兼容了,不意外。

很多为了兼容会case不同的os版本写不同的代码,有时候这也是难免的。

最后也可能实在处理不了了,也要给个友好的提示,系统不支持之类的。e.printStackTrace()肯定不是解决之道。



我不认为会删掉,大量的底层都是hide的,应该是Google不想被调用,要删掉直接@Deprecated就好了。
确认手机版本是有这个方法的,因为安卓中uiautomator调用的就是这个方法,能正常执行。
你的建议也很好,以后会注意catch,谢谢。

#6


同求啊,刚有做了好几个反射调用,都不得行,都报这个异常

#7


遇到了同样的问题,怎么解决?

#8


同求解决方法

#9


多年后回来结贴,想想应该是系统权限问题,如果提高到系统权限应该就可以截图了,猜测

#1


我也刚用了反射方法,调用screenshot,但是只是在个别的机子上可以用。

#2


再补一句,而且,在Manifest文件中,要写 android.uid.sytem。

#3


引用 1 楼 aihujianfei 的回复:
我也刚用了反射方法,调用screenshot,但是只是在个别的机子上可以用。


我的机器不可以使用,这是什么原因,是否是手机制造商封住了?
确认在个别机子上可以使用吗,那样也许还会有解决办法的

#4


既然再API里hide了而没有开放出来,说明google可能随时在后面版本的API里删掉这个方法。
你要看下不可以用的机器系统版本,API里应已经删掉了。
所以catch到NoSuchMethodException也是正常的,catch后换一种处理方式,这算是处理兼容了,不意外。

很多为了兼容会case不同的os版本写不同的代码,有时候这也是难免的。

最后也可能实在处理不了了,也要给个友好的提示,系统不支持之类的。e.printStackTrace()肯定不是解决之道。

#5


引用 4 楼 zyongsheng83 的回复:
既然再API里hide了而没有开放出来,说明google可能随时在后面版本的API里删掉这个方法。
你要看下不可以用的机器系统版本,API里应已经删掉了。
所以catch到NoSuchMethodException也是正常的,catch后换一种处理方式,这算是处理兼容了,不意外。

很多为了兼容会case不同的os版本写不同的代码,有时候这也是难免的。

最后也可能实在处理不了了,也要给个友好的提示,系统不支持之类的。e.printStackTrace()肯定不是解决之道。



我不认为会删掉,大量的底层都是hide的,应该是Google不想被调用,要删掉直接@Deprecated就好了。
确认手机版本是有这个方法的,因为安卓中uiautomator调用的就是这个方法,能正常执行。
你的建议也很好,以后会注意catch,谢谢。

#6


同求啊,刚有做了好几个反射调用,都不得行,都报这个异常

#7


遇到了同样的问题,怎么解决?

#8


同求解决方法

#9


多年后回来结贴,想想应该是系统权限问题,如果提高到系统权限应该就可以截图了,猜测