0

Я пытаюсь получить адрес электронной почты своего устройства, я использовал Java2OP для преобразования класса AccountManager в объект pascal. Тем не менее, я пытался получить адрес электронной почты, используя следующий код:Как получить адрес электронной почты устройства в Delphi 10

jAm: JAccountManager; 
accounts: TJavaObjectArray<JAccountClass>; 
jAcc: JAccountClass; 
begin 

    jAM := TJAccountManager.JavaClass.get(SharedActivityContext); 
    accounts := TJavaObjectArray<JAccountClass>.Wrap(jAM.getAccountsByType(StringToJString('com.google'))); 

    mmLog.Lines.Add('Length Accounts: ' + Inttostr(accounts.Length)); 

    if accounts.Length > 0 then begin 
    jAcc := accounts.Items[0]; 
    mmLog.Lines.Add(jstringtostring(jAcc.name)); 
    end else begin 
    mmLog.Lines.Add('no accounts available'); 
    end; 

Я получаю нарушение прав доступа по адресу 415E5254, доступ адрес 0000002C! любая идея?

JAccountClass = interface(JObjectClass) 
['{94EE6861-F326-489F-8919-E20B39E3D9C1}'] 
{class} function _GetCREATOR: JParcelable_Creator; cdecl; 
{class} function _Getname: JString; cdecl; 
{class} function _Gettype: JString; cdecl; 
{class} function init(name: JString; &type: JString): JAccount; cdecl; overload;//Deprecated 
{class} function init(init: JParcel): JAccount; cdecl; overload;//Deprecated 
{class} function describeContents: Integer; cdecl; 
{class} function equals(o: JObject): Boolean; cdecl; 
{class} property CREATOR: JParcelable_Creator read _GetCREATOR; 
{class} property name: JString read _Getname; 
{class} property &type: JString read _Gettype; 
end; 

    [JavaSignature('android/accounts/Account')] 
JAccount = interface(JObject) 
['{71476381-8B6E-471F-9189-9857ECD7508C}'] 
function hashCode: Integer; cdecl; 
function toString: JString; cdecl; 
procedure writeToParcel(dest: JParcel; flags: Integer); cdecl; 
end; 
TJAccount = class(TJavaGenericImport<JAccountClass, JAccount>) end; 

