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

Android 10 и муз.плеер


Ingalime

Вопрос

Здравствуйте. Есть приложение музыкального плеера со службой переднего фона, которая позволяет проигрывать музыку даже если приложение свернуто. Без этой службы андроид убивает приложение через пару минут если оно свернуто. Приложение работает на андроид 7.1, 8.1 и 9. Других устройств для тестирования нет. На андроид 10 приложение при старте сразу падает. Возникла мысль, что андроид 10 не может запустить службу переднего плана. Код:

procedure TForm1.FormCreate(Sender: TObject);
Begin
//Библиотека BASS для аудио http://www.un4seen.com/
 if not BASS_Init(-1, 44100, 0, nil, nil) Then Begin
	   ShowMessage('Failed to initialize audio!' + sLineBreak + 'Не удалось инициализировать audio!');
     Exit;
     end;

 try
     if FService = Nil Then Begin
      FService := TLocalServiceConnection.Create;
      FService.StartService('serPublic');
      end;
  except
       Exit;
  end;

Пользователь форума Tumaso, предложил код как отменить запуск службы для андроид 10. Лучше уж пусть приложение играет на переднем плане, чем просто падает при старте.

uses
    ... Androidapi.JNI.Os, Androidapi.JNIBridge ...
//изменения при страте в FormCreate
  if TJBuild_VERSION.JavaClass.SDK_INT <= 28 then
  begin
    try
      if not Assigned(FService) then
      begin
        FService := TLocalServiceConnection.Create;
        FService.StartService('serPublic');
      end;
    except
      // что нибудь делаем
    end;  
  end;

Но возникает еще вопрос, а может для андроид 10 надо запросить какие-то дополнительные разрешения или что-то добавить в манифест? Сейчас из разрешений в опциях проекта стоит Foreground service и Internet. Устройства с андроид 10 у меня нет. Ниже код службы, за который меня не ругайте, это солянка найденная в интернете и этот код прекрасно работает на андроид 7.1, 8.1 и 9.

unit Unit1;

interface

uses
  System.SysUtils,
  System.Classes,
  System.Android.Service,
  AndroidApi.JNI.GraphicsContentViewText,
  Androidapi.JNI.Os,
  Androidapi.JNI.App,
  Androidapi.JNI.Support,
  Androidapi.JNI.JavaTypes,
  Androidapi.Helpers,
  Androidapi.JNIBridge,
  Androidapi.Jni,
  System.Notification;

type
  TDM = class(TAndroidService)
    NotificationCenter1: TNotificationCenter;
    function AndroidServiceStartCommand(const Sender: TObject;
      const Intent: JIntent; Flags, StartId: Integer): Integer;

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  DM: TDM;

implementation

{%CLASSGROUP 'FMX.Controls.TControl'}

{$R *.dfm}



function TDM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;

var
  //Android 8.1, 9
  ServiceChannel: JNotificationChannel;
  NotificationManager: JNotificationManager;
  Obj: JObject;
  NewIntent: JIntent;
  ncb: JNotificationCompat_Builder;
  ntf: JNotification;
  PendingIntent: JPendingIntent;
  //Android 7.1
  service             : JService;
  serviceObjectId     : Pointer;
  ntf2                : JNotification;
  intent2             : JIntent;
  PendingIntent2      : JPendingIntent;

