android 操作屏幕需要什么权限
4个回答
展开全部
一般最开始的 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 。
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 。
展开全部
root权限,或者设备管理授权
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
什么都不用,只是在桌面。设置那里
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询