JAccountManagerClass = interface(JObjectClass) 
['{96273844-2D84-47F0-BFD5-14B73402F843}'] 
{class} function _GetACTION_AUTHENTICATOR_INTENT: JString; cdecl; 
{class} function _GetAUTHENTICATOR_ATTRIBUTES_NAME: JString; cdecl; 
{class} function _GetAUTHENTICATOR_META_DATA_NAME: JString; cdecl; 
{class} function _GetERROR_CODE_BAD_ARGUMENTS: Integer; cdecl; 
{class} function _GetERROR_CODE_BAD_AUTHENTICATION: Integer; cdecl; 
{class} function _GetERROR_CODE_BAD_REQUEST: Integer; cdecl; 
{class} function _GetERROR_CODE_CANCELED: Integer; cdecl; 
{class} function _GetERROR_CODE_INVALID_RESPONSE: Integer; cdecl; 
{class} function _GetERROR_CODE_NETWORK_ERROR: Integer; cdecl; 
{class} function _GetERROR_CODE_REMOTE_EXCEPTION: Integer; cdecl; 
{class} function _GetERROR_CODE_UNSUPPORTED_OPERATION: Integer; cdecl; 
{class} function _GetKEY_ACCOUNTS: JString; cdecl; 
{class} function _GetKEY_ACCOUNT_AUTHENTICATOR_RESPONSE: JString; cdecl; 
{class} function _GetKEY_ACCOUNT_MANAGER_RESPONSE: JString; cdecl; 
{class} function _GetKEY_ACCOUNT_NAME: JString; cdecl; 
{class} function _GetKEY_ACCOUNT_TYPE: JString; cdecl; 
{class} function _GetKEY_ANDROID_PACKAGE_NAME: JString; cdecl; 
{class} function _GetKEY_AUTHENTICATOR_TYPES: JString; cdecl; 
{class} function _GetKEY_AUTHTOKEN: JString; cdecl; 
{class} function _GetKEY_AUTH_FAILED_MESSAGE: JString; cdecl; 
{class} function _GetKEY_AUTH_TOKEN_LABEL: JString; cdecl; 
{class} function _GetKEY_BOOLEAN_RESULT: JString; cdecl; 
{class} function _GetKEY_CALLER_PID: JString; cdecl; 
{class} function _GetKEY_CALLER_UID: JString; cdecl; 
{class} function _GetKEY_ERROR_CODE: JString; cdecl; 
{class} function _GetKEY_ERROR_MESSAGE: JString; cdecl; 
{class} function _GetKEY_INTENT: JString; cdecl; 
{class} function _GetKEY_PASSWORD: JString; cdecl; 
{class} function _GetKEY_USERDATA: JString; cdecl; 
{class} function _GetLOGIN_ACCOUNTS_CHANGED_ACTION: JString; cdecl; 
{class} function addAccount(accountType: JString; authTokenType: JString; requiredFeatures: TJavaObjectArray<JString>; addAccountOptions: JBundle; activity: JActivity; callback: JAccountManagerCallback; handler: JHandler): JAccountManagerFuture; cdecl;//Deprecated 
{class} procedure clearPassword(account: JAccount); cdecl;//Deprecated 
{class} function confirmCredentials(account: JAccount; options: JBundle; activity: JActivity; callback: JAccountManagerCallback; handler: JHandler): JAccountManagerFuture; cdecl;//Deprecated 
{class} function editProperties(accountType: JString; activity: JActivity; callback: JAccountManagerCallback; handler: JHandler): JAccountManagerFuture; cdecl;//Deprecated 
{class} function get(context: JContext): JAccountManager; cdecl; 
{class} function getAccountsByTypeAndFeatures(&type: JString; features: TJavaObjectArray<JString>; callback: TJavaObjectArray<JAccountManagerCallback>; handler: JHandler): TJavaObjectArray<JAccountManagerFuture>; cdecl; 
{class} function getAccountsByTypeForPackage(&type: JString; packageName: JString): TJavaObjectArray<JAccount>; cdecl; 
{class} function getAuthToken(account: JAccount; authTokenType: JString; options: JBundle; activity: JActivity; callback: JAccountManagerCallback; handler: JHandler): JAccountManagerFuture; cdecl; overload; 
{class} function getAuthenticatorTypes: TJavaObjectArray<JAuthenticatorDescription>; cdecl; 
{class} function getPassword(account: JAccount): JString; cdecl; 
{class} function getUserData(account: JAccount; key: JString): JString; cdecl; 
{class} function newChooseAccountIntent(selectedAccount: JAccount; allowableAccounts: JArrayList; allowableAccountTypes: TJavaObjectArray<JString>; alwaysPromptForAccount: Boolean; descriptionOverrideText: JString; addAccountAuthTokenType: JString; addAccountRequiredFeatures: TJavaObjectArray<JString>; addAccountOptions: JBundle): JIntent; cdecl; 
{class} function peekAuthToken(account: JAccount; authTokenType: JString): JString; cdecl; 
{class} function removeAccount(account: JAccount; callback: JAccountManagerCallback; handler: JHandler): JAccountManagerFuture; cdecl; 
{class} procedure removeOnAccountsUpdatedListener(listener: JOnAccountsUpdateListener); cdecl; 
{class} function updateCredentials(account: JAccount; authTokenType: JString; options: JBundle; activity: JActivity; callback: JAccountManagerCallback; handler: JHandler): JAccountManagerFuture; cdecl; 
{class} property ACTION_AUTHENTICATOR_INTENT: JString read _GetACTION_AUTHENTICATOR_INTENT; 
{class} property AUTHENTICATOR_ATTRIBUTES_NAME: JString read _GetAUTHENTICATOR_ATTRIBUTES_NAME; 
{class} property AUTHENTICATOR_META_DATA_NAME: JString read _GetAUTHENTICATOR_META_DATA_NAME; 
{class} property ERROR_CODE_BAD_ARGUMENTS: Integer read _GetERROR_CODE_BAD_ARGUMENTS; 
{class} property ERROR_CODE_BAD_AUTHENTICATION: Integer read _GetERROR_CODE_BAD_AUTHENTICATION; 
{class} property ERROR_CODE_BAD_REQUEST: Integer read _GetERROR_CODE_BAD_REQUEST; 
{class} property ERROR_CODE_CANCELED: Integer read _GetERROR_CODE_CANCELED; 
{class} property ERROR_CODE_INVALID_RESPONSE: Integer read _GetERROR_CODE_INVALID_RESPONSE; 
{class} property ERROR_CODE_NETWORK_ERROR: Integer read _GetERROR_CODE_NETWORK_ERROR; 
{class} property ERROR_CODE_REMOTE_EXCEPTION: Integer read _GetERROR_CODE_REMOTE_EXCEPTION; 
{class} property ERROR_CODE_UNSUPPORTED_OPERATION: Integer read _GetERROR_CODE_UNSUPPORTED_OPERATION; 
{class} property KEY_ACCOUNTS: JString read _GetKEY_ACCOUNTS; 
{class} property KEY_ACCOUNT_AUTHENTICATOR_RESPONSE: JString read _GetKEY_ACCOUNT_AUTHENTICATOR_RESPONSE; 
{class} property KEY_ACCOUNT_MANAGER_RESPONSE: JString read _GetKEY_ACCOUNT_MANAGER_RESPONSE; 
{class} property KEY_ACCOUNT_NAME: JString read _GetKEY_ACCOUNT_NAME; 
{class} property KEY_ACCOUNT_TYPE: JString read _GetKEY_ACCOUNT_TYPE; 
{class} property KEY_ANDROID_PACKAGE_NAME: JString read _GetKEY_ANDROID_PACKAGE_NAME; 
{class} property KEY_AUTHENTICATOR_TYPES: JString read _GetKEY_AUTHENTICATOR_TYPES; 
{class} property KEY_AUTHTOKEN: JString read _GetKEY_AUTHTOKEN; 
{class} property KEY_AUTH_FAILED_MESSAGE: JString read _GetKEY_AUTH_FAILED_MESSAGE; 
{class} property KEY_AUTH_TOKEN_LABEL: JString read _GetKEY_AUTH_TOKEN_LABEL; 
{class} property KEY_BOOLEAN_RESULT: JString read _GetKEY_BOOLEAN_RESULT; 
{class} property KEY_CALLER_PID: JString read _GetKEY_CALLER_PID; 
{class} property KEY_CALLER_UID: JString read _GetKEY_CALLER_UID; 
{class} property KEY_ERROR_CODE: JString read _GetKEY_ERROR_CODE; 
{class} property KEY_ERROR_MESSAGE: JString read _GetKEY_ERROR_MESSAGE; 
{class} property KEY_INTENT: JString read _GetKEY_INTENT; 
{class} property KEY_PASSWORD: JString read _GetKEY_PASSWORD; 
{class} property KEY_USERDATA: JString read _GetKEY_USERDATA; 
{class} property LOGIN_ACCOUNTS_CHANGED_ACTION: JString read _GetLOGIN_ACCOUNTS_CHANGED_ACTION; 
end; 