begin

   Result := TJService.JavaClass.START_NOT_STICKY;

   // can't ref .O on earlier phones, must hardcode
  if TJBuild_VERSION.JavaClass.SDK_INT > 26 then // JBuild_VERSION_CODES.JavaClass.O
  begin
     //Android 8.1
     //new ways for SDK > 26 (won't be called when API < 26 anyways)
     try

      ServiceChannel := TJNotificationChannel.JavaClass.init(
      StringtoJString('com.radio.one'), //CHANNEL_ID
      StrToJCharSequence('Public radio Channel'),
      TJNotificationManager.JavaClass.IMPORTANCE_DEFAULT
    );

    Obj := TAndroidHelper.Context.getSystemService(
    TJContext.JavaClass.NOTIFICATION_SERVICE);
    NotificationManager := TJNotificationManager.Wrap(Obj);
    NotificationManager.createNotificationChannel(ServiceChannel);

    NewIntent:= TAndroidHelper.Context.getPackageManager().getLaunchIntentForPackage(
      TAndroidHelper.Context.getPackageName());
    NewIntent.setAction(TJIntent.JavaClass.ACTION_MAIN);
    NewIntent.addCategory(TJIntent.JavaClass.CATEGORY_LAUNCHER);
    NewIntent.addFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);

    PendingIntent := TJPendingIntent.JavaClass.getActivity(
      TAndroidHelper.Context, 0, NewIntent,
      TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK
    );

    ncb := TJNotificationCompat_Builder.JavaClass.init(
      TAndroidHelper.Context,
      StringToJString('com.radio.one')
    );

   ncb.setContentTitle(StrToJCharSequence('PublicRadio Service'));
   // ncb.setTicker(StrToJCharSequence('MyCommsService')); // can't remember why this is commented out to be honest
   ncb.setSmallIcon(JavaService.getApplicationInfo.icon);
   ncb.setContentIntent(PendingIntent);
   ncb.setOngoing(True);
   ntf := ncb.build;
   JavaService.startForeground(StartId, ntf);
   except
       exit;
   end;

 end
 else
 begin
      //Android 7.1
     try
      serviceObjectId  := (JavaService as ILocalObject).GetObjectID;
      service          := TJService.Wrap(serviceObjectId);
      /////ntf2             := TJNotification.Create;
      ////ntf2.icon        := service.getApplicationInfo.icon;

    NewIntent:= TAndroidHelper.Context.getPackageManager().getLaunchIntentForPackage(
      TAndroidHelper.Context.getPackageName());
    NewIntent.setAction(TJIntent.JavaClass.ACTION_MAIN);
    NewIntent.addCategory(TJIntent.JavaClass.CATEGORY_LAUNCHER);
    NewIntent.addFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);

    PendingIntent2 := TJPendingIntent.JavaClass.getActivity(
      TAndroidHelper.Context, 0, NewIntent,
      TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK
    );

      ncb := TJNotificationCompat_Builder.JavaClass.init(
      TAndroidHelper.Context,
      StringToJString('com.radio.one')
    );

      //intent2  := TJIntent.Create;
      //PendingIntent2 := TJPendingIntent.JavaClass.getActivity(service.getApplicationContext, 0, intent2, 0);

      ncb.setContentTitle(StrToJCharSequence('PublicRadio'));
      // ncb.setTicker(StrToJCharSequence('MyCommsService'));
      ncb.setSmallIcon(JavaService.getApplicationInfo.icon);
      ncb.setContentIntent(PendingIntent2);
      ncb.setOngoing(True);
      ntf2 := ncb.build;

      ntf2.setLatestEventInfo(service.getApplicationContext, StrToJCharSequence('PublicRadio'), StrToJCharSequence('PublicRadio Service'), PendingIntent2);
      service.startForeground(StartId, ntf2);
   except
       exit;
   end;

  end;

end;

end.

 

Ссылка на комментарий
  • Ответы 60
  • Создана
  • Последний ответ

Лучшие авторы в вопросе

Рекомендуемые сообщения

  • 0
8 минут назад, Ingalime сказал:

Получается дело не в запуске сервиса, ведь запуск сервиса теперь в отдельной кнопке. Видимо что-то не так для этих версий андроида в манифесте...

Но у меня на десятке на Нокиа всё запускалось и работало. Надо бы действительно протестировать на разных устройствах, но у меня, к сожалению, у компьютера настолько древний процессор, что на нём просто не запускается эмулятор от Android Studio.

Ссылка на комментарий
  • 0

В общем, посмотрел я логи Вашего приложения через logcat. К ошибке приводило это:

FATAL EXCEPTION: main
Process: com.online.PublicRadio, PID: 25974
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.online.PublicRadio/com.embarcadero.firemonkey.FMXNativeActivity}: java.lang.IllegalArgumentException: Unable to find native library: PublicRadio
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java)
    at android.app.ActivityThread.access$1100(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java)
    at android.os.Handler.dispatchMessage(Handler.java)
    at android.os.Looper.loop(Looper.java)
    at android.app.ActivityThread.main(ActivityThread.java)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
