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

x11

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

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

  • Посещение

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

    13

Весь контент x11

  1. Нашёл в логах андроида при смахивании приложения с экрана: Т.е. служба почему-то закрывается аварийно. Broadcast reciever создавался в событии StartCommand, продублировал ещё и в OnCreate DataModule.
  2. x11

    Failure retrieving resources

    Когда нажимаю на смартфоне кнопку для вызова списка запущенных приложений, то получаю в логах андроида ошибку: Что это за "Resource ID #0x0" и где это искать?
  3. Подскажите, в чем может быть причина? При запущенном приложении и службе работает Broadcast reciever (он внутри службы). И успешно получается перехватывать события, т.е. BroadcastReceiver.OnReceive срабатывает. Как только закрываю приложение (смахиваю его с экрана), чтобы служба осталась работать, сразу Broadcast reciever ничего не ловит. Хотя вижу, что служба работает, в логах нет ничего связанного с удалением Broadcast reciever. И даже вижу, что само приложение потом Андроидом запускается. Тут же идея такова, что даже при закрытом приложении, должна срабатывать BroadcastReceiver.OnReceive.
  4. Для Windows всё и так давно понятно - зупустил, работает. Никаких установок и delpoy выполнять не требуется. Винда/среда не даст запустить второй раз программу, если она уже запущена (по этому пути). А вот для Андроида всё сложнее. Например, в настройках deployment есть колонка Overwrite. и везде, у всех строк - Always. И тут проблема в том, что overwrite (перезапись) не работает. Т.е. я в базу добавил поле, запускаю на устройстве аппликацию и получаю ошибку, т.к. оказывается, что на устройство новый файл sqlite базы не попал. Странность в том, что когда я запускаю приложение из среды по F9, то я вижу, что и Deploy выполняется и в строке проскакивает имя базы. Так выполняется или не выполняется? Т.е. какие вообще приготовления нужно сделать, чтобы на устройство попало всё, что в deploy? И нужно ли предварительно выполнять полное удаление с очисткой данных на устройстве? Т.к., как я уже выше описал, файл могут не заменятся. Нужно ли перед запуском закрывать на устройстве приложение или Андроид его сам закроет перед установкой? Какие ещё могут быть тонкости/нюансы? Спасибо.
  5. А вот в настройках проекта самого сервиса у меня своё название, не com.embarcadera.... и работает ведь.
  6. И ещё не понятно, как работает код, когда у контакта в адресной книге есть 2 номера телефона. Я проверил - оба функция находит, но где это, в каком месте кода, я не понял.
  7. Вот мне подсказали на sql.ru рабочий пример, который и у меня получилось использовать в службе. Я так понимаю, что приходится в этом случае получать полностью всю адресную книгу и потом перебирать её у себя в коде циклом, что не совсем правильно. Пример компилируется и работает на Delphi Tokyo: function GetContactByNumbers(const aPhoneNumbers: TList<String>): string; var wUri: JNet_URI; lookupID: String; wCursor, wSubCursor: JCursor; wLookup_Idx: Integer; wDisplayNameIdx: integer; wfilter, wJQueryParams: TJavaObjectArray<JString>; wDataUri: JNet_URI; begin wUri := TJContactsContract_Contacts.JavaClass.CONTENT_URI; wCursor := TAndroidHelper.Context.getContentResolver.query(wUri, nil, nil, nil, StringToJString('display_name ASC')); try wLookup_Idx := wCursor.getColumnIndex(StringToJString('lookup')); wDisplayNameIdx := wCursor.getColumnIndex(StringToJString('display_name')); while wCursor.moveToNext do begin lookupID := JStringToString(wCursor.getString(wLookup_Idx)); wfilter := TJavaObjectArray<JString>.Create(1); wfilter[0] := TJCommonDataKinds_Phone.JavaClass.NUMBER; // Qurey condition (Exrtact only data for specific ID) wJQueryParams := TJavaObjectArray<JString>.Create(2); wJQueryParams[0] := TJCommonDataKinds_Phone.JavaClass.CONTENT_ITEM_TYPE; wJQueryParams[1] := StringToJString(lookupID); wDataUri := TJContactsContract_Data.JavaClass.CONTENT_URI; // Contacts data uri wSubCursor := TAndroidHelper.Context.getContentResolver. Query(wDataUri,wfilter,StringToJString('mimetype = ? AND lookup = ?') , wJQueryParams,nil); // Exec query try if wSubCursor.getCount > 0 then begin while (wSubCursor.moveToNext) do begin if aPhoneNumbers.Contains(JStringToString(wSubCursor.getString(0))) then begin Result := JStringToString(wCursor.getString(wDisplayNameIdx)); Break; end; end; end; finally wSubCursor.close; wSubCursor := nil; end; end; finally wCursor.Close; wCursor := nil; end; end; К сожалению, в справке по Delphi нет описания TJContactsContract_Contacts, TJCommonDataKinds_Phone и TAndroidHelper.Context.getContentResolver.query. И примеров нет. И пример использования: // В USES нужно добавить System.Generics.Collections для TList. VAR ListNumbers: TList<string>; begin ListNumbers := TList<string>.Create; try ListNumbers.Add(sTel);// передаем полный номер: +380681234567 ListNumbers.Add(RightStr(sTel, 10));// если в адресной книге записан номер без кода оператора - 0681234567 ContactName := GetContactByNumbers(ListNumbers); finally FreeAndNil(ListNumbers); end;
  8. В том-то и дело, что не получается. Вот пример (см там, где 79 оценок) https://stackoverflow.com/questions/3712112/search-contact-by-phone-number как его перевести в Delphi?
  9. Вы про код сейчас или про настройки проекта?
  10. Для решения задачи, по идее, мне нужна только одна маленькая процедура. Т.е. получается за многолетнюю историю FMX я сейчас пока что единственный, кому понадобилось выполнить поиск контакта по номеру в сервисе? Ну или другой поиск в адресной книге Андроида.
  11. Создал пустое приложение из одной формы, запустил. Та же проблема: приложение почему-то лезет туда, куда не следует.
  12. Взял файл, удалил из uses все упоминания, начинающиеся с FMX, "прикрепил" к проекту, при попытке скомпилировать - 70+ ошибок.
  13. Спасибо, конечно... но... На сколько я знаю, то FMX.AddressBook тянет за собой всю адресную книгу себе... зачем? Ну и я не настолько в этом разбираюсь, чтобы правильно что-то "убрать".
  14. Есть такой пример поиска имени контакта по номеру телефона. Он компилируется, работает, но номер телефона не находит. function TDMSrv.GetContactByPhoneNumber(const sTel: string): string; var wJDislpayName, wJFirstName, wJLastName, wJQueryStr: JString; wJQueryParams: TJavaObjectArray<JString>; wSubCursor: JCursor; wfilter: TJavaObjectArray<JString>; wDataUri: JNet_URI; begin if sTel.IsEmpty then begin log('GetContactByPhoneNumber. Phone number is empty!'); exit; end; wDataUri := TJContactsContract_Data.JavaClass.CONTENT_URI; wfilter := TJavaObjectArray<JString>.Create(3); wfilter[0] := TJCommonDataKinds_StructuredName.JavaClass.DISPLAY_NAME; wfilter[1] := TJCommonDataKinds_StructuredName.JavaClass.FAMILY_NAME; wfilter[2] := TJCommonDataKinds_StructuredName.JavaClass.GIVEN_NAME; wJQueryStr := StringToJString('mimetype = ? AND lookup = ?'); wJQueryParams := TJavaObjectArray<JString>.Create(2); wJQueryParams[0] := TJCommonDataKinds_Phone.JavaClass.NUMBER; wJQueryParams[1] := StringToJString(sTel); wSubCursor := TAndroidHelper.Context.getContentResolver.Query(wDataUri, wfilter, wJQueryStr, wJQueryParams, nil); try if wSubCursor.getCount > 0 then begin // Getting only first row, as we retrieving only names, a contact can have only one first name, one familyname, // for phone number for example, we need to loop on each row (while (wSubCursor.moveToNext) do) because a contact can have many phone number log('wSubCursor.getCount = ' + wSubCursor.getCount.ToString); wSubCursor.moveToNext; wJDislpayName := wSubCursor.getString(0); wJLastName := wSubCursor.getString(1); wJFirstName := wSubCursor.getString(2); end else log('wSubCursor.getCount = 0'); Result := JStringToString(wJDislpayName); finally wSubCursor.close; FreeAndNil(wSubCursor);// := nil; end; end;
  15. Всё-таки есть у кого-нибудь рабочий пример поиска имени по номеру телефона? Буду премного благодарен.
  16. А как быть со службой? Если в USES есть FMX.AddressBook, то в службах это работать не будет.
  17. Убрал права WRITE_EXTERNAL_STORAGE. Проблема осталась.
  18. Я про то, что можно досить не только мускуль, но и другие сервисы. SSH сервер же тоже открыт бывает.
  19. В логах вижу ошибку 3 раза при старте приложения. В коде нет ничего, что запрашивало бы доступ к внешней карте памяти. В Deploymet что может быть такого, что будет запрашивать такой путь? Deploymet и в коде есть пара файлов, но они складываются в: Deploymet: .\assets\internal\db Код: /data/data/имя_пакета/files/db/имя_базы.sqlite Может ли это быть связано с правами? В правах есть "read external storage" и "write external storage". А что это за папка "obb" я вообще не имею представления.
  20. Порт к базе мускула, например, открыт, выставлена база несколько лет уже наружу. Пока норм. Ну т.е. я не совсем корректно написал. Не всегда будут проблемы. Хотя - это не есть хорошо. С другой стороны, все же выставляют наружу тот же http или http+API. Если будет целенаправленная атака, то вы хоть что там закрывайте, всё равно будут проблемы.
  21. Решение нашёл здесь https://stackoverflow.com/questions/34262554/how-to-check-if-a-service-is-running-in-delphi-10-seattle/34264464#34264464
  22. Я не пойму, как правильно стартовать службу и именовать пакеты. Подскажите. Есть пакет хост-приложения и пакет службы. В options обоих пакетов, в VersionInfo, в строке package прописано одинаково "com.maindomain.$(ModuleName)". А для создания и старта службы есть код: const MyPackageName = 'com.embarcadero.services.CallerIdSrv'; ... ... ... FService := TJIntent.Create; FService.setClassName(TAndroidHelper.Context.getPackageName, TAndroidHelper.StringToJString(MyPackageName)); FService.setAction(StringToJString('StartService')); TAndroidHelper.Activity.startService(FService); так служба запускается. А если MyPackageName = 'com.maindomain.CallerIdSrv', то так служба не запускается и ошибок (исключений) нет. Что это setClassName и что она делает? Что нужно туда передавать, как правильно? В справке не нашел. Спасибо.
  23. Как проверить, работает ли моя служба? Т.е. перед запуском или остановкой хочется выполнить проверку. FService := TJIntent.Create; FService.setClassName(TAndroidHelper.Context.getPackageName, TAndroidHelper.StringToJString('com.embarcadero.services.pak1')); FService.setAction(StringToJString('StopService')); TAndroidHelper.Activity.startService(FService);
  24. Событие "android.intent.action.PHONE_STATE" - это и есть отслеживание входящего звонка, т.е. смена состояния телефона. Других событий для отслеживания входящего звонка вроде бы нету. Если есть, подскажите решение. Спасибо.
×
×
  • Создать...