[JavaSignature('android/accounts/AccountManager')] 
JAccountManager = interface(JObject) 
['{9FA4077B-4628-433C-BAFC-9EB299DA9C98}'] 
function addAccountExplicitly(account: JAccount; password: JString; userdata: JBundle): Boolean; cdecl;//Deprecated 
procedure addOnAccountsUpdatedListener(listener: JOnAccountsUpdateListener; handler: JHandler; updateImmediately: Boolean); cdecl;//Deprecated 
function blockingGetAuthToken(account: JAccount; authTokenType: JString; notifyAuthFailure: Boolean): JString; cdecl;//Deprecated 
function getAccounts: TJavaObjectArray<JAccount>; cdecl; 
function getAccountsByType(&type: JString): TJavaObjectArray<JAccount>; cdecl; 
function getAuthToken(account: JAccount; authTokenType: JString; notifyAuthFailure: Boolean; callback: JAccountManagerCallback; handler: JHandler): JAccountManagerFuture; cdecl; overload;//Deprecated 
function getAuthToken(account: JAccount; authTokenType: JString; options: JBundle; notifyAuthFailure: Boolean; callback: JAccountManagerCallback; handler: JHandler): JAccountManagerFuture; cdecl; overload; 
function getAuthTokenByFeatures(accountType: JString; authTokenType: JString; features: TJavaObjectArray<JString>; activity: JActivity; addAccountOptions: JBundle; getAuthTokenOptions: JBundle; callback: JAccountManagerCallback; handler: JHandler): JAccountManagerFuture; cdecl; 
function hasFeatures(account: JAccount; features: TJavaObjectArray<JString>; callback: JAccountManagerCallback; handler: JHandler): JAccountManagerFuture; cdecl; 
procedure invalidateAuthToken(accountType: JString; authToken: JString); cdecl; 
procedure setAuthToken(account: JAccount; authTokenType: JString; authToken: JString); cdecl; 
procedure setPassword(account: JAccount; password: JString); cdecl; 
procedure setUserData(account: JAccount; key: JString; value: JString); cdecl; 
end; 
TJAccountManager = class(TJavaGenericImport<JAccountManagerClass, JAccountManager>) end; 

