永发信息网

安卓怎么用root权限调用surfacecontrol.screenshot函数

答案:1  悬赏:0  手机版
解决时间 2021-02-12 12:06
安卓怎么用root权限调用surfacecontrol.screenshot函数
最佳答案
一般最开始的 Android 截屏程序,都是来源于 Linux 的截屏方法,android 使用的 Linux 内核,那么 Linux 下的截屏方法也就最先被 android 采用。Linux 使用了 framebuffer 管理显示输出,传统的办法就是读取 framebuffer 的数据,然后得到整个屏幕的数据。此方法在 Android3.0 版本之前是也唯一可行的方法。 然而 linux 采用了严格的权限控制 设备文件,framebuffer 也是其控制之一,在 Android 中只有 root , 和 graphic 组用户才有权限读取:

ls -l /dev/graphics/fb0
crw-rw---- root graphics 29, 0 2015-01-16 03:26 fb0

所以要采用读取 framebuffer 的方式实现截屏,应用必须获得 root 权限。

随着 Android 显示系统的变迁,自 Android 4.2 开始, Android 自己增加截屏接口,而且更多的设备采用了多个 framebuffer 使用 overlay 的方式,更有采用硬件 composer 的设备,使得单独读取 framebuffer 并不能截取到,一个完整的屏幕。于是这个方法也渐渐被开发者抛弃。

Android 截屏 -- SurfaceFlinger
在 Android 4.0 里,显示系统采用了新的构架,加入“黄油计划”,同时也添加截屏接口:

status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
sp<IMemoryHeap>* heap,
uint32_t* width, uint32_t* height, PixelFormat* format,
uint32_t sw, uint32_t sh,
uint32_t minLayerZ, uint32_t maxLayerZ)
{
if (CC_UNLIKELY(display == 0))
return BAD_VALUE;

if (!GLExtensions::getInstance().haveFramebufferObject())
return INVALID_OPERATION;

class MessageCaptureScreen : public MessageBase {
SurfaceFlinger* flinger;
sp<IBinder> display;
sp<IMemoryHeap>* heap;
uint32_t* w;
uint32_t* h;
PixelFormat* f;
uint32_t sw;
uint32_t sh;
uint32_t minLayerZ;
uint32_t maxLayerZ;
status_t result;
public:
MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display,
sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
uint32_t sw, uint32_t sh,
uint32_t minLayerZ, uint32_t maxLayerZ)
: flinger(flinger), display(display),
heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
result(PERMISSION_DENIED)
{
}
status_t getResult() const {
return result;
}
virtual bool handler() {
Mutex::Autolock _l(flinger->mStateLock);
result = flinger->captureScreenImplLocked(display,
heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
return true;
}
};

sp<MessageBase> msg = new MessageCaptureScreen(this,
display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
status_t res = postMessageSync(msg);
if (res == NO_ERROR) {
res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
}
return res;
}

现在应用可以调用系统接口来截屏,最好的例子就是 screencap : frameworks/base/cmds/screencap/screencap.cpp

然而,系统依然出于安全的考虑,对权限的控制依然严格:使用系统截屏接口需要 READ_FRAMEBUFFER 权限:

case CAPTURE_SCREEN:
{
// codes that require permission check
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
const int uid = ipc->getCallingUid();
if ((uid != AID_GRAPHICS) &&
!PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
ALOGE("Permission Denial: "
"can't read framebuffer pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;
}
break;
}

而且 READ_FRAMEBUFFER 属于 system 级别的权限,非系统应用无法获得,所以在应用程序中声明了使用这个权限,应用程序如果不是 system 程序,依然没有权限。第三方程序要能截屏成功还是需要 root 。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
求CF安装软件(应用程序),不是下载的网址,
炫姿彩妆培训地址好找么,我有些事要过去
如何加强对制造计量器具企业的监管力度
【爱的轮回】爱的轮回作文
灵宝市依法治市工作领导小组办公室地址在什么
永庆艺馨舞蹈学校果都分校地址有知道的么?有
形容要求迫切是什么词语最好是成语
持有电焊操作证可以办职工养老保险吗
荷塘月色 故都的秋 囚绿记的比较三篇课文做下
N多寿司(上悦城店)地址在哪,我要去那里办事
海贼王145集里的怪物
数字新泰地址好找么,我有些事要过去
北京喜来登美容美发院在哪里啊,我有事要去这
城阳托管地址在哪,我要去那里办事
青岛家佳康医药连锁有限公司第7药店地址在什
推荐资讯
果麦NO.1007怎么去啊,有知道地址的么
什么是车档?
我是白户,谁能帮我贷款,要前期费用的免谈
化学氧气的符号是什么?
昂达 MDA785G+/128M 主板加内存 4GB ( 威
停车场(新城嘉园南区东南)地址好找么,我有些
落红村在哪里啊,我有事要去这个地方
广西北流市社会体育指导中心地址在哪,我要去
测量学求高程
花颜美业美容美体工作室怎么去啊,我要去那办
快手里那些女孩拿一根杆子拍视频是什么意思
我的孩子是虎年公历1月生的,帮忙取一个名字,
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?