android 的application 都是有窗口系统的,会把各种事件给阻拦掉.但是,用c++写的程序是直接在linux上运行的,并没有窗口这一概念,所以可以向鼠标一样,只绘制图像而不响应任何窗口时间.
具体实现是通过SurfaceComposerClient,这个类相当于surfaceflinger的代理,可以创建一个显示图像的surface.
注意,不同系统的接口可能不一样.若有问题,可以参考一下本系统中frameworks/base/service/input/SpriteController.cpp中的doUpdateSprites()函数.这个函数是显示鼠标的最主核心的函数.
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include 15 16 #define LOG_TAG "zhy"17 18 using namespace android;19 int main()20 {21 SkBitmap bitmap;22 SkImageDecoder::DecodeFile("/system/data/test.png", &bitmap);23 sp pSurfaceComposerClient = new SurfaceComposerClient();24 int32_t width = bitmap.height();25 int32_t height = bitmap.width();26 ALOGI("width= %d \n", width);27 ALOGI("height= %d \n", height);28 sp surfaceControl = pSurfaceComposerClient->createSurface(29 String8("test"), width, height, PIXEL_FORMAT_RGBA_8888,30 ISurfaceComposerClient::eHidden);31 32 if (surfaceControl == NULL || !surfaceControl->isValid()) {33 ALOGE("Error creating sprite surface.");34 return -1;35 }36 sp surface = surfaceControl->getSurface();37 ANativeWindow_Buffer outBuffer;38 status_t status = surface->lock(&outBuffer, NULL);39 if (status) {40 ALOGE("Error %d locking sprite surface before drawing.", status);41 } else {42 SkBitmap surfaceBitmap;43 ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);44 surfaceBitmap.setConfig(SkBitmap::kARGB_8888_Config,45 outBuffer.width, outBuffer.height, bpr);46 surfaceBitmap.setPixels(outBuffer.bits);47 SkCanvas surfaceCanvas(surfaceBitmap);48 SkPaint paint;49 paint.setXfermodeMode(SkXfermode::kSrc_Mode);50 surfaceCanvas.drawBitmap(bitmap, 0, 0, &paint);51 if (outBuffer.width > uint32_t(bitmap.width())) {52 paint.setColor(0); // transparent fill color53 surfaceCanvas.drawRectCoords(bitmap.width(), 0,54 outBuffer.width, bitmap.height(), paint);55 }56 if (outBuffer.height > uint32_t(bitmap.height())) {57 paint.setColor(0); // transparent fill color58 surfaceCanvas.drawRectCoords(0, bitmap.height(),59 outBuffer.width, outBuffer.height, paint);60 }61 status = surface->unlockAndPost();62 if (status) {63 ALOGE("Error %d unlocking and posting sprite surface after drawing.", status);64 }65 }66 67 int x = 0, y = 0;68 SurfaceComposerClient::openGlobalTransaction();69 //surfaceControl->setAlpha(1.0f);70 surfaceControl->setLayer(100000);71 //surfaceControl->setMatrix(1.0, 1.0, 1.0, 1.0);72 SurfaceComposerClient::closeGlobalTransaction();73 while(true){74 ALOGI("openGlobalTransaction \n");75 SurfaceComposerClient::openGlobalTransaction();76 surfaceControl->setPosition(x, y);77 x = (x+10) %1920;78 y = (y+10) %1280;79 static bool isShow = false;80 if(!isShow){81 surfaceControl->show();82 isShow = true;83 }84 ALOGI("closeGlobalTransaction \n");85 SurfaceComposerClient::closeGlobalTransaction();86 sleep(1);87 88 }89 return 0;90 }