Перейти к содержанию
Fire Monkey от А до Я

Tot999

Пользователи
  • Постов

    9
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные Tot999

  1. Насколько помню по своей возне четырёхлетней давности с тогдашним Rad Studio. Проблема перезаписи БД из Deployment решалась постоянным увеличением версии программы, т.е. перед запуском на тест уcтройстве, надо заходить в настройки проекта и менять Version. Как сейчас обстоят дела - хз.

  2. Добрый день!

    Обратил внимание, что большинство негативных оценок приложению ставят, с отзывом "приложение не запустилось" (обычно с матом :) ). Начинаю смотреть устройства, от Xiaomi много колов стоит:

    Xiaomi Redmi 5A (riva) - "игра даже не открылась".

    Android 7.1, проц: Qualcomm Snapdragon 425 MSM8917, арх: ARMv8

    При этом вижу оценку 4 от Xiaomi Redmi Note 4 (nikel) 

    Android 6, проц: Qualcomm Snapdragon 625 MSM8953 Android 6.0, арх: ARMv8

     Читаю http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Supported_Target_Platforms

    Да, там в табличке нет стоит Андроид 7, 8, про 7.1 ничего нет, но от устройств с Андроид 7.1 есть оценки 5. 

    На каких-то достаточно мощных устройствах пишут, что жутко тормозит.

    К чему веду: не могу понять по какому принципу ограничивать список поддерживаемых устройств в консоли гугл. Сейчас выставлено (автоматически, я ничего нигде не менял)  10690 из 13391.  Как правильно ограничения, чтобы было не поштучно. Если выбрать только девайсы с процом Cortex-A выдаёт 10242 устройств, остальное всё надо добавить в исключенные? Что еще следует фильтровать?

     

     

     

  3. Добрый день! 

    Решил покопаться в своей старой спрайтовой игрушке, чтобы освежить в памяти знания и состряпать что-нибудь новое. Возникли сомнения, нормально ли сделано графическое отображение, можно ли доработать.

    Все спрайты в дизайнтайме распиханы по Timagelist-ам.  На старте приложения я загружаю битмапы из имэджлистов в свои обджектлисты, подгоняя под нужный размер. 

    MeduzasBitmpAr : array [1..numofMeduzas] of TObjectList<Tbitmap>;

     

    Спойлер


    
    //загрузка медуз
      for i := 1 to numofMeduzas do begin
         MeduzasBitmpAr[i]:=  TObjectList<Tbitmap>.create;
    
          for k := 0 to TImageList(FindComponent('ImageListMedusa'+inttostr(i))).Count-1 do begin
           LoadedBitmap := tbitmap.Create;
    
           cx:=  settings.standartx* Power(settings.xprop, i);
           cy:=  settings.standarty* Power(settings.yprop, i);
    
           arectf.Top:= 0 ;
           arectf.left:= 0 ;
           arectf.width:= cx ;
           arectf.height:= cy ;
    
           LoadedBitmap.Assign(TImageList(FindComponent('ImageListMedusa'+inttostr(i))).Bitmap(arectf.Size,k));
    
           ResizeBitmap(LoadedBitmap, trunc(cx), trunc(cy));
           MeduzasBitmpAr[i].Add(LoadedBitmap);
          end;
      end;


     

    Дальше рисую по таймеру в основном окне игры Tpaintbox.OnPaint:
             

    Спойлер

     

     

    
    srcrect.left:= 0  ;
               srcrect.top:= 0  ;
               srcrect.Width:= MeduzasBitmpAr[Creatures[i].level][Creatures[i].AnimationIndex].Width;
               srcrect.height:= MeduzasBitmpAr[Creatures[i].level][Creatures[i].AnimationIndex].height;
    
               dstrect.left:=Creatures[i].RectF.Location.x-mapdx;
               dstrect.top:= Creatures[i].RectF.Location.y-mapdy;
               dstrect.Width:=Creatures[i].RectF.Width;
               dstrect.height:=Creatures[i].RectF.height;
    
               bufbitmap.Assign(MeduzasBitmpAr[Creatures[i].level][Creatures[i].AnimationIndex]);
    
                if ((Creatures[i].angle < 90)and(Creatures[i].angle >= 0)) then begin
                   angle:= 180 + Creatures[i].angle;
                   end else begin
    
                      if ((Creatures[i].angle <= 360)and(Creatures[i].angle > 270))  then begin
                        angle:= 180+ Creatures[i].angle;
                      end else begin
                         if (Creatures[i].angle > 90)and(Creatures[i].angle <= 270) then begin
                            bufbitmap.FlipHorizontal;
                           angle:=  Creatures[i].angle;
                         end else begin
                             if (Creatures[i].angle = 90) then begin
                               angle:= 270;
                             end;
                         end;
                      end;
                 end;
    
               PaintBoxMain.BeginUpdate;
               DrawBitmapRotate(PaintBoxMain.Canvas,bufbitmap , srcrect, dstrect, 1 , true, degtorad(angle));
               PaintBoxMain.EndUpdate;


     

    В принципе, даже на слабеньких телефончиках, всё вроде бодро. Но может, опытные товарищи чего подскажут, а то я 3ий день в собственном соку варюсь, ничего толкового.

  4. Да, "Get", безусловно работает, но для переименования файла на гугл диске нужно использовать метод "Patch" (это Google Api Drive + REST). 

    Насколько понял, по изучению сторонних форумов, данная ошибка будет возникать на Android KitKat и не будет на Android Lollipop, связано это с java библиотеками.

     

    При компиляции под windows, данная процедура работает исправно. В общем-то откатился обратно на XE7, но если кто знает, как решить, буду благодарен. 

  5. После перехода с XE7 на RAD 10  при выполнении след. процедуры возникает исключение, изображенное на скрине, что необходимо обновить/починить? 

    procedure ServerPatchDriveFile;
        var
        Folder  : TJSONObject ;
        FolderDest, itemmm   : TJSONObject ;
        parents:  TJSONArray ;
        begin
     
         form2.RESTResponseDataSetAdapter1.AutoUpdate := false;
         form2.RESTRequest1.Params.Clear;
         form2.RESTRequest1.ClearBody;
         form2.RESTClient1.AutoCreateParams:=false;
         form2.RESTClient1.Accept:= '';
         form2.RESTClient1.ContentType:= '';
         form2.RESTRequest1.Method:= rmPATCH;
          Form2.RESTClient1.BaseURL:='https://www.googleapis.com/drive/v2/files/{FileId}';
          form2.RESTRequest1.Resource := '';
          form2.RESTRequest1.Params.AddUrlSegment('fileId', UntitledId);
     
          Parents:= TJSONArray.Create;
          itemmm := TJSONObject.Create;
          itemmm.AddPair(TJSONPair.Create('id', form2.EditIdFOlder.Text));
          Parents.AddElement((itemmm));
     
            Folder:= TJSONObject.create;
            Folder.AddPair(TJSONPair.Create('title', 'Myfile'));
            Folder.AddPair(TJSONPair.Create('parents', Parents));
            form2.RESTRequest1.AddBody(Folder);
        try
          form2.RESTRequest1.Execute;
        except
        on e: Exception do
        begin
          ShowMessage(e.Message);//Show Exception
        end;
        end;
     
        Folder.free;
        Application.ProcessMessages;
     
        end;

    post-1622-0-91309300-1444502232.png

  6. Как оказалось, можно так:

    1. В OAuth2Authenticator в Redirection endpoint : http://localhost

    2. Ловить webform.lasttitle, например,  таймером так:

     

    procedure TForm2.TimerGetAuthCodeTimer(Sender: TObject);
    var
     tokentoedit: string;
    begin
      {$IF DEFINED(ANDROID)}
      if Pos('localhost/?code=', webform.LastURL) > 0 then
      begin
        AuthCode := Copy(webform.LastURL, 24, Length(webform.LastURL));
        if (AuthCode <> '') then
        begin
          editactoken.Text:= AuthCode;
          webform.close;
          TimerGetAuthCode.Enabled:=false;
        end;
      end;
      {$ENDIF}
    end;
  7. Мужики, нужны пояснения. Реализую rest delphi xe7 + google api oauth 2.0. Код, привел в порядок с примером ZuBy:

    uses
    
    
      {$IF DEFINED(ANDROID)}
           REST.Authenticator.OAuth.WebForm.FMX , Androidapi.Helpers,
        Androidapi.jni , AndroidAPI.JNIBridge, Androidapi.JNI.JavaTypes,  FMX.Helpers.Android,
        Androidapi.JNI.GraphicsContentViewText;
      {$ENDIF}
      {$IF DEFINED(MsWindows)}
        REST.Authenticator.OAuth.WebForm.Win;
      {$ENDIF}
    
    
    ...
      private
        { Private declarations }
        WebForm: Tfrm_OAuthWebForm;
        procedure Auth;
        procedure OAuth2_GoogleTasks_BrowserTitleChanged(const ATitle: string;  var DoCloseWebView: boolean);
      public
        { Public declarations }
    ...
    
    
    procedure TForm2.OAuth2_GoogleTasks_BrowserTitleChanged(const ATitle: string;
      var DoCloseWebView: boolean);
    begin
      //Memo3.text:=(webform.LastURL);
      if Pos('Success code', ATitle) > 0 then
      begin
        AuthCode := Copy(ATitle, 14, Length(ATitle));
        if (AuthCode <> '') then
        begin
          //Memo3.Lines.Add(AuthCode);
          editactoken.Text:= AuthCode;
          DoCloseWebView := true;
          webform.Release;
        end;
      end;
    end;
    
    
    procedure TForm2.Button59Click(Sender: TObject);
    begin
          WebForm:=Tfrm_OAuthWebForm.Create(nil);
          WebForm.OnTitleChanged  := self.OAuth2_GoogleTasks_BrowserTitleChanged;
         WebForm.ShowWithURL(OAuth2Authenticator1.AuthorizationRequestURI);
    end;

    На windows все работает, на Android не происходит события TitleChanged, меняю так:

     

    procedure TForm2.OAuth2_GoogleTasks_BrowserTitleChanged(const ATitle: string;
      var DoCloseWebView: boolean);
    begin
       ListBoxDatabase.Items.Add(ATitle);
    end;

    На Windows отображаются все заголовки, на Android - пусто.  

    Оставляю webform, просто пробую открыть страницу авторизации в дефолтном браузере на устройстве:

    var
      Intent: JIntent;
    begin
      Intent := TJIntent.Create;
      Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
      Intent.setData(StrToJURI(OAuth2Authenticator1.AuthorizationRequestURI));
      SharedActivity.startActivity(Intent);

    Результат на скриншотах внизу. Поясняю: из самого браузера скопировать строку не удается, не вызываются стандартные механизмы, в Title отлично видно, что Success Code пришел, когда на него кликаешь, чтобы скопировать, получаешь строку со скрина 3 (который ..approval... )

     

    Просто создаю проект с браузером, открываю авторизацию в приложении, без webform  и пытаюсь скопировать код из тела webbrowser:

    procedure TForm4.Button4Click(Sender: TObject);
    Var
      Clipboard: IFMXClipboardService;
      value: TValue;
      hasText: boolean;
      s: string;
    begin
      hasText := False;
      if TPlatformServices.Current.SupportsPlatformService(IFMXClipboardService, IInterface(Clipboard)) then
      begin
        value := Clipboard.GetClipboard;
        hasText := value.TryAsType<String>(s);
      end;
      ShowMessage(BoolToStr(hasText));
      if hasText then ShowMessage(s);
     end;

    Не берет.

     

    Читаю статьи:

    https://developers.google.com/api-cl.../installed-app
    https://developers.google.com/android/guides/http-auth

     

    Понимаю, что авторизацию через веббраузер надо делать для installed applications, для Android необходимо использовать нативные библиотеки. Там правда не сказано, что нельзя делать авторизацию на android через webbrowser. В связи с этим у меня возникает пара вопросов:

     

    1. Концептуально: Можно ли получать токен на Android вышеуказанным путем?

        Тактически: Если да, то в таком случае, как получить success code, в чем проблема? webform.fmx забыли припечатать title? Подскажите, что переделать.

    ( все остальное: обмен на токен, настройка коомпонентов, скачка, закачка файлов и т.д. все работает на винде исправно, т.е. весь механизм обкатан, но при переносе на андроид возникает загвоздка с получением sucess code)

     

    2. if  not (1) тогда, есть ли у кого-то сэмплы или ссылки на реализацию через Java в Delphi, так понимаю, Android.Jni JIntent etc. 

     

    post-1622-0-24110300-1442596810.png

    post-1622-0-73053700-1442596820.png

    post-1622-0-84356000-1442596832.png

  8. Да, у меня также было сделано с примера webdelphi. Ваш код при компиляции под windows отлично работает. Title меняется из него извлекается Access Code, но при компиляции на андроид устройстве, события OnTitleChanged не происходит, при все тех же действиях.

    открываю REST.Authenticator.OAuth.WebForm.Win и REST.Authenticator.OAuth.WebForm.FMX, начинаю сравнивать, в глаза бросается следующее:

    ...  private
        { Private declarations }
        FOnBeforeRedirect: TOAuth2WebFormRedirectEvent;
        FOnAfterRedirect: TOAuth2WebFormRedirectEvent;
        FOnBrowserTitleChanged : TOAuth2WebFormTitleChangedEvent;
    
    
        FLastTitle: string;  // <------- ЭТОГО нет в FMX
        FLastURL: string;
      public
    ...

    В WebForm.FMX:

    ...  private
        { Private declarations }
        FOnBeforeRedirect: TOAuth2WebFormRedirectEvent;
        FOnAfterRedirect: TOAuth2WebFormRedirectEvent;
        FOnBrowserTitleChanged : TOAuth2WebFormTitleChangedEvent;
    
    
        FLastURL: string;
    ...  public

    В случае с Win можно также извлечь код из свойства lasttitle, опять-таки в FMX только Flasturl, но он остается неизменным. Пробовал в Delphi XE7  и Delphi XE8.

    Может, как-то можно из WebBrowser достать значение? 

     

  9. Использую библиотеку Rest для работы с гугл-диском. Для авторизации вызываю Webform, под windows все работает хорошо. Стал переносить на Android (Rest.authenticator.oauth.webform.fmx) и столкнулся с проблемой, что андроид не вызывает функции копирования строки. 

    В webform.win было свойство lasttitle из которого можно было достать access code.

    В webform.fmx присутствует Flasturl, но он не меняется при закрытии формы.

     

    Подскажите как быть?

     

     

    post-1622-0-83799100-1442187460.png

×
×
  • Создать...