Caused by: java.lang.IllegalArgumentException: Unable to find native library: PublicRadio
    at android.app.NativeActivity.onCreate(NativeActivity.java)
    at com.embarcadero.firemonkey.FMXNativeActivity.onCreate(FMXNativeActivity.java:135)
    at android.app.Activity.performCreate(Activity.java)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java)
    ... 10 more

 

А что это значит, Вы уже смотрите сами, так как доступа к Вашему коду я не имею.

Изменено пользователем PowerOwl
Ссылка на комментарий
  • 0
1 час назад, PowerOwl сказал:

А вообще, почему бы Вам не скинуть полностью проект, тогда можно было бы посмотреть, в каком месте возникает ошибка.

Там большие SO файлы библиотеки BASS, картинки. В ZIP архиве проект 280 Мг. Могу выложить на хостинг и дать ссылку, но вряд ли кто захочет такой размер скачать... Можно конечно уменьшить размер убрав какие-то временные файлы студии, но это моя первая программа на паскале, боюсь что-то удалять. :)

P.S.

А эмулятор не удалось запустить.

 

 

pic1.jpg

Ссылка на комментарий
  • 0
9 минут назад, Ingalime сказал:

А эмулятор не удалось запустить.

Попробуйте в BIOS включить "Secure virtual machine mode". И напишите, какой у Вас процессор.

9 минут назад, Ingalime сказал:

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

Можете выложить хотя бы .pas файл(-ы), чтобы хоть примерно представлять, в чём ошибка. Я выложил логи снятые с logcat, можете сами посмотреть, в чём там может быть проблема.

Изменено пользователем PowerOwl
Ссылка на комментарий
  • 0

Cкриншот деплоя 64 бит. 32 бит я не компилировала вообще.
С дебагом у меня тоже были проблемы. Компилятор ембаркадеро упорно писал что не может распознать Readmi5A и отваливался.
Компилировала в релизе с ShowMessage-ми в поисках ошибок. :)
Если у кого есть терпение на скачивание то ссылка на весь проект: http://nsnllc.um.la/delphi821FMX.zip

Проект у меня по пути C:\Users\Lena\Documents\Embarcadero\Studio\Projects\delphi82
Хотелось бы по окончании дискуссии, чтобы на этом форуме кто-то из специалистов выложил статью как правильно создать службу переднего плана в дельфи.
Служба весьма полезная, но централизованной информации нет и вообще все странно работает - в одних версиях нормально, в других падение.

 

deploy.jpg

Изменено пользователем Ingalime
Ссылка на комментарий
  • 0
18 минут назад, Andrey Efimov сказал:

По какой причине вы сняли галочки с записей связанных с libnative-activity.so?

Вроде это отвечает судя по папкам за 32 бит, которые я не использую. Компилировалась только 64 бит... Структура папок BASS:

 

 

32.jpg

Ссылка на комментарий
  • 0
57 минут назад, Ingalime сказал:

Хотелось бы по окончании дискуссии, чтобы на этом форуме кто-то из специалистов выложил статью как правильно создать службу переднего плана в дельфи.

Крайне сильно поддерживаю. У меня самого сейчас в проекте настал момент, когда нужно написать службу переднего фона, а инфы в интернете централизованной нет.

Ссылка на комментарий
  • 0

У меня, кстати, появилось предположение, почему прога запустилась у меня на Android 10, но на Android 6.0.1 и у Олега Киреева на Android 10 - нет. Возможно, это связано с тем, что Вы скомпилировали приложение только под Android 64. У моего телефона процессор 64-разрядный(Samsung Exynos 7 Octa(5433)), но, как сказала Aida64, 32-bit Mode. У Олега Киреева процессор Samsung Exynos 7 Octa 7870, тоже 64-разрядный, но, поскольку разница между датами выхода чипов всего 2 года, то, возможно, он тоже работает в 32-битном режиме.  На Нокиа 3.1, на которой всё работало, стоит 64-разрядный Mediatek MT6750n. Сейчас ещё проверю на Самсунг Ноут 10+ с чипом Qualcomm Snapdragon 855 в 64-разрядном режиме.

