Здравствуйте. Есть приложение музыкального плеера со службой переднего фона, которая позволяет проигрывать музыку даже если приложение свернуто. Без этой службы андроид убивает приложение через пару минут если оно свернуто. Приложение работает на андроид 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.
Вопрос
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.
Ссылка на комментарий
Лучшие авторы в вопросе
9
5
26
19
Популярные дни
6 июль
28
8 июль
8
9 июль
6
2 июль
5
Лучшие авторы в вопросе
Andrey Efimov 9 постов
Олег Киреев 5 постов
Ingalime 26 постов
PowerOwl 19 постов
Популярные дни
6 июль 2021
28 постов
8 июль 2021
8 постов
9 июль 2021
6 постов
2 июль 2021
5 постов
Популярные посты
Andrey Efimov
У меня на устройстве с Андроид 11 и эмуляторе с Андроид 7.1.2 приложение не падает. По теме, делайте дебаг версию и ищите устройство на котором падает, запускайте monitor.bat и приложение, сни
PowerOwl
У меня, кстати, появилось предположение, почему прога запустилась у меня на Android 10, но на Android 6.0.1 и у Олега Киреева на Android 10 - нет. Возможно, это связано с тем, что Вы скомпилировали пр
Andrey Efimov
но при этом подсовываете туда библиотеку bass... В этих папках (кроме arm64-v8a (для 64 бит) и armeabi-v7a (для 32 бит)) должны лежать заглушки, которые в случае несовместимости с девайсом буду в
Изображения в теме
60 ответов на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.