我是基于android2.3.3系统之上的,想必大家应该知道在android源码下面有个文件叫做screencap吧,位于frameworksaseservicessurfaceflinger estsscreencapscreencap.cpp,你直接在linux下编译(保存在 /system/bin/test-screencap),然后push到手机上再通过电脑去敲命令test-screencap /mnt/sdcard/scapxx.png就可以实现截屏。 复制代码 代码如下: /* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
编译:编译是个很伟大的工程,需要你花大量的时间与精力。直接在终端进入工程存放的所在位置,我的是Administrator/Android.2.3.3/development,然后mm(Builds all of the modules in the current directory),如果成功,那么你运气比较好,在终端回提示你APK保存的位置。push进手机试一试。但是往往是不成功的。你可能会遇到一些问题,比如android.permission.ACCESS_SURFACE_FLINGER ,android.permission.READ_FRAME_BUFFER(因为capturescrren这个函数是surfaceflinger里面的函数,然而surfaceflinger里面的opengl截屏函数会去读取framebuffer),相关源代码是: 复制代码 代码如下: status_t SurfaceFlinger::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
switch (code) { case CREATE_CONNECTION: case OPEN_GLOBAL_TRANSACTION: case CLOSE_GLOBAL_TRANSACTION: case SET_ORIENTATION: case FREEZE_DISPLAY: case UNFREEZE_DISPLAY: case BOOT_FINISHED: case TURN_ELECTRON_BEAM_OFF: case TURN_ELECTRON_BEAM_ON: { // codes that require permission check IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid(); if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) { LOGE("Permission Denial: " "can"t access SurfaceFlinger pid=%d, uid=%d", pid, uid); return PERMISSION_DENIED; } break; } 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) && !mReadFramebuffer.check(pid, uid)) {
status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { CHECK_INTERFACE(ISurfaceComposer, data, reply); if (UNLIKELY(!mHardwareTest.checkCalling())) { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid();
LOGI("err"); LOGE("Permission Denial: " "can"t access SurfaceFlinger pid=%d, uid=%d", pid, uid); return PERMISSION_DENIED; } int n; switch (code) { case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE return NO_ERROR; case 1002: // SHOW_UPDATES n = data.readInt32(); mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); return NO_ERROR; case 1003: // SHOW_BACKGROUND n = data.readInt32(); mDebugBackground = n ? 1 : 0; return NO_ERROR; case 1004:{ // repaint everything Mutex::Autolock _l(mStateLock); const DisplayHardware& hw(graphicPlane(0).displayHardware()); mDirtyRegion.set(hw.bounds()); // careful that"s not thread-safe signalEvent(); return NO_ERROR; } case 1005:{ // force transaction setTransactionFlags(eTransactionNeeded|eTraversalNeeded); return NO_ERROR; } case 1006:{ // enable/disable GraphicLog int enabled = data.readInt32(); GraphicLog::getInstance().setEnabled(enabled); return NO_ERROR; } case 1007: // set mFreezeCount mFreezeCount = data.readInt32(); mFreezeDisplayTime = 0; return NO_ERROR; case 1010: // interrogate. reply->writeInt32(0); reply->writeInt32(0); reply->writeInt32(mDebugRegion); reply->writeInt32(mDebugBackground); return NO_ERROR; case 1013: { Mutex::Autolock _l(mStateLock); const DisplayHardware& hw(graphicPlane(0).displayHardware()); reply->writeInt32(hw.getPageFlipCount()); } return NO_ERROR; } } return err; }
这个仅仅只是开始! 你会发现你即使在xml里面添加相应的权限仍然会有这个问题出现,为什么呢?在packageManger文件里面发现相关代码: 复制代码 代码如下: int checkSignaturesLP(Signature[] s1, Signature[] s2) { if (s1 == null) { return s2 == null ? PackageManager.SIGNATURE_NEITHER_SIGNED : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; } if (s2 == null) { return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; } HashSet<Signature> set1 = new HashSet<Signature>(); for (Signature sig : s1) { set1.add(sig); } HashSet<Signature> set2 = new HashSet<Signature>(); for (Signature sig : s2) { set2.add(sig); } // Make sure s2 contains all signatures in s1. if (set1.equals(set2)) { return PackageManager.SIGNATURE_MATCH; } return PackageManager.SIGNATURE_NO_MATCH; }
// Check for shared user signatures if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { Slog.e(TAG, "Package " + pkg.packageName + " has no signatures that match those in shared user " + pkgSetting.sharedUser.name + "; ignoring!"); mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; return false; } } return true;
// Check for shared user signatures if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
Slog.e(TAG, "Package " + pkg.packageName + " has no signatures that match those in shared user " + pkgSetting.sharedUser.name + "; ignoring!"); mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; return false;