Wykrywanie połączenia z internetem gdy aplikacja jest wyłączona

0

Cześć ! Mam pewien problem z wykrywaniem połączenia.

Mój kod wygląda tak:

class NetworkStateChangeReceiver: BroadcastReceiver()
{
    private val TAG = "NSCR"

    override fun onReceive(context: Context?, intent: Intent?)
    {
        Log.v(TAG, "onReceive(): init")

        var counter = 0
        val serviceManager = ServiceManager(context)
        var isConnected = serviceManager.checkInternetState()

        while(isConnected == 0)
        {
            isConnected = serviceManager.checkInternetState()
            counter++

            if(counter > 20)
            {
                break
            }

            Thread.sleep(1000)
        }

        if(isConnected == 1)
        {
            Toast.makeText(context, "Połączono z internetem !!!", Toast.LENGTH_LONG).show()
        }
        else if (isConnected == 2)
        {
            Toast.makeText(context, "Połączono z internetem !!!", Toast.LENGTH_LONG).show()
        }
        else
        {
            Log.e(TAG, "Brak połączenia")
        }

    }
}

Receiver ( AndroidManifest ):

 <receiver
                android:name=".NetworkStateChangeReceiver"
                android:enabled="true"
                android:exported="true">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
            </intent-filter>
        </receiver>

Gdy aplikacja jest wyłączona i włączę WIFI, aplikacja robi to co powinna ( pokazuje Toast-a ), natomiast kiedy aplikacja jest wyłączona i włącze dane komórkowe nic się nie pokazuje ( funkcja onReceive() nie jest wywoływana ).

Co muszę zrobić aby aplikacja wykrywała włączenie danych komórkowych ?

Potrzebuje to zrobić, żeby aplikacja od razu po połączeniu z internetem połączyła się z serwerem.

**EDIT: **

Kiedy aplikacja jest wyłączona i kiedy WIFI i dane komórkowe są włączone, to urządzenie korzysta z WIFI.
Kiedy to WIFI wyłącze, telefon automatycznie przerzuca się na **dane komórkowe **. Kiedy tak zrobię, aplkacja wykrywa zmianę.

1

jeśli masz androida 7.0 lub wyższego to tu masz odpowiedź https://developer.android.com/topic/performance/background-optimization.html#connectivity-action

0

W dokumentacji ConnectivityManager też jest to wspomniane:

ConnectivityManager  |  Android Developers

public static final String CONNECTIVITY_ACTION

This constant was deprecated in API level 28.
apps should use the more versatile requestNetwork(NetworkRequest, PendingIntent), registerNetworkCallback(NetworkRequest, PendingIntent) or registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback) functions instead for faster and more detailed updates about the network changes they care about.

A change in network connectivity has occurred. A default connection has either been established or lost. The NetworkInfo for the affected network is sent as an extra; it should be consulted to see what kind of connectivity event occurred.

Apps targeting Android 7.0 (API level 24) and higher do not receive this broadcast if they declare the broadcast receiver in their manifest. Apps will still receive broadcasts if they register their BroadcastReceiver with Context.registerReceiver() and that context is still valid.

0

Zrobiłem teraz tak:

class MainActivity : AppCompatActivity()
{

    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val intentFilter = IntentFilter()

        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE")
        intentFilter.priority = 100

        val broadcastReceiver = BroadcastReceiver()

        registerReceiver(broadcastReceiver, intentFilter)
    }
}
class BroadcastReceiver: BroadcastReceiver()
{
    private val TAG = "BR"
    override fun onReceive(context: Context?, intent: Intent?)
    {
        val cm = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val ni = cm.activeNetworkInfo

        var isAvalible = false

        if(ni != null)
        {
            if(ni.isAvailable)
            {
                isAvalible = true
            }
        }
        else
        {
            Log.e(TAG, "Error")
        }


        if(isAvalible)
        {
            Log.v(TAG, "Is available")
            Toast.makeText(context, "Is available", Toast.LENGTH_LONG).show()
        }
        else
        {
            Log.e(TAG, "Isn't available")
        }
    }
}

Teraz wykrywa każdą zmianę sieci ( WIFI i dane komórkowe ).
Ale w tym momencie wykrywa zmianę tylko wtedy kiedy aplikacja jest włączona lub działa w tle ( ona musi to wykrywać również jak jest wyłączona )

1

Prawdopodobnie próbujesz zrobić coś czego użytkownicy twojej apki - albo raczej użytkownik telefonu na którym ona jest zainstalowana - nie chcą. W Androidzie to jest tak, że jeśli proces aplikacji nie istnieje to znaczy że TAK MA BYĆ. Właśnie dlatego w najnowszych wersjach Androida to co chcesz zrobić jest tak trudne / niemożliwe / upierdliwe - żeby tego nie robić.

W starszych wersjach Androida sztuczne utrzymywanie procesu apki przy życiu było dośc łatwe i masowo nadużywane. Prowadziło to do zmulenia telefonu.

Więc może po prostu tego nie rób. I wszyscy będziemy szczęśliwsi.

0

Dokładnie chodzi mi o to, żeby działało to jak np. Facebook czy Snapchat.

Jak włączę Internet, Facebook się odświeża i pokazuje powiadomienia.
To samo chciałbym zrobić ze swoją aplikacja.

1
Adrian098741 napisał(a):

Dokładnie chodzi mi o to, żeby działało to jak np. Facebook czy Snapchat.

Jak włączę Internet, Facebook się odświeża i pokazuje powiadomienia.
To samo chciałbym zrobić ze swoją aplikacja.

Ale to nie jest zrealizowane za pomocą obserwacji stanu sieci! Tego się tak nie robi!
Od tego jest Google Cloud Messaging.
Na iOS to się nazywa Push Notification.

Generalnie to system odpowiada, za obserwację stanu sieci i aktualizację notyfikacji. Twój serwer ma wysłać notifikację do serwerów google-a on to przekieruje w telefony w energooszczędny sposób.
Jeśli każda apka robiłaby to po swojemu, to bateria byłaby (jak kiedyś) niepotrzebnie zjadana, bo nie da się skoordynować inaczej wszystkich aplikacji potrzebujących takiej funkcjonalności.

Ten wątek to klasyczny przykład problemu XY.

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