Перейти к содержанию

Ingalime

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

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

  • Посещение

  • Победитель дней

    5

Активность репутации

  1. Like
    Ingalime выдал репутацию qz5 в Это приложение было создано для более ранней версии Android   
    Приложение может вылетать по разным причинам.
    Возможно дело в том, что пытаетесь прочитать или записать файл в публичную папку. На Андроид 11 мало запроса разрешения, теперь чтение и запись файлов делается иначе.
     
    У меня приложение на Делфи работает на 29 СДК (это от Андроид 10), но пришлось добавить строку, о которой написано в теме на которую дал ссылку. Иначе не работало на Андроид 11.
  2. Like
    Ingalime выдал репутацию slav_z в Это приложение было создано для более ранней версии Android   
    здесь на форуме это все уже обсуждалось...  на андроид 11 изменилось расположение системных библиотек...  дельфи 10.2 об этом не знает...  10.3.3 еще можно было заставить работать с андроид 11 (исправлением и перекомпиляцией System.pas)... но надо ставить 10.4...  надо... sdk и файл манифеста тыркать бесполезно....
  3. Like
    Ingalime выдал репутацию Legended в Экспорт в файл/импорт из файла.   
    Получилось написать, работает на всех уровнях.
     
    Экспорт
    Импорт
    P.S.Сорри за мой кодстайл, но думаю суть поймете.
  4. Like
    Ingalime выдал репутацию Равиль Зарипов (ZuBy) в Экспорт в файл/импорт из файла.   
    вот так примерно
    json-treeview.zip
  5. Like
    Ingalime выдал репутацию Freezer_86 в TakePhotoFromCameraAction   
    Доброго времени суток. Столкнулся с такой же проблемой в 10.4.2. В стандартном примере все работает, а в мигрированном приложении из 10.3.3 - приложение всегда ловит отмену запроса на фото. Я так понимаю где-то не хватает прав для временного файла. 
    Путем долгих и мучительных экспериментов и курением доки организовал эту всю штуку через нативные интенты.
    Код вырезан из рабочего проекта, по этому извините если что-то не так. Но смысл должен быть понятен.
    Здесь кроме самого фото еще реализовано автоматическое поворачивание картинки по Exif-даным, относительно того в каком положении был телефон.
    Так же очень важно не забыть выставить права в опциях приложение и подключить Secure File Sharing в Entitlement List. С Uses секцией надеюсь разберетесь, не уверен что нужно для Вашей задачи все из того что я кинул.
    Uses .... Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.App, Androidapi.JNI.JavaTypes, Androidapi.Helpers, FMX.Platform.Android, System.Permissions, Androidapi.JNI.Os, Androidapi.JNI.Net, Androidapi.JNI.Support, Androidapi.JNI.Provider, Androidapi.JNIBridge, FMX.Helpers.Android, FMX.Surfaces, Androidapi.JNI.Media; TfmMain = class(TForm) ... procedure FormCreate(Sender: TObject); procedure btnPhotos_ShowCameraClick(Sender: TObject); ... protected FMessageSubscriptionID : integer; FPermissionWriteExternalStorage: string; FPermissionCamera: string; FPermissionReadExternalStorage: string; FphotoUri :Jnet_Uri; JFileName: JFile; procedure DisplayRationale(Sender: TObject; const APermissions: TArray<string>; const APostRationaleProc: TProc); procedure TakePicturePermissionRequestResult(Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>); procedure TakePicturePermissionRequestAfterINitResult(Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>); procedure HandleActivityMessage(const Sender: TObject; const M: TMessage); function OnActivityResult(RequestCode, ResultCode: Integer; Data: JIntent): Boolean; end; procedure TfmMain.FormCreate(Sender: TObject); begin FPermissionCamera := JStringToString(TJManifest_permission.JavaClass.CAMERA); FPermissionReadExternalStorage := JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE); FPermissionWriteExternalStorage := JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE); ... end; procedure TfmMain.HandleActivityMessage(const Sender: TObject; const M: TMessage); begin if M is TMessageResultNotification then begin OnActivityResult(TMessageResultNotification(M).RequestCode, TMessageResultNotification(M).ResultCode, TMessageResultNotification(M).Value); end; end; function TfmMain.OnActivityResult(RequestCode, ResultCode: Integer; Data: JIntent): Boolean; procedure SetPhotoData(); var jBmp : JBitmap; xSurface : TBitmapSurface; vImage : TImage; xExif : JExifInterface; sOrientation : JString; rotationAngle, orientation : integer; sFile : string; ScreenService: IFMXScreenService; begin if RequestCode = 1001 then begin if ResultCode = TJActivity.JavaClass.RESULT_OK then begin if FphotoUri <> nil then begin jBmp := TJImages_Media.JavaClass.getBitmap(SharedActivity.getContentResolver, FphotoUri); if jBmp <> nil then begin xSurface := TBitmapSurface.Create; try JBitmapToSurface(jBmp, xSurface); vImage := TImage.Create(nil); try vImage.Bitmap.Assign(xSurface); sFile := JStringToString(JFileName.getAbsolutePath); xExif := TJExifInterface.JavaClass.init(StringToJString(sFile)); sOrientation := xExif.getAttribute(TJExifInterface.JavaClass.TAG_ORIENTATION); if sOrientation = nil then orientation := TJExifInterface.JavaClass.ORIENTATION_NORMAL else orientation := StrToIntDef(JStringToString(sOrientation), 0); rotationAngle := 0; if orientation = TJExifInterface.JavaClass.ORIENTATION_ROTATE_90 then rotationAngle := 90; if orientation = TJExifInterface.JavaClass.ORIENTATION_ROTATE_180 then rotationAngle := 180; if orientation = TJExifInterface.JavaClass.ORIENTATION_ROTATE_270 then rotationAngle := 270; if rotationAngle <> 0 then vImage.Bitmap.Rotate(rotationAngle); //Готовое фото уже в vImage - выводим куда нужно imPhotos_Photo.Bitmap.Assign(vImage.Bitmap); finally vImage.Free; end; finally xSurface.Free end{try..finally}; end else begin //не вдалось завантажити картинку TDialogService.ShowMessage('Не вдалось завантажити картинку'); end{if..else}; end else begin //пустий Uri TDialogService.ShowMessage('Пустий Uri'); end{if..else}; end else begin TDialogService.ShowMessage('Відмовились робити фото'); end{if..else}; end{if}; end; begin Result := False; TMessageManager.DefaultManager.Unsubscribe(TMessageResultNotification, FMessageSubscriptionID); FMessageSubscriptionID := 0; if RequestCode = 1001 then begin // робота з камерою - отримання фото SetPhotoData(); exit; end; ... end; procedure TfmMain.TakePicturePermissionRequestResult(Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>); var intent : jintent; Authority: JString; begin // 3 permissions involved: CAMERA, READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE if (Length(AGrantResults) = 3) and (AGrantResults[0] = TPermissionStatus.Granted) and (AGrantResults[1] = TPermissionStatus.Granted) and (AGrantResults[2] = TPermissionStatus.Granted) then begin //створюємо "намір" отримання фото з камери intent := TJIntent.JavaClass.init; intent.setAction(TJMediaStore.JavaClass.ACTION_IMAGE_CAPTURE); //створюємо тимчасовий файл JFileName := TJFile.JavaClass.createTempFile(StringToJString('picture'), StringToJString('.jpg')); //отримуємо опис прав по файлам Authority := StringToJString(JStringToString(TAndroidHelper.Context.getApplicationContext.getPackageName) + '.fileprovider'); //отримуємо URI-до тимчасового файлу в контексті нашої аплікації FphotoUri:= TJFileProvider.JavaClass.getUriForFile(TAndroidHelper.Context, Authority, JFileName); //кажемо що наш "намір" має писати дані в цей тимчасовий файл intent.putExtra(TJMediaStore.JavaClass.EXTRA_OUTPUT, TJParcelable.Wrap((FphotoUri as ILocalObject).GetObjectID) ); //реєструємось на отримання подій FMessageSubscriptionID := TMessageManager.DefaultManager.SubscribeToMessage(TMessageResultNotification, HandleActivityMessage); //стартуємо наш "намір" MainActivity.startActivityForResult(intent, 1001); end else TDialogService.ShowMessage('Не надані необхідні для роботи дозволи!'); end; procedure TfmMain.DisplayRationale(Sender: TObject; const APermissions: TArray<string>; const APostRationaleProc: TProc); var I: Integer; RationaleMsg: string; begin for I := 0 to High(APermissions) do begin if APermissions[I] = FPermissionCamera then RationaleMsg := RationaleMsg + 'The app needs to access the camera to take a photo' + SLineBreak + SLineBreak else if APermissions[I] = FPermissionReadExternalStorage then RationaleMsg := RationaleMsg + 'The app needs to read a photo file from your device'; end; // Show an explanation to the user *asynchronously* - don't block this thread waiting for the user's response! // After the user sees the explanation, invoke the post-rationale routine to request the permissions TDialogService.ShowMessage(RationaleMsg, procedure(const AResult: TModalResult) begin APostRationaleProc; end); end; procedure TfmMain.btnPhotos_ShowCameraClick(Sender: TObject); begin PermissionsService.RequestPermissions( [FPermissionCamera, FPermissionReadExternalStorage, FPermissionWriteExternalStorage], TakePicturePermissionRequestResult, DisplayRationale ); end; P.S. возможно нужно будет вставить в манифест:
    android:requestLegacyExternalStorage="true"  
  6. Like
    Ingalime выдал репутацию haword в Фокус окна после разворачивания из трея   
    в 10.4.1 нет такой проблемы вообще
  7. Like
    Ingalime выдал репутацию Денис Сапронов в В DataSnap TClientDataSet установка фильтра   
    Ребят, вопрос снят! На новых девайсах всё работает. 
  8. Like
    Ingalime выдал репутацию WinterSun в Помогите проиграть звук в MediaPlayer   
    Привет.
    TMediaPlayer умеет воспроизводить только из файлов - не из ресурсов. Надо ресурс сохранить в файл и затем его проиграть. 
  9. Like
    Ingalime выдал репутацию krapotkin в Помогите проиграть звук в MediaPlayer   
    ну логично если указать только имя файла, а путь к нему не указать, то он и не найдется
  10. Like
    Ingalime выдал репутацию krapotkin в Воспроизведение видео с жесткого диска в twebbrowser   
    а где часть "Дано" ?
    ОС? Каким способом загружаете файл в браузер?
    в теории TMediaPlayer умеет и mp4 воспроизводить, но нужна конкретика
    есть также вариант PasLibVlc
  11. Like
    Ingalime выдал репутацию qz5 в TPath.GetSharedDownloadsPath в Android 11 не находит файлы   
    Вот еще почитать на эту тему:
    https://developer.android.com/training/data-storage/use-cases
    и
    https://developer.android.com/about/versions/11/privacy/storage
    Так что после Target SDK 30 вообще старый код работать не будет... Нужно будет переписывать код работы с файлами.
  12. Like
    Ingalime выдал репутацию qz5 в TPath.GetSharedDownloadsPath в Android 11 не находит файлы   
    Дело в том, что ты выставил Target SDK 29
    Теперь чтобы на Андроид 10, 11 или 12 старым способом иметь доступ к файлам надо объявить явно это в манифесте
    Кажется с помощью android:requestLegacyExternalStorage="true"
    но лучше погугли.
    И вообще в будущем возможно... Гугл зарежут прямой доступ к файлам и придется через медиа-запросы обращаться к файлам.
  13. Like
    Ingalime выдал репутацию krapotkin в Работа Listview   
    самое простое (по мне лично) взять и положить на него новый объект типа крашеный прямоугольник.
    Свой класс объектов для listView можно создать аналогично тем, что есть в delphi, унаследовав от TDrawable
    https://www.youtube.com/watch?v=XRj3qjUjBlc
     
  14. Like
    Ingalime выдал репутацию Billy Bones в Владелец файла и права доступа   
    Получить UID (идентификатор пользователя - владельца) можно с помошью функции stat (Описана в POSIX стандарте : https://pubs.opengroup.org/onlinepubs/9699919799/ ). Далее есть файл /etc/passwd где UID пользователей сопоставлены с их именами.
    В Linux документацию на stat можно посмотреть командой man 2 stat (В случае если установлены средства разработки на языках C/C++).
    Если не ошибаюсь, она находится в библиотеке libc. Значит задача состоит в том, чтобы загрузить "dll" библиотеку libc ( например /usr/lib64/libc.so.6 ) и вызвать функцию stat. Для загрузки динамических библиотек (разделяемых объектов - shared object - so) используется вызов dlopen.
    Альтернативный способ состоит в том, чтобы напрямую (без библиотеки libc ) выполнить системный вызов stat, обратившись непосредственно к ядру ОС. Для этого, нужно, найти документацию на системный вызов stat, и вызвать его самому - вы по сути сами реализуете функционал библиотеки libc.
    Второй способ, хоть и кажется сложнее, на самом деле реализуется буквально несколькими assembler'ными инструкциями.
    Возможно в Delphi это уже сделали (не исключаю, что в какой-то библиотеке, уже есть функция Stat ).
    В RAD Studio, в каталоге source\rtl\posix, есть файл SysStatAPI.inc - он включен в posix.sysstat.pas.
    Значит просто: Uses Posix.SysStat и используйте функцию stat.
  15. Like
    Ingalime выдал репутацию krapotkin в Виртуальный ListBox в FireMonkey (FMX)   
    вроде уж везде написали что ListBox не предназначен для 20+ элементов. используйте ListView 
    https://www.youtube.com/watch?v=XRj3qjUjBlc
    для облегчения нелегкой работки можно посмотреть тут 
    http://fire-monkey.ru/topic/5519-фреймворк-для-стандартного-listview/#comment-34912
     
    ну и да, 50000+ элементов это несколько трешовый UI
  16. Like
    Ingalime выдал репутацию ddr 2 в Векторный стилевой класс   
    Задумался о применении векторных изображений в стилях контролов. На примере TButton, т.е. создать векторный "стилевой" класс по аналогичный с растровым TButtonStyleObject, 
    где для 4-х визуальных представлений будет использовать не TBitmapLinks, а TPath. 
    Минусы:
    Не будет 9parts, а значит только фиксированное соотношение сторон;  Не родное решение (ниже Сомнение№2);  Плюсы:
    Самый очевидный - один стиль с 4-мя картинками, вместо в много раз(10+) больше картинок под разные scale/разрешений экрана/размеров....(в зависимости от выбронного способа избавления от "мыла" для работы приложения на любых экранах и мониторах с любым разрешением и scale);  Меньшая ресурсоёмкость. Будет шустрее работать (как минимум НЕ медленне), что не критично для Windows, но актуально для  большей части комьюнити данного форума, разработчиков под мобильные платформы. Только за счет отказа от 9parts, быстродействие отрисовки вырастет. См. реализацию TCustomStyleObject.DoDrawToCanvas -9 частей отрисовываются всегда(9 вызовов Canvas.DrawBitmap(...)), даже если они фактически не используются. Я, к примеру, 9parts использую только у стиля листбокса, который "внутри" комбобокса. В остальных случаях, дефакто - 1 область + 8 областей нулевой площади. При желении, даже у листбокса можно отказаться от 9parts. Время загрузки Стиля- (+/-)10% по сравнению к растровому решению. Сомнения:
    Поизучав FMX.Styles.Objects.pas "легкой" реализации, что бы, что-нибудь наследовать и пару строк дописать, я не нашёл. Для меня понятное решение, это полностью скопировать(взять за основу "векторных" стиливых классов) TCustomStyleObject и TButtonStyleObject и править... Это 1500+ строк кода. Зная свой темп работы, я для себя переписывание и отладку оцениваю в 2-е недели работы. А потом выйдет 10.4.3 или если сильно повезет, то переставать работать "векторный" класс будет лишь на каждом втором релизе и... goto п.1 ПРЕДЛАГАЮ ОБСУДИТЬ + И - ТАКОГО РЕШЕНИЯ, РЕАЛИЗАЦИЮ,  ЦЕЛЕСООБРАЗНОСТЬ, АЛЬТЕРНАТИВЫ.
  17. Like
    Ingalime выдал репутацию qz5 в Как сделать управление в TWebBrowser под Win как на мобильных платформах   
    Есть еще вариант использовать CEF4Delphi - https://github.com/salvadordf/CEF4Delphi
     
  18. Like
    Ingalime выдал репутацию haword в Как сделать управление в TWebBrowser под Win как на мобильных платформах   
    на таких постоматах есть листание экрана кнопками такой, метод и использовать.
    либо использовать компоненты типа html component library либо thtmlview если vcl и там уже реализовать что надо. 
  19. Like
    Ingalime выдал репутацию brunnengi в Как сделать управление в TWebBrowser под Win как на мобильных платформах   
    Будем отталкиваться от мысли что обычные браузеры из под винды тоже через Tap не пашут.
    У вас стоит инфомат. Если у вас там просто текст и кликане по элементам не требуется,  а просто листают вниз текст, то можно сохранить как картинку или pdf и положить в vertdscroll. А уже потом обрабатывать самому tap и свайпы.
    Но в целом, вообще, эта работа, больше по части фронтовика, т.е. фронтенд разраба. Ему ничто не мешает сделать ветку сайта с JS кодом который запрещает выделение текста на странице, а сролл делать либо по клику какой нить круглой кнопки внизу по центру странице или обработать зажатие ЛКМ, свайп вверх или вниз и отпускание. 

    Однако на моей практике при работе с терминалами и инфоматами, лучше писать именно ПО, а не грузить в браузер свою страницу. А если уж горит через веб браузер, то надо саму страницу адоптировать всё таки, так как даже всё сделать как вы хотите, то тыкать портянки текста вниз и читать никто не будет. Максимум пару экранов в сторону отлистают и всё и интереса больше нет.

    Но повторюсь что ПО, exe файл куда лучше пашет. Получаете с сервера разметку текста, картинки спокойно отображаете у себя. В FMX это вообще задачка три-семь дней, если речь именно о инфомате.
  20. Like
    Ingalime выдал репутацию krapotkin в В DataSnap TClientDataSet установка фильтра   
    Можно воспользоваться OnFilterRecord
    там все ручное, под контролем
  21. Like
    Ingalime выдал репутацию krapotkin в Как сделать управление в TWebBrowser под Win как на мобильных платформах   
    prerequisite
    /priːˈrɛkwɪzɪt/ noun plural noun: prerequisites a thing that is required as a prior condition for something else to happen or exist. "sponsorship is not a prerequisite for any of our courses"   системные требования по-местному
  22. Like
    Ingalime выдал репутацию krapotkin в Как сделать управление в TWebBrowser под Win как на мобильных платформах   
    хм. а ведь в каждом браузере есть встроенный режим "смартфон" в панели разработчика
  23. Like
    Ingalime выдал репутацию Tumaso в Создание HTTP сервера   
    Почему?)
    Я делал в виде демона для ubuntu с использованием indy + mysql + json. Работает уже как два года, полет нормальный, ни разу не крешилось
  24. Like
    Ingalime выдал репутацию OnePeople в [Android] Воспроизводить аудио   
    По поведению на различных прошивках я не могу вам ни чего сказать вообще не думаю что это связанно с версией андроида, а связанно с прошивкой вендора.
    Выдернул из рабочего проекта, строго не пинать, за корявость)
    1.
    type       {$IFDEF ANDROID}   TMyAudioFocusChangeListener = class;         {$ENDIF}   TForm1 = class(TForm) 2.
    private     { Private declarations }            {$IFDEF ANDROID}     afChangeListener: TMyAudioFocusChangeListener; 3.
    public procedure onAudioFocusChange(focusChange: Integer); end; TAudioFocusChangeEvent = procedure(focusChange: Integer) of object;   TMyAudioFocusChangeListener = class(TJavaLocal, JAudioManager_OnAudioFocusChangeListener)   private     [weak]     FParent : TForm1;     FOnAudioFocusChanged: TAudioFocusChangeEvent;   public     constructor Create(AParent : TForm1);     property OnAudioFocusChanged: TAudioFocusChangeEvent read FOnAudioFocusChanged write FOnAudioFocusChanged;     Destructor Destroy; Override;     procedure onAudioFocusChange(focusChange: Integer); cdecl;    end; 4.
    constructor TMyAudioFocusChangeListener.Create; begin   inherited Create;   FParent := AParent; end; destructor TMyAudioFocusChangeListener.Destroy; begin   inherited; end; procedure TMyAudioFocusChangeListener.onAudioFocusChange(focusChange: Integer); begin   if Assigned(FOnAudioFocusChanged) then     begin       FOnAudioFocusChanged(focusChange);     end;     FParent.onAudioFocusChange(focusChange); end; procedure TForm1.onAudioFocusChange(focusChange: Integer); begin   Form1.Memo2.Lines.Add('focus change:'+focusChange.ToString);    if  (focusChange=TJaudioManager.JavaClass.AUDIOFOCUS_LOSS) then         begin           MusicControl.AudioFocus:=false;           case MusicControl.MusicType of           TMusicType.Music:           if MusicControl.Music.MusicState=TMusicState.Play then               begin                  MusicPlayPause;                  exit;               end;           TMusicType.Radio:           if MusicControl.Radio.MusicState=TMusicState.Play then               begin                  RadioPlayPause;                  exit;               end;         end;         end; end; 5.
    procedure TForm1.GetAudioFocus; begin //   {$IFDEF ANDROID} CallinUIThread(procedure     var      AudioFocusRequest: JAudioFocusRequest;  playbackAttributes: JAudioAttributes;  afHandler: JHandler;  res: integer;  begin afChangeListener:=TMyAudioFocusChangeListener.Create(Self); afHandler:= TJHandler.Create; playbackAttributes := TJAudioAttributes_Builder.Create         .setUsage(TJAudioAttributes.JavaClass.USAGE_MEDIA)         .setContentType(TJAudioAttributes.JavaClass.CONTENT_TYPE_MUSIC)         .build(); AudioFocusRequest:=TJAudioFocusRequest_Builder(TJAudioManager.JavaClass.AUDIOFOCUS_GAIN).Create         .setAudioAttributes(playbackAttributes)         .setAcceptsDelayedFocusGain(true)         .setOnAudioFocusChangeListener(afChangeListener, afHandler)         .build();  res:=FAudioManager.requestAudioFocus(AudioFocusRequest);   if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_DELAYED then         LogCAAdd('AUDIOFOCUS_REQUEST_DELAYED')      else if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_GRANTED then      begin         MusicControl.AudioFocus:=true;         LogCAAdd('AUDIOFOCUS_REQUEST_GRANTED');      end      else if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_DELAYED then         LogCAAdd('AUDIOFOCUS_REQUEST_DELAYED');      end     );       {$ENDIF} end; P.S. Для android 8 выше! для поддержки ранешних версий Android нужно немного дописать
  25. Like
    Ingalime выдал репутацию Slym в string   
    тогда везде тыкай {$ZEROBASEDSTRINGS OFF} глобально никак
×
×
  • Создать...