Я добавить некоторые классы из AccountManager.pas, то JAccount класс не имеет Name свойство, оно находится в JAccountClass, но код работает, и я все еще получаю Ошибка нарушения доступа.

+1

это woul d помогите узнать, какая строка бросает нарушение доступа ... –

+0

может быть эта строка 'accounts: = TJavaObjectArray .Wrap (jAM.getAccountsByType (StringToJString ('com.google')));' или этот 'mmLog .Lines.Add (jstringtostring (jAcc.name)); ', я не могу скомпилировать без них. @J ... – ColdZer0

+0

... так как вы получили нарушение доступа, если оно не скомпилировано? Тебе не нужно угадывать здесь. Когда вы получаете нарушение доступа, переходите к отладчику и смотрите, на какую строку указывает указатель инструкции, - тогда скажите нам, что это за строка. –

ответ

1

копия {class} function _Getname: JString; cdecl; в JAccount класс, а затем использовать этот код:

var 
    jAm: JAccountManager; 
    accounts: TJavaObjectArray<JAccount>; 
    jAcc: JAccount; 
begin 
    jAM := TJAccountManager.JavaClass.get(SharedActivityContext); 
    if jAM <> nil then begin 
    accounts := TJavaObjectArray<JAccount>.Wrap(jAM.getAccountsByType(StringToJString('com.google'))); 
    if accounts <> nil then begin 
     mmLog.Lines.Add('Length Accounts: ' + IntToStr(accounts.Length)); 
     if accounts.Length > 0 then begin 
     jAcc := accounts.Items[0]; 
     mmLog.Lines.Add(JStringtoString(jAcc._Getname)); 
     end else begin 
     mmLog.Lines.Add('no accounts available'); 
     end; 
    end; 
    end else begin 
    mmLog.Lines.Add('no accounts found'); 
    end; 
end; 
+0

Благодаря Хелти и Реми – ColdZer0

1

Вы должны использовать свойство name объекта Account и не просить преобразовать объект в строку.

mmLog.Lines.Add(jstringtostring(jAcc.name)); 
+0

я получаю нарушение доступа по адресу 415E5254, обращаясь к адресу 0000002C! – ColdZer0

1

getAccountsByType() возвращает массив Account объектов, а не массив типов классов. И проверьте нулевые указатели.

Попробуйте вместо этого:

var 
    jAm: JAccountManager; 
    accounts: TJavaObjectArray<JAccount>; 
    jAcc: JAccount; 
begin 
    jAM := TJAccountManager.JavaClass.get(SharedActivityContext); 
    if jAM <> nil then begin 
    accounts := TJavaObjectArray<JAccount>.Wrap(jAM.getAccountsByType(StringToJString('com.google'))); 
    if accounts <> nil then begin 
     mmLog.Lines.Add('Length Accounts: ' + IntToStr(accounts.Length)); 
     if accounts.Length > 0 then begin 
     jAcc := accounts.Items[0]; 
     mmLog.Lines.Add(JStringtoString(jAcc.name)); 
     end else begin 
     mmLog.Lines.Add('no accounts available'); 
     end; 
    end; 
    end else begin 
    mmLog.Lines.Add('no accounts found'); 
    end; 
else begin 
    mmLog.Lines.Add('no account manager available'); 
end; 
+0

Большое спасибо за то, что я посмотрел на свой пост. Тем не менее, я все еще получил ошибку «Нарушение прав доступа» по адресу 415E5254, обратившись к адресу 0000002C! и к сожалению, я не могу отламываться отладчиком. @Remy Lebeau – ColdZer0

+0

Вам нужно отладить код. Если вы не можете использовать фактический отладчик, вам придется выводить все в журнал.В любом случае вам нужно проанализировать свои значения переменных. AV-адреса, расположенные рядом с адресом 0, обычно подразумевают, что к нему обращается нулевой указатель. –

+0

как вывести все в журнал?, Я выведу вывод здесь. У моего delphi10 есть проблемы с отладчиком в настоящее время !. Я добавил некоторые классы из AccountManager.pas, если это помогает matbe, спасибо. @Remy Lebeau – ColdZer0

1

Поскольку есть некоторые замечания по поводу вопросов, используя фрагменты кода, я думал, что это может быть полезно бросать полный блок (хотя и содержать минимальные определения импорта), чтобы попытаться устранить проблемы и путаницу.

Вот помощник блок, который работает в Delphi X Е8 до Delphi 10.1 Berlin (я не могу проверить более ранние версии, но в принципе это должно быть в порядке):

unit AccountEmailsU; 

interface 

function GetAccountEmails(const AccountType: String): TArray<String>; 

implementation 

uses 
    Androidapi.Helpers, 
    Androidapi.Jni, 
{$IF Declared(RTLVersion) and (RTLVersion >= 31)} 
    // Delphi 10.1 Berlin adds in full imports for the accounts classes 
    Androidapi.JNI.Accounts; 
{$ELSE} 
    Androidapi.JNIBridge, 
    Androidapi.JNI.App, 
    Androidapi.JNI.GraphicsContentViewText, 
    Androidapi.JNI.JavaTypes, 
    Androidapi.JNI.Os; 

type 
// ===== Forward declarations ===== 

    JAccount = interface;//android.accounts.Account 
    JAccountManager = interface;//android.accounts.AccountManager 

// ===== Interface declarations ===== 

    JAccountClass = interface(JObjectClass) 
    ['{94EE6861-F326-489F-8919-E20B39E3D9C1}'] 
    end; 

    [JavaSignature('android/accounts/Account')] 
    JAccount = interface(JObject) 
    ['{71476381-8B6E-471F-9189-9857ECD7508C}'] 
    function _Getname: JString; cdecl; 
    function _Gettype: JString; cdecl; 
    property name: JString read _Getname; 
    property &type: JString read _Gettype; 
    end; 
    TJAccount = class(TJavaGenericImport<JAccountClass, JAccount>) end; 

    JAccountManagerClass = interface(JObjectClass) 
    ['{96273844-2D84-47F0-BFD5-14B73402F843}'] 
    {class} function &get(context: JContext): JAccountManager; cdecl; 
    end; 

    [JavaSignature('android/accounts/AccountManager')] 
    JAccountManager = interface(JObject) 
    ['{9FA4077B-4628-433C-BAFC-9EB299DA9C98}'] 
    function getAccountsByType(type_: JString): TJavaObjectArray<JAccount>; cdecl; 
    end; 
    TJAccountManager = class(TJavaGenericImport<JAccountManagerClass, JAccountManager>) end; 
{$ENDIF} 

