Как избежать закрытия службы Android при закрытии приложения?Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как избежать закрытия службы Android при закрытии приложения?

Сообщение Anonymous »

Delphi 11.1
Мне нужно запустить службу Android, которая продолжает работать, даже если приложение закрыто пользователем или уничтожено ОС. В папке документов приложения есть база данных SQLite, и службе необходимо получить доступ к этой базе данных и вставить некоторые данные в течение длительного времени.
Я пробовал много стратегий, но ни одна не сработала. .
Моя основная попытка — создать локальную службу, используя START_STICKY и вызывая StartForeground() в событии StartCommand. >
Модуль служебных данных:

Код: Выделить всё

unit UDMService;

interface

uses
System.SysUtils,
System.Classes, System.IOUtils,
System.Android.Service,
AndroidApi.JNI.GraphicsContentViewText,
Androidapi.JNI.Os, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error,
FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool,
FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef,
FireDAC.Stan.ExprFuncs, FireDAC.ConsoleUI.Wait, FireDAC.DApt,
FireDAC.Phys.SQLiteWrapper.Stat, Data.DB, FireDAC.Comp.Client;

type
TThreadTeste = class(TThread)
protected
procedure Execute; override;
end;
TDM = class(TAndroidService)
fdConDados: TFDConnection;
FDPhysSQLiteDriverLink1: TFDPhysSQLiteDriverLink;
function AndroidServiceStartCommand(const Sender: TObject;
const Intent: JIntent; Flags, StartId: Integer): Integer;
private
{ Private declarations }
FThreadGravarTabela: TThread;
procedure ConectarBanco;
procedure GerarRegistroTabela;
procedure GerarRegistrosTabela;
procedure StartForeground;
public
{ Public declarations }
end;

var
DM: TDM;

implementation

{%CLASSGROUP 'FMX.Controls.TControl'}

{$R *.dfm}

uses Androidapi.JNI.App, Androidapi.JNI.Support, Androidapi.Helpers;

procedure TDM.StartForeground;
var
{$if COMPILERVERSION > 34}
LBuilder: Japp_NotificationCompat_Builder;
{$else}
LBuilder: JNotificationCompat_Builder;
{$endif}
begin
try
//if FIsForeground or not TAndroidHelperEx.CheckBuildAndTarget(26) then
//Exit; //   10 then
Terminate;
end;
finally
AQuery.Free;
end;
end;

end.
Основная форма из приложения

Код: Выделить всё

unit UMainApp;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, System.Android.Service,
FireDAC.Stan.ExprFuncs, FireDAC.Phys.SQLiteWrapper.Stat,
FireDAC.Phys.SQLiteDef, FireDAC.Stan.Intf, FireDAC.Stan.Option,
FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def,
FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.SQLite,
FireDAC.FMXUI.Wait, Data.DB, FireDAC.Comp.Client, System.IOUtils,
FMX.Memo.Types, FireDAC.DApt, FMX.ScrollBox, FMX.Memo, FMX.ListView.Types,
FMX.ListView.Appearances, FMX.ListView.Adapters.Base, FMX.ListView;

type
TForm1 = class(TForm)
Button1: TButton;
FDPhysSQLiteDriverLink1: TFDPhysSQLiteDriverLink;
fdConDados: TFDConnection;
mmLog: TMemo;
ButAtualizarLista: TButton;
ListView1: TListView;
procedure butStartServiceClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ButAtualizarListaClick(Sender: TObject);
private
{ Private declarations }
ConexaoServico : TLocalServiceConnection;
procedure AtualizarEstruturaBase;
function GetDadosTabelaTestes: TDataSet;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.AtualizarEstruturaBase;
function TabelaExiste(const pTable: String): Boolean;
begin
var AQuery: TFDQuery := TFDQuery.Create(nil);
AQuery.Connection := fdConDados;
try
AQuery.Open('PRAGMA table_info(' + QuotedStr(pTable) + ')');
result := AQuery.RecordCount > 0;
finally
AQuery.Free;
end;
end;

const SQL_CRIAR_TABELA_TESTES =
'CREATE TABLE tabela'
+ ' (id INTEGER PRIMARY KEY AUTOINCREMENT,'
+ ' data DATETIME)';
begin
var AQuery: TFDQuery := TFDQuery.Create(nil);
AQuery.Connection := fdConDados;
try
if not (TabelaExiste('tabela')) then
AQuery.ExecSQL(SQL_CRIAR_TABELA_TESTES);
finally
AQuery.Free;
end;
end;

procedure TForm1.ButAtualizarListaClick(Sender: TObject);
begin
ListView1.Items.Clear;
var ADataSet: TDataSet := GetDadosTabelaTestes;
with ADataSet do
begin
First;
while not (Eof) do
begin
ListView1.Items.Add.Text := Format('%d - %s',
[FieldBYName('id').AsInteger,
FormatDateTime('dd/mm/yyyy hh:nn:ss', FieldByName('data').AsDateTime)]);
Next;
end;
end;
end;

procedure TForm1.butStartServiceClick(Sender: TObject);
begin
ConexaoServico := TLocalServiceConnection.Create;
TThread.CreateAnonymousThread(
procedure
begin
ConexaoServico.StartService('MyService2');
end).Start;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
try
fdconDados.Params.Values['Database'] := TPath.Combine(TPath.GetDocumentsPath, 'MyServicePOC.db3');
fdconDados.Params.Add('SharedCache=False');
fdconDados.UpdateOptions.LockWait := True;
fdconDados.Connected := True;
AtualizarEstruturaBase;
except
on e: exception do
mmLog.Lines.Add('[TForm1.FormCreate]'+e.Message)
end;
end;

function TForm1.GetDadosTabelaTestes: TDataSet;
begin
fdConDados.ExecSQL('SELECT * FROM tabela ORDER BY id, data', result);
end;

end.
Этот код работает нормально, генерирует вставки, и я могу загрузить данные, но когда я закрываю приложение, служба также отключается ОС.
Сервис создан как «Локальный». Я попытался создать ту же группу проектов, используя опцию «Удаленно» для службы, но данные не вставляются в базу данных приложения.
Может ли кто-нибудь помочь с этой проблемой?

Подробнее здесь: https://stackoverflow.com/questions/783 ... -is-closed
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»