我是靠谱客的博主 大力大树,最近开发中收集的这篇文章主要介绍android+桌面+同步+getscreenshot(),Android系统截屏的实现分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

(该图引自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) {

spdisplayToken = ibinderForJavaObject(env, displayTokenObj);

if (displayToken != NULL) {

spconsumer = 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) {

sps(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();

}

搬个源码做个笔记

再往下就是涉及底层buffer之类的处理了=。=

最后

以上就是大力大树为你收集整理的android+桌面+同步+getscreenshot(),Android系统截屏的实现分析的全部内容,希望文章能够帮你解决android+桌面+同步+getscreenshot(),Android系统截屏的实现分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(30)

评论列表共有 0 条评论

立即
投稿
返回
顶部