function GetAccountEmails(const AccountType: String): TArray<String>; 
var 
    AccountManager: JAccountManager; 
    Accounts: TJavaObjectArray<JAccount>; 
    Account: JAccount; 
    AccountLoopCounter: Integer; 
begin 
{$IF RTLVersion >= 30} 
    AccountManager := TJAccountManager.JavaClass.get(TAndroidHelper.Context); 
{$ELSE} 
    AccountManager := TJAccountManager.JavaClass.get(SharedActivityContext); 
{$ENDIF} 
    if AccountManager <> nil then 
    begin 
    Accounts := AccountManager.getAccountsByType(StringToJString(AccountType)); 
    if Accounts <> nil then 
    begin 
     SetLength(Result, Accounts.Length); 
     for AccountLoopCounter := 0 to Pred(Accounts.Length) do 
     begin 
     //Account := Accounts.Items[AccountLoopCounter]; 
     Account := TJAccount.Wrap(Accounts.GetRawItem(AccountLoopCounter)); 
     Result[AccountLoopCounter] := JStringtoString(Account.name); 
     end 
    end; 
    end; 
end; 

procedure RegisterTypes; 
begin 
    TRegTypes.RegisterType('AccountEmailsU.JAccount', TypeInfo(AccountEmailsU.JAccount)); 
    TRegTypes.RegisterType('AccountEmailsU.JAccountManager', TypeInfo(AccountEmailsU.JAccountManager)); 
end; 

initialization 
    RegisterTypes; 
end. 

Это может быть использовано в мода сродни этому:

uses 
{$IF RTLVersion >= 31} 
    FMX.DialogService, 
//{$ELSE} 
// FMX.Dialogs, 
{$ENDIF} 
    AccountEmailsU, 
    MiscU; 

procedure TForm1.btnGetAccountEmailsClick(Sender: TObject); 
const 
    AccountType = 'com.google'; 
var 
    AccountNames: TArray<String>; 
    AccountLoopCounter: Integer; 
begin 
    if not HasPermission('android.permission.GET_ACCOUNTS') then 
{$IF RTLVersion >= 31} 
    TDialogService.MessageDialog('App does not have the GET_ACCOUNTS permission', 
     TMsgDlgType.mtError, [TMsgDlgBtn.mbCancel], TMsgDlgBtn.mbCancel, 0, nil) 
{$ELSE} 
    MessageDlg('App does not have the GET_ACCOUNTS permission', 
     TMsgDlgType.mtError, [TMsgDlgBtn.mbCancel], 0) 
{$ENDIF} 
    else 
    begin 
    AccountNames := GetAccountEmails(AccountType); 
    AccountsListBox.Items.Clear; 
    for AccountLoopCounter := Low(AccountNames) to High(AccountNames) do 
     AccountsListBox.Items.Add(AccountNames[AccountLoopCounter]) 
    end; 
end; 

разрешения проверки кода происходит от этого хелперов блока:

unit MiscU; 

interface 

function HasPermission(const Permission: string): Boolean; 

implementation 

uses 
    FMX.Helpers.Android, 
    Androidapi.Helpers, 
    Androidapi.JNI.JavaTypes, 
    Androidapi.JNI.GraphicsContentViewText; 

function HasPermission(const Permission: string): Boolean; 
begin 
    //Permissions listed at http://d.android.com/reference/android/Manifest.permission.html 
{$IF RTLVersion >= 30} 
    Result := TAndroidHelper.Context.checkCallingOrSelfPermission(
{$ELSE} 
    Result := SharedActivityContext.checkCallingOrSelfPermission(
{$ENDIF} 
    StringToJString(Permission)) = 
    TJPackageManager.JavaClass.PERMISSION_GRANTED 
end; 

end. 
Смежные вопросы