[Android] Aplikacja bez UI, działająca w tle, jak zrobić?

0

Cześć.
Chcę zrobić aplikacje, która będzie, działając w tle, zbierać dane z urządzenia i synchronizować je w serwerem.
Aplikacja nie powinna być widoczna i nie powinno dać się jej łatwo wyłączyć.
Póki co używam

android:theme="@android:style/Theme.Translucent"

i w main activity startuje service i daje finish().

Jako tako to działa, ale przeważnie z niewiadomych mi powodów, usługa się wyłącza.
Raz po minucie działania, raz po godzinie. Nie wiem dlaczego.

Tutaj prosty kod aplikacji:

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="pl.work.myapplication">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity" android:theme="@android:style/Theme.Translucent">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="false" />
    </application>

</manifest>

MainActivity.java

package pl.work.myapplication;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startService(new Intent(this,MyService.class));
        finish();
    }
}

MyService.java

package pl.work.myapplication;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;

public class MyService extends Service {
    public MyService() {

    }
    private AtomicBoolean working = new AtomicBoolean(true);

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while(working.get())
            {
                SystemClock.sleep(1000);
                String currentTime = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(new Date());

                Log.d("APP",currentTime);
            }
        }
    };
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this,"Service Started",Toast.LENGTH_LONG).show();
        new Thread(runnable).start();

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        working.set(false);
        Log.d("APP","Service destroyed");
        Toast.makeText(this,"Service Destroyed",Toast.LENGTH_LONG).show();
    }
}

Czy mógłby ktoś użyczyć swojej wiedzy i wskazać jaki kierunek obrać przy budowie takiej aplikacji?
Dziękuję i pozdrawiam.

1

Na szczęście nie da się czegoś takiego zrobić. Najbliższy pożądany efekt dadzą Ci ForegroundService albo WorkManager.

0

Czyli nie mam możliwości aby ustanowić połączenie dwukierunkowe w relacji Urządzenie mobilne <=> Serwer ?
Wiadomo że aplikacja na mobilce odpytuje serwer w jakiś tam sposób i np serwer zwraca dane.
A jak to zrobić w drugą stronę, że to mobilka jest serwerem i jest odpytywana? Raczej bezsensu WorkManagerem który uruchamia się w jakichś tam interwałach.

1

Możesz osiągnąć to przy użyciu powiadomień i serwisów. Szukaj pod hasłami push notification i FCM.

0

Próbowałem WorkManagerem, JobSchedulerem, FireBase.

Wymagania:

  1. Co X czasu (interwał do ustalenia - ale mogą to być interwały rzędu 10 sekund a mogą być rzędu godzina) aplikacja musi wywołać szereg funkcji które zbiorą zakres danych i wysyłać dane na serwer.
  2. Dane nie powinny przechodzić ani znajdować się na serwerach firm zewnętrznych, dane powinny trafiać bezpośrednio na dedykowany serwer na którym pracuje odpowiednia aplikacja (serwer).
  3. Aplikacja musi uruchamiać procedurę synchronizacji (zbierania i wysłania danych na serwer) bez ingerencji i wiedzy użytkownika. Nie chce aby wyświetlały mi się jakieś powiadomienia itp.
  4. Aplikacja powinna mieć możliwość nasłuchiwania na niecykliczne rządania serwera dotyczące zebrania i wysłania danych.

Czy coś takiego da się zrealizować? Za pomocą czego?

1

Opisujesz dwie osobne rzeczy. Synchronizację na żądanie i synchronizację co jakiś czas z poziomu aplikacji. Synchronizacja na żądanie to FCM + Service. Bez powiadomień dla użytkownika będzie to działać różnie. Zależy jak długo taka synchronizacja zajmuje. Synchronizacja okresowa to WorkManager albo AlarmManager.

0

Dzięki za odpowiedź Michał,
mam jeszcze pytanie jakiego sposobu użyć aby przesyłać dane na serwer z aplikacji (klienta).
Danymi będą JSONy.
Serwer działa cały czas i może oczekiwać na dane, klienci (aplikacje mobilne) muszą mieć możliwość w każdej chwili wysłać dane do serwera.
Klienci są na Androidzie a server na Javie (spring).

1

W nowych systemach Android nie da się długo pracować w tle bez wiedzy użytkownika. Taki serwis może zostać automatycznie zatrzymany. Jeżeli chcesz pracować cały czas to konieczna jest chociaż notyfikacja

1 użytkowników online, w tym zalogowanych: 0, gości: 1