Я написал что-то с Delphi для тестирования Android MediaProjection API.(https://developer.android.com/reference/android/media/projection/MediaProjection)
Я попытался преобразовать некоторые из кодов Java в Delphi.
java пример: https://github.com/mtsahakis/MediaProjectionDemo/blob/master/src/com/mtsahakis/mediaprojectiondemo/ScreenCaptureImageActivity.java
Когда вы нажимаете кнопку, она попросит авторизовать пользователя для захвата экрана.
Когда пользователь примет, он зарегистрирует одну процедуру в медиапроекции api.
Поэтому, когда экран изменился, API вызовет нашу процедуру с данными изображения, и мы покажем любой текст на экране для тестирования.
Я проверил мой код ниже.
Когда вы принимаете экран с запросом разрешения, приложение закрывается и мгновенно закрывается.
На Android 8.1:
поднял класс исключений Ошибка сенментации (11) ----> Система --->процедура _InstCopy () ----> Source .__ ObjAddRef
или
с повышенным классом исключений Недопустимая инструкция (4) ----> System.Internal.Excutils.SignalConverter
На Android 6.0:
поднял класс исключений EInvalidCast с сообщением «Тип неверного типа» ----> System.Rtti ---> System._DbgExcNotify
unit frmuMediaProjectionTest;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls,
System.Messaging, Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNI.Media, Androidapi.JNIBridge;
type
TonImageAvailable = procedure (reader: JImageReader) of object;
TImageAvailableListener = class( TJavaLocal, JImageReader_OnImageAvailableListener )
private
FonImageAvailable: TonImageAvailable;
public
procedure onImageAvailable(reader: JImageReader);cdecl;
property onIAvailable: TonImageAvailable read FonImageAvailable write FonImageAvailable;
end;
TfrmMediaProjectionTest = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
MPManager: JMediaProjectionManager;
FMessageSubscriptionID: integer;
procedure HandleActivityMessage(const Sender: TObject; const M: TMessage);
function OnActivityResult(RequestCode, ResultCode: Integer; Data: JIntent): Boolean;
procedure onImageAvailable(reader: JImageReader);
public
end;
var
frmMediaProjectionTest: TfrmMediaProjectionTest;
implementation
{$R *.fmx}
Uses //Androidapi.JNI.Media,
AndroidApi.Jni.JavaTypes,
Androidapi.Helpers,
//Androidapi.JNI.GRaphicsContentViewText,
//Androidapi.JNIBridge,
Androidapi.JNI.os,
Androidapi.JNI.App;
procedure TfrmMediaProjectionTest.FormCreate(Sender: TObject);
begin
MPManager := nil;
end;
procedure TfrmMediaProjectionTest.Button1Click(Sender: TObject);
var MPObj: JObject;
begin
FMessageSubscriptionID := TMessageManager.DefaultManager.SubscribeToMessage( TMessageResultNotification, HandleActivityMessage );
MPObj := TAndroidHelper.Context.getSystemService( TJContext.JavaClass.MEDIA_PROJECTION_SERVICE );
MPManager := TJMediaProjectionManager.Wrap( ( MPObj as ILocalObject ).GetObjectID );
TAndroidHelper.Activity.startActivityForResult( MPManager.createScreenCaptureIntent, 100 );
end;
procedure TfrmMediaProjectionTest.HandleActivityMessage(const Sender: TObject; const M: TMessage);
begin
if M is TMessageResultNotification then
OnActivityResult( TMessageResultNotification( M ).RequestCode, TMessageResultNotification( M ).ResultCode,
TMessageResultNotification( M ).Value );
end;
//ResultCode: iptal: 0 kabul: -1
function TfrmMediaProjectionTest.OnActivityResult( RequestCode, ResultCode: Integer; Data: JIntent ): Boolean;
const RGBA_8888: integer = 1;
mDencity: integer = 160;
VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY: integer = 8;
VIRTUAL_DISPLAY_FLAG_PUBLIC: integer = 1;
var mp: JMediaProjection;
imageReader: JImageReader;
handler: JHandler;
ImageAvailableListener: TImageAvailableListener;
begin
TMessageManager.DefaultManager.Unsubscribe( TMessageResultNotification, FMessageSubscriptionID );
if ResultCode = -1 then
begin
mp := MpManager.getMediaProjection( ResultCode, Data );
if mp <> nil then
begin
imageReader := TJImageReader.JavaClass.newInstance( screen.Width, screen.Height, RGBA_8888, 2 );
handler := TJHandler.JavaClass.init();
mp.createVirtualDisplay( StringToJString( 'Test' ), screen.Width, screen.Height, mDencity,
VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY or VIRTUAL_DISPLAY_FLAG_PUBLIC,
imageReader.getSurface, nil, handler );
ImageAvailableListener := TImageAvailableListener.Create;
ImageAvailableListener.onIAvailable := onImageAvailable;
imageReader.setOnImageAvailableListener( ImageAvailableListener, handler );
end;
end
else
if ResultCode = 0 then showmessage( 'Canceled' );
result := true;
end;
procedure TfrmMediaProjectionTest.onImageAvailable(reader: JImageReader);
begin
Label1.Text := 'Called from api';
end;
{ TImageAvailableListener }
procedure TImageAvailableListener.onImageAvailable(reader: JImageReader);cdecl;
begin
if assigned( FonImageAvailable ) then
begin
FonImageAvailable( reader );
end;
end;
end.