Вот тут было обсуждение по поводу устройства на базе такого же чипа, как у Олега, где оказалось, что ЦПУ поддерживает 64-битные инструкции, но прошивка - нет: https://stackoverflow.com/questions/49184689/why-does-my-android-device-with-armv8-based-cpu-cores-exynos-7-octa-7870-not-s

Изменено пользователем PowerOwl
Ссылка на комментарий
  • 0
  • Модераторы
4 часа назад, Ingalime сказал:

Вроде это отвечает судя по папкам за 32 бит, которые я не использую

но при этом подсовываете туда библиотеку bass...

В этих папках (кроме arm64-v8a (для 64 бит) и armeabi-v7a (для 32 бит)) должны лежать заглушки, которые в случае несовместимости с девайсом буду выдавать сообщение типа такого "Application does not support this device".

Собственно, PowerOwl, уже сделал предположение.

 

 

Ссылка на комментарий
  • 0

Что-то никак не могу осмыслить. Прошу прощения за тупость. :)
Мне надо арк 64 бит для маркета.
Мои шаги теперь:
1. В деплоймент сейчас добавляем дополнительно libbass.so из папки armeabi.
Это будет заглушка? 
2. Имеем три libbass.so ВААS в деплойменте.
3. Есть еще папки BAAS x86 и x86_64 но для них не понятно какой путь выбрать в Remote Path.
Я так понимаю файлы libbass.so из этих папок добавлять в деплоймент не надо?
4. Какие галочки надо установить для libnative-activity.so там и релиз есть и дебаг пути. Или поставить все пять галочек где пусто?
Вот сейчас такой деплоймент на картинке:

 

arm.jpg

Ссылка на комментарий
  • 0
  • Модераторы

Вот что сейчас я вижу на Delphi 10.4.2 для чистого проекта Project1 и сервиса:

Релиз для 32 бит (Application store/Development):

  • armeabi - заглушка libProject1.so.
  • armeabi-v7a - проект libProject1.so, сервис и т.д.
  • mips - заглушка libProject1.so.

Релиз для 64 бит (Development, для Application store создаётся aab файл(который может включать в себя 32 битную версию))

  • arm64-v8a - проект libProject1.so, сервис и т.д.

Библиотеку bass я бы положил только в armeabi-v7a (для 32 бит) и arm64-v8a (для 64 бит).

5 часов назад, Ingalime сказал:

4. Какие галочки надо установить для libnative-activity.so там и релиз есть и дебаг пути. Или поставить все пять галочек где пусто?

Эти галочки управляются из блока Project Manager, в зависимости от выбранной битности и конфигурации(Debug/Release и Application store/Development). Поэтому, если вы снимали их самостоятельно (через Deployment Manager), то рекомендую поставить их обратно, т.е. вернуть в дефолтное состояние.

Повторюсь, сейчас нужно собрать 32 битную версию и выложить сюда для теста (возможно, PowerOwl или Олег смогут проверить).

 

 

p.s. Вопрос, какую версию студии вы используете?

Ссылка на комментарий
  • -1
Цитата

Повторюсь, сейчас нужно собрать 32 битную версию 

Для 32 бит я не могу указать armeabi-v7a, в  Remote Path нет правильного пути. Я не могу собрать 32 бит. Приложение падает.

Embarcadero® RAD Studio 10.4 Version 27.0.40680.4203 

32.jpg

Ссылка на комментарий
  • 0

В опциях проекта студии поставила галочку true у
Generate Android 32-bit and 64-bit binaries(armedi-7a + arm64-v8a)
в режиме платформа Андроид 64 бит/релиз/Development
На выходе получила этот АРК. На телефоне андроид 8.1 Readmi5A запустилось.
.aab я так понимаю будет получен в режиме Configuration->Application Store

PublicRadio.apk

Ссылка на комментарий
  • 0

Android 6.0.1 - падение. А вы хоть разобрались с Deployment? Я так понимаю, что приложение падает от того, что пытается найти файлы библиотеки BASS для armeabi-v7a, но не находит. А на 64-битных устройствах всё работает от того, что им нужны файлы для arm64-v8a, которые вы задеплоили.

