Евгений Корепов
Пользователи-
Постов
738 -
Зарегистрирован
-
Посещение
-
Победитель дней
100
Весь контент Евгений Корепов
-
TidHTTPClient перестал работать в Android 6. При попытке Get приложение закрывается с segmentation fault. То же самое приложение на всех остальных версиях андроида работает нормально. На эмуляторе проверить не удалось, по какой то причине эмулятор с андроид 6 у меня запускается около часа, а попытка отладки приводит к зависанию дельфи. Взял на пол часа живое устройство, отладка показала что крах происходит на стадии разбора результата. Т.е. данные с сервера реально получает (это подтверджают логи сервера), и при попытке вернуть результат все умирает. Код простой: Var HTTPResult : TStringStream; URI: TIdURI; HTTP: TIdHTTP; begin AURL:='http://10.10.0.1'; FHost:='10.0.0.1'; HTTP:=TIdHTTP.Create; HTTP.CookieManager := TIdCookieManager.Create(HTTP); HTTP.Request.Host:=FHost; HTTP.AllowCookies := true; HTTP.HandleRedirects := True; HTTP.ConnectTimeout:=6000; HTTP.ReadTimeout:=30000; HTTP.Request.CustomHeaders.AddValue('Connection','keep-alive'); HTTP.Request.Accept:='text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'; HTTP.Request.UserAgent:='Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36'; HTTP.Request.AcceptEncoding:='gzip, deflate, sdch'; HTTP.Request.AcceptLanguage:='ru,en-US;q=0.8,en;q=0.6'; Result.Status:=False; Result.MessageText:=''; AURL:=StringReplace(AURL,'{AuthorizationKey}',AuthorizationKey,[]); AURL:=StringReplace(AURL,'{Host}',FHost,[]); HTTPResult:= TStringStream.Create('', TEncoding.UTF8); URI := TIdURI.Create(AURL); HTTP.CookieManager.AddServerCookie(CookieAuthorization, URI); try HTTP.Get(AURL,HTTPResult); except on E : Exception do begin Result.Status:=False; Result.MessageText:=E.Message; Exit; end; end; Result.Status:=True; Result.MessageText:=Trim(HTTPResult.DataString); HTTPResult.Free; URI. Free; end; Падает на строке HTTP.Get(AURL,HTTPResult);, try не срабатывает. Запрос именно http, не https. К сожалению живое устройство было у меня не долго, досконально разобраться не успел. Выяснил что падает на строке 1423 в idHTTP.pas: IOHandler.ReadStream(LS, -1, True); У кого будут какие мысли? Понятно что разработчики забили на Indy довольно давно, но не хочется целиком десяток проектов переписывать. P.S. System.Net.HTTPClient работает в тех же условиях, не падает, но не смог заставить работать cookie, разбираюсь в чем дело. Хотя при отсутствии таймаутов и обработки редиректов применение сего очень ограничено.
-
Избежать появления кнопки Вставить можно очисткой буфера обмена. Например так: procedure TFormMain.Edit1CanFocus(Sender: TObject; var ACanFocus: Boolean); begin if Assigned(FClipboardSvc) then FClipboardSvc.SetClipboard(''); ACanFocus:=True; end; Обратите внимание что именно пустая строка очищает буфер, попытка сделать FClipboardSvc.SetClipboard(Nil); поместит в буфер строку 'empty'.
-
Вы будете смеяться, но проблема решена. Методом научного тыка. Не работающая установка значения ListView.ScrollViewPos решается следующей строкой ListView.ItemIndex:=0; (Не важно 0 или любое другое число). Т.е. для того чтоб заработало делаем так: ListView.ItemIndex:=0; ListView.ScrollViewPos:=333; // Ура, работает!!! Почему так работает, я не понял.
-
Ветка форума поэтому и называется TListView, что речь идет о TListView, а не ListBox. Кстати заметил странность, после ListView.Resize иногда GetMaxScrollViewPos выдает реальное число а не 0. Удалось точно узнать в какой ситуации: 1. Добавляем много итемов, чтоб не помещались в видимую область 2. Удаляем все итемы (ListView.ClearItems;) 3. Опять добавляем итемы и позиционируем ScrollViewPos:=300 - Ура все работает. Если в 1 пункте все итемы помещаются в видимую область, то в Четвертом пункте ScrollViewPos:=300 не приводит ни к какому результату (GetMaxScrollViewPos = 0). Остается списать все на очередной косяк Embarcadero, других мыслей нет...
-
Вот здесь посмотрите https://code.google.com/p/delphi-foundations/source/browse/trunk/Book/06.+Arrays,+collections+and+enumerators/Simple+search+%28TArray+class+helper%29/CCR.Generics.SimpleArraySearch.pas?r=29
-
Не подходит. ScrollTo позиционирует Item по нижней границе ListView. Трудно придумать применение этой функции с точки зрения дизайна приложения. Логично позиционировать по верху. Но если высота ListView не кратна ItemHeight, то даже с помощью дополнительных вычислений не возможно этим методом позиционировать нужный итем сверху. Метод ScrollViewPos идеален для этого, но по какой то причине не работает сразу после создания итемов.
-
Установка ScrollViewPos после добавления ListViewItem
Евгений Корепов опубликовал вопрос в TListView
Задача в следующем: Динамически заполняю ListView, после заполнения нужно установить ListView.ScrollViewPos в произвольную позицию. Но не выходит по причине того, что в процедуре TCustomListView.SetScrollViewPos(const Value: Single) функция GetMaxScrollViewPos всегда в таком случае возвращает ноль. Подозреваю что после добавления итемов нужно как то передёрнуть ListView, но не знаю как. Пробовал ApplyStyleLookup, Repaint, Resize, RecalcSize - не помогает. Отрисованный и видимый в приложении ListView прекрасно позиционируется с помощью ScrollViewPos. А GetMaxScrollViewPos выдает реальную длину списка. Ткните меня в правильную процедуру. -
Думаю да, судя по исходникам под все платформы. И кстати ошибка у меня в коде: Note: FindFirst allocates resources (memory) that must be released by calling FindClose. Забыл FindClose.. В хелпе есть упоминание мака, так что думаю будет работать точно. Note: Some of the file attribute constants are not valid on all platforms. For example, faVolumeID and faArchive do not work on MAC OS.
-
Ура! Я победил проблему. Причем с помощью почти забытой мной процедуры FindFirst ;-) Код работает корректно под Windows и Android. Файл не передергивается, антивирус спокоен. function TFileManager.GetFileSize(APath : String) : String; Var AFileSizeByte : Int64; AFileSizeFloat : Double; SearchRec : TSearchRec; FileAttrs: Integer; begin FileAttrs :=faArchive; FileAttrs := FileAttrs + faAnyFile; Result:='unknow'; AFileSizeByte:=0; try FindFirst(APath,FileAttrs,SearchRec); AFileSizeByte:=SearchRec.Size; FindClose(SearchRec); except Exit; end; if AFileSizeByte<1024 then begin Result:=Format('%d',[AFileSizeByte])+' Byte'; Exit; end; if AFileSizeByte<1048576 then begin AFileSizeFloat:=AFileSizeByte/1024; Result:=Format('%6.3f',[AFileSizeFloat])+' KByte'; Exit; end; if AFileSizeByte<1073741824 then begin AFileSizeFloat:=AFileSizeByte/1048576; Result:=Format('%6.3f',[AFileSizeFloat])+' MByte'; Exit; end; AFileSizeFloat:=AFileSizeByte/1073741824; Result:=Format('%6.3f',[AFileSizeFloat])+' GByte'; end;
-
Эффект тот же. Этот способ я вторым проверил.
-
Нужно получить размер файла под любыми платформами. Сейчас использую функцию function TFileManager.GetFileSize(APath : String) : String; Var F : file of Byte; AFileSizeByte : Integer; AFileSizeMbyte : Double; begin Result:=''; AssignFile(F, APath); FileMode := 0; // readonly try try Reset(F); AFileSizeByte:=FileSize(F); CloseFile(f); except end; finally AFileSizeMbyte:=AFileSizeByte/1048576; Result:=Format('%6.3f',[AFileSizeMbyte])+' Mbyte'; end; end; Работает, но есть одно но - под Windows, если проверяю exe файл, антивирус (в данном случае Защитник Windows) унюхивает что производится открытие файла и начинает его проверять на вирусы. Из за этого сканирование директории с большим количеством исполняемых файлов подвешивает основной поток приложения. Вопрос в следующем - нет ли другого способа получения размера? Странно что TFile, TPath или TDirectory не содержат такого полезного метода. В данный момент двигаюсь в направлении отдельного потока получения размера, но решение не красивое, хочется быстро и сразу.
-
Без "FloatAnimation.Parent:=Nil" вылетало исключение. Какой именно не скажу, грохнул весь этот код. Опять наступил на старые грабли и изменил принципу "Никогда, никогда не использовать ListBox в проектах". Самодельный аналог на вертикальном скроллбоксе работает на порядок красивее и стабильнее. Этот компонент переписал на ListView.
-
Смена родительского компонента для аниматора №2
Евгений Корепов опубликовал вопрос в TFloatAnimation
Задача следующая - добавить анимацию в ListBoxItem по клику, ListBoxItem может быть несколько десятков. Создавать для каждого Animation накладно. Update: Нашел решение в теме http://fire-monkey.ru/topic/1073-smena-roditelskogo-komponenta-dlia-animatora/ : но мне нужно также событие AnimationFinish, по нему происходит смена содержимого ListBox. (Пишу компонент файл-менеджера для одного проекта). Update: Вроде нашел решение, все работает. Подскажите корректно ли я это делаю? procedure TFormMain.FormCreate(Sender: TObject); begin FloatAnimation.Parent:=Nil; // FloatAnimation создан в дизайнатйме, лежит на форме, поэтому нужно так сделать. FloatAnimation.Enabled:=False; end; procedure TFormMain.ListBoxFilesItemClick(const Sender: TCustomListBox; const Item: TListBoxItem); begin CurrentItem:=Item; if CurrentItem.Tag=1 then // Смена папки begin FloatAnimation.Parent:=Item; FloatAnimation.PropertyName:='Opacity'; FloatAnimation.Enabled:=True; FloatAnimation.Start; end; end; procedure TFormMain.FloatAnimationFinish(Sender: TObject); begin FloatAnimation.Enabled:=False; FloatAnimation.Parent:=Nil; FillListBoxFile(CurrentItem.TagString); end; Причем без этого куска кода: FloatAnimation.Enabled:=False; FloatAnimation.Parent:=Nil; работать не хочет. Хотя работает и ладно... ;-) -
Подскажите где закралась ошибка. Процедура должна отправлять файл через намерение (файл текстовый). aFileName:='/storage/emulated/0/Download/test/тестовый файл для отправки.out.txt'; aComment:='Комментарий к файлу'; procedure ShareFile(aFileName, aComment : String); var Intent : JIntent; uri : Jnet_Uri; AttachmentFile: JFile; begin Intent := TJIntent.Create; Intent.setAction(TJIntent.JavaClass.ACTION_SEND); Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK); Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(aComment)); Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(aComment)); AttachmentFile := TJFile.JavaClass.init(StringToJString(aFileName)); Uri := TJnet_Uri.JavaClass.fromFile(AttachmentFile); Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, TJParcelable.Wrap((Uri as ILocalObject).GetObjectID)); Intent.setType(StringToJString('text/plain')); SharedActivity.startActivity(Intent); end; Наблюдаю следующее: Gmail - все отлично, файл присоединён, комментарий в теме письма DropBox - все отлично, файл передан Google Drive - файл передан, но у него отрезано расширение (в папке лежит файл с именем "тестовый файл для отправки") Yandex Disk - все работает Облако Mail.ru - предлагает создать текстовый файл ("Новый текстовый файл.txt"), в который записывает только две одинаковые строчки "Комментарий к файлу" Уже весь мозг сломал. А заказчик требует работу через все эти системы.
- 23 ответа
-
- JIntent
- ACTION_SEND
-
(и ещё 1 )
C тегом:
-
Да, точно. Дезинформировал в прошлом посте. У меня вот так: implementation {$IFDEF ANDROID} uses FMX.PushNotification.Android; Var APushService : TPushService; AServiceConnection : TPushServiceConnection; {$ENDIF ANDROID}
-
В uses должно быть только System.PushNotification. В опциях проекта отметили Receive push notifications?
-
Огромное спасибо!!! Все заработало! Проблема видимо в косячном примере от embarcadero. Проверку InAppPurchase.IsProductPurchased(ProductId) необходимо выполнять в событии OnProductsRequestResponse, т.е. после завершения ,видимо ассинхронного, InAppPurchase.QueryProducts. А никак не в OnSetupComplete как в примере от Embarcadero "CapitalIAP". Кстати в Delphi 10 тот же косяк в примере, видимо они даже не пробовали проверять его работоспособность.
-
Купил сам у себя, не через тестовый аккаунт. Деньги списались,в "Payments Merchant Center" покупка отобразилась. Но FInAppPurchase.IsProductPurchased(NoAdsID) мне говорит False, не куплен продукт. Что делать, ума не приложу.
-
InAppPurchase.IsProductPurchased работает на тестовых аккаунтах? Сделал покупку, но IsProductPurchased всегда возвращает False. procedure TFormMain.InAppPurchaseSetupComplete(Sender: TObject); begin LogMy('InAppPurchaseSetupComplete'); FInAppPurchase.QueryProducts; if FInAppPurchase.IsProductPurchased(NoAdsID) then begin LogMy(NoAdsID+' Yes ProductPurchased'); Буду очень благодарен, если кто даст ссылку на нормальную документацию, желательно на русском. Хочется понять хотя бы основные вещи, к примеру что такое метод ConsumeProducts (потреблять продукты?). И возможна ли отладка InAppPurchase? Запуск в отладочной версии не позволяет работать с InAppPurchase.
-
Virtual Keboard как раз есть и видима. Так что не вариант. Кстати события OnVirtualKeyboardHidden и OnVirtualKeyboardShown в XE8 работают не стабильно, иногда с секундными задержками, иногда вообще забывают срабатывать. Видимость лучше проверять с помощью function TFormMain.KeyboardVisible : Boolean;var Keyboard: IFMXVirtualKeyboardService; begin Result:=False; if TPlatformServices.Current.SupportsPlatformService( IFMXVirtualKeyboardService, IInterface( Keyboard ) ) then Result:=TVirtualKeyboardState.Visible in Keyboard.GetVirtualKeyBoardState; end;
-
Delphi XE8, Android. Возможно ли определить источник ввода символов в TEdit? Т.е. откуда приходит ввод - виртуальная клавиатура или внешняя usb или блютус клавиатура (в моём случае это сканеры штрих кодов)
-
Var HDevicePushParams : TDevicePushParams; APushService : TPushService; AServiceConnection : TPushServiceConnection; SQuery : String; begin APushService:=TPushServiceManager.Instance.GetServiceByName(TPushService.TServiceNames.GCM); APushService.AppProps[TPushService.TAppPropNames.GCMAppID]:='ХХХХХХХХХХХХХХХХ'; AServiceConnection:=TPushServiceConnection.Create(APushService); AServiceConnection.Active:=True; AServiceConnection.OnChange:=ServiceConnectionOnChange; AServiceConnection.OnReceiveNotification:=ServiceConnectionOnReceiveNotification; HDevicePushParams.DeviceID:=APushService.DeviceIDValue[TPushService.TDeviceIDNames.DeviceID]; HDevicePushParams.DeviceToken:=APushService.DeviceTokenValue[TPushService.TDeviceTokenNames.DeviceToken]; SQuery:=APIURL+'?DeviceID='+HDevicePushParams.DeviceID+'&DeviceToken='+HDevicePushParams.DeviceToken; HTTPThread:=THTTPThread.Create(SQuery,FQueue); // Здесь просто отправка на сервер в потоке. Сервер принимает стоку и складывает в базу пары "DeviceID - DeviceToken", можно еще что нибудь отправлять, чтоб точно идентифицировать клиента. А на сервере все еще проще. Вот php: $title = 'Это заголовок'; $message = 'Это текст сообщения.' $devices = 'DeviceToken - один конкретный получатель'; $apiKey = "AIzaХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХ"; $gcpm = new GCMPushMessage($apiKey); $gcpm->setDevices($devices); $response = $gcpm->send($message, array('title' => $title)); Лениво было писать велосипед, использовал готовую отсылалку https://github.com/mattg888/GCM-PHP-Server-Push-Message . Там все просто, она заворачивает все в json и отправляет на http
-
Delphi XE8, Android. Пишу слайдер картинок. Задачу себе поставил аналогичную слайдеру Ввконтакте. Т.е. Жестами листаем налево/направо, двойной клик увеличение, повторный двойной клик уменьшение, ну и пальцами можно растягивать изображения. Все работало замечательно до момента добавления анимации. Слайд (TImage) лежит в TScrollBox. Анимация увеличения (FloatAnimation) тоже отлично работает. Но позиционирование картинки сделать не могу с анимацией, анимацию не могу привязать к ViewportPosition. В итоге, при увеличении картинки, не область по которой ткнули, а по уродски - левый верхний угол остаётся зафиксированным, увеличивается вправо и вниз. Как можно связать FloatAnimation и ViewportPosition ?
- 1 ответ
-
- Delphi XE8
- Android
-
(и ещё 3 )
C тегом: