android系统截屏功能吗,Android系统截屏的实现分析

先来看看别个总结的流程(自己本来想画个,发现找到个就不造车了)

0818b9ca8b590ca3270a3433284dd417.png

(该图引自http://blog.csdn.net/hk_256/article/details/7306590)

源码部分

喔  对鸟,这个是5.1的代码,kk的没有研究过,想必也差不多

interceptKeyBeforeQueueing()拦截按键信息

interceptScreenshotChord():handler调用截屏

private void interceptScreenshotChord() {

if (mScreenshotChordEnabled

&& mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered

&& !mScreenshotChordVolumeUpKeyTriggered) {

final long now = SystemClock.uptimeMillis();

if (now <= mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS

&& now <= mScreenshotChordPowerKeyTime

+ SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {

mScreenshotChordVolumeDownKeyConsumed = true;

cancelPendingPowerKeyAction();

mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay());

}

}

}

private final Runnable mScreenshotRunnable = new Runnable() {

@Override

public void run() {

takeScreenshot();

}

};

private void takeScreenshot() {

synchronized (mScreenshotLock) {

if (mScreenshotConnection != null) {

return;

}

ComponentName cn = new ComponentName("com.android.systemui",

"com.android.systemui.screenshot.TakeScreenshotService");//实际上是通过启动systemui的TakeScreenshotServiceservice来实现

Intent intent = new Intent();

intent.setComponent(cn);

ServiceConnection conn = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

synchronized (mScreenshotLock) {

if (mScreenshotConnection != this) {

return;

}

Messenger messenger = new Messenger(service);

Message msg = Message.obtain(null, 1);

final ServiceConnection myConn = this;

Handler h = new Handler(mHandler.getLooper()) {

@Override

public void handleMessage(Message msg) {

synchronized (mScreenshotLock) {

if (mScreenshotConnection == myConn) {

mContext.unbindService(mScreenshotConnection);

mScreenshotConnection = null;

mHandler.removeCallbacks(mScreenshotTimeout);

}

}

}

};

msg.replyTo = new Messenger(h);

msg.arg1 = msg.arg2 = 0;

if (mStatusBar != null && mStatusBar.isVisibleLw())

msg.arg1 = 1;

if (mNavigationBar != null && mNavigationBar.isVisibleLw())

msg.arg2 = 1;

try {

messenger.send(msg);

} catch (RemoteException e) {

}

}

}

@Override

public void onServiceDisconnected(ComponentName name) {}

};

if (mContext.bindServiceAsUser(

intent, conn, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {

mScreenshotConnection = conn;

mHandler.postDelayed(mScreenshotTimeout, 10000);

}

}

}

public class TakeScreenshotService extends Service {

private static final String TAG = "TakeScreenshotService";

private static GlobalScreenshot mScreenshot;

private Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case 1:

final Messenger callback = msg.replyTo;

if (mScreenshot == null) {

mScreenshot = new GlobalScreenshot(TakeScreenshotService.this);

}

mScreenshot.takeScreenshot(new Runnable() {

@Override public void run() {

Message reply = Message.obtain(null, 1);

try {

callback.send(reply);

} catch (RemoteException e) {

}

}

}, msg.arg1 > 0, msg.arg2 > 0);//这个方法执行截屏,以及window的ui效果等

}

}

};

@Override

public IBinder onBind(Intent intent) {

return new Messenger(mHandler).getBinder();

}

}

在SurfaceControl类中,在这儿调用底层nativeScreenshot方法截屏

/**

* Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but

* with builtInDisplayId in the screenshot.

*

* @param width The desired width of the returned bitmap; the raw

* screen will be scaled down to this size.

* @param height The desired height of the returned bitmap; the raw

* screen will be scaled down to this size.

* @param builtInDisplayId The Built-in physical display id.

* @return Returns a Bitmap containing the screen contents, or null

* if an error occurs. Make sure to call Bitmap.recycle() as soon as

* possible, once its content is not needed anymore.

*

* @hide

*/

public static Bitmap screenshot(int width, int height, int builtInDisplayId) {

IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId);

Log.d(TAG, "screenshot, builtInDisplayId = " + builtInDisplayId);

return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,

false, Surface.ROTATION_0);

}

再找到对应的jni

static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj,

jobject surfaceObj, jobject sourceCropObj, jint width, jint height,

jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {

sp displayToken = ibinderForJavaObject(env, displayTokenObj);

if (displayToken != NULL) {

sp consumer = android_view_Surface_getSurface(env, surfaceObj);

if (consumer != NULL) {

int left = env->GetIntField(sourceCropObj, gRectClassInfo.left);

int top = env->GetIntField(sourceCropObj, gRectClassInfo.top);

int right = env->GetIntField(sourceCropObj, gRectClassInfo.right);

int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom);

Rect sourceCrop(left, top, right, bottom);

if (allLayers) {

minLayer = 0;

maxLayer = -1;

}

ScreenshotClient::capture(displayToken,

consumer->getIGraphicBufferProducer(), sourceCrop,

width, height, uint32_t(minLayer), uint32_t(maxLayer),

useIdentityTransform);

}

}

}

再往下

status_t ScreenshotClient::capture(

const sp& display,

const sp& producer,

Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,

uint32_t minLayerZ, uint32_t maxLayerZ, bool useIdentityTransform) {

sp s(ComposerService::getComposerService());

if (s == NULL) return NO_INIT;

return s->captureScreen(display, producer, sourceCrop,

reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);

}

再找找

virtual status_t captureScreen(const sp& display,

const sp& producer,

Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,

uint32_t minLayerZ, uint32_t maxLayerZ,

bool useIdentityTransform,

ISurfaceComposer::Rotation rotation)

{

Parcel data, reply;

data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());

data.writeStrongBinder(display);

data.writeStrongBinder(producer->asBinder());

data.write(sourceCrop);

data.writeInt32(reqWidth);

data.writeInt32(reqHeight);

data.writeInt32(minLayerZ);

data.writeInt32(maxLayerZ);

data.writeInt32(static_cast(useIdentityTransform));

data.writeInt32(static_cast(rotation));

remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);

return reply.readInt32();

}

再往下就不怎么看得懂了=。=   简直是作

只是搬个源码做个笔记,涉及c的就模糊了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值