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

Андрей Рулин

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

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

  • Посещение

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

    1

Весь контент Андрей Рулин

  1. Buf1,Buf2 : Array[0..13100] of byte; FileByte : File of byte; Len : array[0..7] of integer = (26,20,26,131,13100,36,36,36); В отдельном потоке читаем файл. После каждого чтения поток "засыпает". Если у нас осталось меньше 13100 байт, опять будим поток. Вот ещё вариант, накодил сегодня. procedure TThreadSignal.Execute; begin inherited; while True do begin fCompleted := False; Task[fi].Solve; fCompleted := True; Suspend; end; end; Тут вообще андройдовская версия намертво повисает. А под win32 всё исправно работает, производит вычисления. Тут идея тоже самая почти. Надо провести 4 вычисления параллельно. Потом дождаться , пока все 4 выполнятся и идти дальше.
  2. В ходи анализа обнаружилось, что первый раз приложение открывается в любом положении экрана. Потом , если нажать кнопку "Выход", в которой выполняется метод Close; , то потом эта проблема и возникает.
  3. Очередная "чуча" от fmx(Delphi 10 Seattle) Если просто читать без потока , кода работает на обоих платформах begin if ThreadFile.BytesReady<=ThreadFile.Counter then begin BlockRead(FileByte,ThreadFile.Buf1,Len[4]); ThreadFile.Counter := 0; ThreadFile.BytesReady :=Len[4]; end; Move(ThreadFile.Buf1[ThreadFile.Counter],GetHidBufPointer^,Len[3]); ThreadFile.Counter := ThreadFile.Counter + Len[3]; end; Если использовать потоки begin if ThreadFile.BytesReady=0 then begin BlockRead(FileByte,ThreadFile.Buf1,Len[4]); ThreadFile.BackBuf := False; ThreadFile.BytesReady := Len[4]; ThreadFile.Resume; end; if ThreadFile.Counter=ThreadFile.BytesReady then begin ThreadFile.Counter := 0; ThreadFile.BytesReady :=0; ThreadFile.BackBuf := not ThreadFile.BackBuf; ThreadFile.Resume; end; if ThreadFile.BackBuf then Move(ThreadFile.Buf2[ThreadFile.Counter],GetHidBufPointer^,Len[3]) else Move(ThreadFile.Buf1[ThreadFile.Counter],GetHidBufPointer^,Len[3]); ThreadFile.Counter := ThreadFile.Counter + Len[3]; end; //------------- procedure TThreadFile.Execute; begin inherited; while True do begin if BackBuf then BlockRead(FileByte,Buf1,Len[4]) else BlockRead(FileByte,Buf2,Len[4]); BytesReady := BytesReady + Len[4]; Suspend; // Self. end; end; То в этом случае всё работает только в fmx в версии win32 . В Андройде , увы читаются нули. В принципе ошибка не критичная, т.к. второй вариант в итоге не даёт приросто производительности, но в общей случае настораживает.
  4. Стоит Delphi 10.0 Разрешены две ориентации экрана LandscapeHomeright и LandscapeHomeleft. При открытии в одной ориентации приложения чаще всего вылетает, когда форма показывается. При открытии во второй всё перевёрнутое, но зато не вылетает . Можно перевернуть экран и тогда тоже не вылетает. Ну и естественно в Windows всё нормальное работате, программа никогда не вылетает . Вопрос, что собственно это такое.
  5. При обновление приложении иногда обновляется иногда рандомно пишет "приложение не установлено". Остановка приложение не всегда помогает. Устройство Samsung Galaxy Tab 8 , Android 9 . Но было с другими устройствами и другими системами тоже.
  6. Допустим идут вычисления, мне надо в Label выводить, что они закончились на 10%...20%...100% После изменения текста я делаю Label1.Repaint; Invalidate; При этом текст не изменяется, пока не окончатся вычисления. Хотя в Vcl версии хватает Repaint для формы.
  7. Да, у меня на телефоне API 33. Я вот почитал https://developer.android.com/training/data-storage/use-cases#opt-out-scoped-storage , что теперь только Downloads получается открыта?
  8. Раньше у меня в директории assets она же android/data ,она же получаемая по TPath.GetSharedDocumentsPath располагался конфигурационный файл, который я мог править из файлового менеджера. Туда же скидывались логи и т.д. Начиная с версии 10.0 Android эту возможность прикрыли. Теперь android/data пуста, конфигурационный файл я не вижу. В 10-й версии причём как-то "через раз" работает. В 11-м уже железно не работает. Есть какая-это папка , которая доступна и для программы и для файлового менеджера? Или можно в assets как-то доступ из файлового менеджера получить?
  9. Решил я загрузить на Samsung Galaxy Store своё приложение. При этом на Google Play Store аккаунта не имеют. Мне приложение заморозили по причине "Play Protect pop-up appears during installation." - то есть , что ругается защитник. Как показало гугление, для того, чтобы он не ругался надо загрузить приложение сначала на Google Play Store. Вопрос , кто-то работал с а Samsung Galaxy Store? Можно к ним загружать уникальные приложения. Или только те, что на Google Play Store уже загрузил(тогда непонятно зачем они вообще нужны).
  10. krapotkin - может вы и правы. Потестирую на других устройствах пока тестировал на Samsung A71. Вот ещё что есть интересного. Я протестировал в режиме портретном, там угол экрана всё-таки ровно по центру пальца оказывается. А в ланшафтном - увы. Slym - я пробовал нажимать стандартные иконки. Там именно реакция на нажатие именно по центру пальца. Что в портретном режиме, что в ландшафтном. --- UPD - на планшете Galaxy Tab 8a всё работает, левый верхний угол именно по центру. UPD2 - на Galaxy A6+ тоже работает. UPD3 - на A71 фронтальная камера расположена прямо на экране. При клике на фронтальную камеру ничего не происходит. При клике сверху или снизу камеры(если держать в ландшафтной ориентации) тоже никакой реакции. Если кликнуть чуть правее камеры, то левая часть прямоугольника устанавливается ровно слева от экрана. То есть сдвиг идёт ровно на ширину этой фронтальной камеры.
  11. С помощью старших товарищей на этом форуме я научился отображать прямоугольники. Вот код, который мне подсказали. procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin FCrd := PointF(X,Y); end; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin Invalidate; end; procedure TForm1.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF); begin Canvas.Fill.Color := TAlphaColorRec.Wheat; Canvas.FillRect(rectf(FCrd.X, FCrd.Y, FCrd.X+100, FCrd.Y+100), 0,0,[], 1); end; Так вот в Windows , если нажать курсор, то как мы и ожидаем, левый верхний угол прямоугольника будет установлен именно туда , куда мы нажали. В Andoroid же левый верхний угол устанавливается где-то по левой верхней части пальца. А ожидается, что он будет установлен в центр пальца. В связи с этим вопросы. 1) X,Y -это координаты центра пальца или левой верхней его части? 2) Как получить координаты именно куда нажал центр пальца? Ведь я не знаю ни размера устройства ни размера пальца, поэтому просто прибавлять к X,Y какое-то значение, это такое себе.. В справке удалось нарыть только это - http://docwiki.embarcadero.com/Libraries/Sydney/en/FMX.Controls.TControl.MouseDown . Так никак не описывается поведение на планшетах.
  12. Большое спасибо! Invalidate действительно работает и в моём проекте тоже, если поставить вместо InvalidateRect.
  13. Увы, и это не работает. InvalidateRect(WinRect); //FormPaint(Sender,Canvas,TestRect); WinRect - посылается размер окна. Естественно на win32 работает и этот вариант. Ну на VCL - это был скорее фича , можно было всё без танцев с бубном делать. Но на FMX на разных платформах должно работать единообразно - или везде или нигде. ПОтому , что любую программу надо будет тестировать на win32/64 , потом так же тщательно на Android , а потом ещё и на IoS. Вот у меня устойств с IOS нет , я уже понял, то доступ раз в недёлю "отца русской демократии" не спасёт.
  14. Да , так работает лучше, но всё же всё-рано что-то не так. Вот я отрабатываю клик мышкой. TestRect.Left := XToEtalon(X)-50; TestRect.Top := XToEtalon(Y)-50; FormPaint(Sender,Canvas,TestRect); WriteToLog(report,FloatToStr(X)+' , '+ FloatToStr(Y)); И соотвественно, redraw(0,0,1,false); redraw(Round(ARect.Left),Round(ARect.Top),1,true); В итоге в Win32 всё работает отлично - куда я щёлкаю мышкой, появляются прямоугольники. В Android - нулевая реакция. При этом в логе записывается , что клик произошёл. Test2.rar
  15. Данный код работает в windows-32 , но не хочет работать в Android. Form1.Canvas.BeginScene; Form1.Canvas.Fill.Kind := TBrushKind.bkSolid; Form1.Canvas.Fill.Color := TAlphaColorRec.Red; form1.Canvas.FillRect(fs,0,0,AllCorners,1); Form1.Canvas.EndScene; Просто ничего не отрисовывается. В чём может быть причина? Прикрепляют также тестовый проект, вдруг на какой-то версии он нормально работает. Test.rar
  16. Пример который я выше привёл, всё-таки рабочий(на запись). Но в Delphi XE7 и ниже неправильно компилируется. В Delphi 10 нормально компилируется.
  17. bytes_written := FUsbDeviceConnection.bulkTransfer({FUsbEPBO}FUsbEPII, Buffer, Size, 100); Что характерно, если так вот записать, то есть пытаться передать данные в не ту EndPoint всё равно выдаёт,что передано 3 байта. Истина, похоже где-то рядом...
  18. Я вот кстати пробовал реализовать более простой пример подключения , чем в этой библиотеке. //NewUSB:=TUSB.Create; FEpOut:=nil; Memo1.Lines.Append('Begin'); if UsbManager=nil then UsbManager:= TJvHidDeviceController.Create(Self); //usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager DeviceList := UsbManager.FUsbManager.getDeviceList; iter := DeviceList.values.iterator; while iter.hasNext do begin LocalUSBDevice := TJUSBDevice.Wrap((iter.next as ILocalObject).GetObjectID); if (LocalUSBDevice.getVendorId <> VENDOR) or (LocalUSBDevice.getproductId <> PRODUCT) then continue;//continue; Memo1.Lines.Append('Stage 1'); for i:=0 to LocalUsbDevice.getInterfaceCount-1 do begin Memo1.Lines.Append('Stage 2'); LocalUsbInterface := LocalUsbDevice.getInterface(0); if LocalUsbInterface.getInterfaceClass=3 then break; end; //Open end; if NOT UsbManager.UsbManager.hasPermission(LocalUSBDevice) then begin PermissionIntent:=TJPendingIntent.JavaClass.getBroadcast(SharedActivityContext, 0, TJIntent.JavaClass.init(StringToJString(ACTION_USB_PERMISSION)), 0); Filter := TJIntentFilter.JavaClass.init; Filter.addAction(StringToJString(ACTION_USB_PERMISSION)); FBroadcastReceiverListener := TBroadcastReceiverListener.Create(UsbManager); FReceiver := TJFMXBroadcastReceiver.JavaClass.init(FBroadcastReceiverListener); SharedActivityContext.getApplicationContext.registerReceiver( FReceiver, Filter); UsbManager.UsbManager.requestPermission(LocalUSBDevice,PermissionIntent); exit; end; if LocalUsbInterface=nil then exit else Memo1.Lines.Append('Stage 3'); for I := 0 to LocalUsbInterface.getEndpointCount-1 do begin FUsbEP := LocalUsbInterface.getEndpoint(i); if FUsbEP.getType=3 then begin if FUsbEP.getDirection = TJUsbConstantsUSB_DIR_OUT then begin if FEpOut=nil then FEpOut := FUsbEP; end else if FUsbEP.getDirection = TJUsbConstantsUSB_DIR_IN then begin if FEpIn=nil then FEpIn := FUsbEP; end; end; end; if {(EpIn=nil) AND} (FEpOut=nil) then exit; Memo1.Lines.Append('Stage 4'); // Open device FUsbDeviceConnection := UsbManager.UsbManager.openDevice(LocalUSBDevice); if not assigned( FUsbDeviceConnection) then exit; Memo1.Lines.Append('Stage 5'); if not FUsbDeviceConnection.claimInterface(LocalUsbInterface, True) then exit; Memo1.Lines.Append('Stage 6'); btnHIDEnable.Enabled := True; btnGetSerial.Enabled := True; //FUsbDeviceConnection. Соотвественно, передача делается через S:=IntToStr(FUsbDeviceConnection.bulkTransfer(FEpOut, Buffer, {Buffer.Length}3, 0)); //можно 0 Memo1.Lines.Append('Retval = '+S); Он кстати при подключении пишет, что всё нормально. Но при попытке отправки данных увы, ничего не передаёт. Даже более того, другие программы на Java , запущенные параллельно тоже после моей не могут ничего передать.
  19. Вот например есть https://github.com/LongDirtyAnimAlf/Delphi-Android-USB-HID . К сожалению библиотека старая , не использует возможности последний версий API . И, подозреваю, глючная.
  20. В итоге для определеления имени продукта изменил код на FProductName := JStringToString(FUsbDevice.getProductName); Вместо Серийный номер так и не получилось получать.
  21. Приведу куски кода, которые , собственно эту хрень и вызывают. function THidServer.DeviceName(HidDev: TJvHidDevice): string; begin if HidDev.ProductName <> '' then Result := HidDev.ProductName else Result := Format('Device VID=%.4x PID=%.4x', [HidDev.Attributes.VendorID, HidDev.Attributes.ProductID]); if HidDev.SerialNumber <> '' then Result := Result + Format(' (Serial=%s)', [HidDev.SerialNumber]); end; Соотвественно HidDev.ProductName и HidDev.SerialNumber получаем так function TJvHidDevice.GetProductName: String; begin if FProductName = '' then begin FProductName := GetDeviceString(2); //FProductName := JStringToString(FUsbDevice.getDeviceName); end; Result := FProductName; end; function TJvHidDevice.GetSerialNumber: String; begin if FSerialNumber = '' then begin FSerialNumber:=GetDeviceString(3); //if Openfile then FSerialNumber:=JStringToString(FUsbDeviceConnection.getSerial); end; Result := FSerialNumber; end; Наконец GetDeviceString - это вот что: function TJvHidDevice.GetDeviceString(Idx: Byte): string; const STD_USB_REQUEST_GET_DESCRIPTOR = $06; STD_USB_REQUEST_GET_REPORT = $01; LIBUSB_FEATURE_REPORT = $0301; //Feature report, ID = 1 LIBUSB_DT_STRING = $03; var i,rdo:integer; rawDescs,buffer : TJavaArray<Byte>; requestidx:integer; S : String; begin if Openfile then begin rawDescs := FUsbDeviceConnection.getRawDescriptors; if (13+Idx)>rawDescs.Length then begin result:=''; exit; end; requestidx := rawDescs[13+Idx]; rawDescs.Free; buffer := TJavaArray<Byte>.Create(255); rdo := FUsbDeviceConnection.controlTransfer( (TJUsbConstantsUSB_DIR_IN OR TJUsbConstantsUSB_TYPE_STANDARD), STD_USB_REQUEST_GET_DESCRIPTOR, ((LIBUSB_DT_STRING SHL 8) OR requestidx), 0, buffer, $FF, 0); if rdo>100 then rdo:=100; if rdo<3 then begin result:=''; exit; end; S:=''; for i:=1 to (rdo-2) do begin S:=S+Char(buffer.Items[i+1]); end; result:=S; buffer.Free; end else result:=''; end; Если изменить кусок кода так чтобы в явном виде выдавался код символов. В итоге получается такой лог Arrival of #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 (Serial= #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0 #0)
  22. Андрей Рулин

    device_filter.xml

    Устанавливая в device_filter.xml устройство, с которым хочу работать. Например для PicKIT3 ставлю <usb-device vendor-id="1240" product-id="36874"/> После этого при подключении данного устройства он предлагает выполнить мою программу. Это было ожидаемый результат. Неожидаемый результат, что если не прописать это устройство, то например выдаётся Device VID=04D8 PID=900 А если устройство прописать, то выдаётся хрень вида (Serial= ) Это что, особенность планшета? Или это потому, что я к нему не правильно подключился? Или я как-то в лог могу неправильно записывать то, что он прислал?
  23. Большое спасибо, всё заработало. Только у меня XE7, поэтому изменил параметр "Key: package"
  24. Мне надо установить две версии своей программы на один планшет. Но при установке система говорит, что это я старую пытаюсь обновить. И по итогу установлена оказывается одна(которую я последней установил). Переименование проекта не спасает, он всё равно считает, что это одна и та же программа. Как заставить систему их различать?
×
×
  • Создать...