Ссылка на комментарий
  • 0

Всё еще вылетает.

Вот логи снятые с logcat:

Screenshot_20210708-135554.thumb.png.ddc39e9c12d202340ae2ce2a293692dc.png

Вам следует сделать дебаг-версию вашего апк и проверить на любом эмуляторе андроида, создав образ 32-битной системы. Если получите ошибку не в юните вашего приложения, тогда с помощью брейкпоинтов(клик слева от номера строки) искать место, где происходит ошибка.

Ссылка на комментарий
  • 0
  • Модераторы

Оба apk файла собраны для 64-бит.

Вам нужно собрать 32 битную версию:

ProjectManager.PNG

Честно говоря, я не знаю как вам ещё объяснить это... (раз проблемы возникают даже на таком этапе, то я обязан сообщить, что на форуме существует раздел: Ищу подрядчика)

Перед тем как вы соберётесь выложить сюда собранный 32-битный apk, проверьте его, открыв например в винраре. Зайдите в папку "lib" и проверьте каждую папку. Выше я уже написал, что будет внутри каждой папки для 32-битного apk и для 64-битного apk (https://fire-monkey.ru/topic/7447-android-10-и-музплеер/?do=findComment&comment=43249). Т.о. в 32-битном apk должна получиться примерно такая структура (на примере Project1):

  • armeabi - заглушка libProject1.so.
  • armeabi-v7a - ваш проект libProject1.so, сервис, библиотека bass и т.д.
  • mips - заглушка libProject1.so.

 

p.s. По поводу логов, то они сообщают о том, что не найдена библиотека PublicRadio (что собственно подтверждается и текстом ошибки и вскрытием apk файла, в нем библиотека есть только в папке для 64-бит, т.е. apk файл собран не для 32-бит).

 

Ссылка на комментарий
  • 0
47 минут назад, Andrey Efimov сказал:

Оба apk файла собраны для 64-бит.

Сам не обратил внимания на это.

Для Ingalime:

Ваш apk внутри выглядит так:

1361708318_Screenshot_20210708-1546361.thumb.png.45f43b78270b6938262fed3824f46cb3.png

В директории lib должны находится библиотеки необходимые приложению. Для каждой архитектуры процессоров нужны свои библиотеки. Следовательно они рассортированы по каталогам:

703092827_Screenshot_20210708-1546481.thumb.png.51a7c76301fb93d370c5fa17ffe210cc.png

Внутри каталога arm64-v8a всё необходимое присутствует:

1991487686_Screenshot_20210708-1546551.thumb.png.a791ad2d21382233ab27a7d5af51d0d3.png

Соответственно, при установке приложения на 64-битное устройство, установщик будет доставать файлы отсюда.

Однако, если устанавливать на 32-битное устройство, то установщик будет доставать файлы уже из каталога armeabi-v7a:

501077326_Screenshot_20210708-1543571.thumb.png.956b1387987025a53a862004bc05a723.png

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

Ссылка на комментарий
  • 0
Цитата

Перед тем как вы соберётесь выложить сюда собранный 32-битный apk, 

Не могу я собрать 32 бит падает.
 

Цитата

Выше я уже написал, что будет внутри каждой папки для 32-битного apk

-> стрелочка это содержимое файлов в пакете 32 бит.
Папки наблюдаю arm64-v8a->libbass.so; armeabi->libPublicRadio.so; armeabi-v7a->libPublicRadio.so->libProxyAndroidService.so->libbass.so->gdbserver; mips->libPublicRadio.so

Библиотеку BASS было скачено несколько месяцев назад. Решила скачать самую последнюю версию с официального сайта.
Обнаружилось что папки armeabi вообще нет. Только паки arm64-v8a, armeabi-v7a, x86, x86_64.

Добавлены рекомендации PowerOwl по добавлению в деплой не хватающих файлов.

Единственная разница, что у файла в 32 битной версии service/Android64/Realise libserPublic.so тип File а в 64 битной версии тип файла AndroidServiceOutput

32 битная версия падает.

 

dep.jpg

Изменено пользователем Ingalime
Ссылка на комментарий

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

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