Ссылки на общий каталог этой серии статей и введение в каждую часть: Android Qcom Display Learning (Zero)
Простой способ
Принцип реализации скриншота кнопки, через PhoneWindowManager.java -> DisplayPolicy.java -> ScreenshotHelper.java, много описаний в интернете не развернется
adb shell input keyevent KEYCODE_SYSRQ
/frameworks/base/cmds/screencap/screencap.cpp На самом деле это то, о чем мы упоминали ранее в разделе «Слои», вызывая GPU для синтеза всех изображений.
adb shell
screencap /sdcard/screen.png
Выполнение
frameworks/base/core/java/com/android/internal/util/ScreenshotHelper.java
frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java —
самая простая демонстрация в системе, вызывающей это метод в apk - это просто попытка обучения.Новичок в фреймворке
на самом деле является bindService TakeScreenshotService и затем устанавливает соединение onServiceConnected, а затем отправляет его в TakeScreenshotService через send(msg), чтобы вызвать функцию скриншота и анимацию после скриншота. Обратите внимание, что сообщение должно быть передано при передаче параметров. Вам нужно принести msg.obj, потому что TakeScreenshotService вызовет getTopComponent() в ScreenshotHelper.ScreenshotRequest, когда вы снова обработаете сообщение. Если параметр не передан, это будет нулевой указатель и сообщить об ошибке напрямую.
import com.android.internal.util.ScreenshotHelper;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.os.Looper;
import android.os.Handler;
import android.os.UserHandle;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.ComponentName;
private void takeScreenshot(){
ComponentName cn = new ComponentName("com.android.systemui",
"com.android.systemui.screenshot.TakeScreenshotService");
Intent intent = new Intent();
intent.setComponent(cn);
Log.e(TAG, "jerry triggger takeScreenshot");
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name,
IBinder service) {
if (mScreenshotConnection != this) {
return;
}
Messenger messenger = new Messenger(service);
int TAKE_SCREENSHOT_FULLSCREEN = 1;
int mScreenshotType = TAKE_SCREENSHOT_FULLSCREEN;
Message msg = Message.obtain(null, mScreenshotType);
int SCREENSHOT_OTHER = 5;
boolean hasStatus = true;
boolean hasNav = true;
//ScreenshotHelper.ScreenshotRequest screenrequest = new ScreenshotHelper.ScreenshotRequest(
// SCREENSHOT_OTHER, hasStatus, hasNav);
ScreenshotHelper screen = new ScreenshotHelper(mContext);
ScreenshotHelper.ScreenshotRequest screenrequest = screen.newobject();
final ServiceConnection myConn = this;
Handler h = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
}
};
msg.obj = screenrequest;
msg.replyTo = new Messenger(h);
msg.arg1 = msg.arg2 = 0;
try {
messenger.send(msg);
} catch (RemoteException e) {
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
if (mScreenshotConnection != null) {
unbindService(mScreenshotConnection);
mScreenshotConnection = null;
}
}
};
bindServiceAsUser(intent, conn, BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE,
UserHandle.CURRENT);
mScreenshotConnection = conn;
}
Внутренний статический класс сообщает об ошибке отсутствия конструкции, и причина не может быть найдена, ошибка: не найден подходящий конструктор для ScreenshotRequest(int, boolean, boolean) ScreenshotHelper.ScreenshotRequest screenrequest = new ScreenshotHelper.ScreenshotRequest(SCREENSHOT_OTHER, hasStatus,
hasNav ); Сначала напишите интерфейс для возврата нового объекта,
frameworks/base/core/java/com/android/internal/util/ScreenshotHelper.java
public ScreenshotRequest newobject(){
ScreenshotRequest screenshot = new ScreenshotRequest(SCREENSHOT_OTHER, true, true);
return screenshot;
}