Rheinwerk Computing < openbook >

 
Inhaltsverzeichnis
Vorwort
Teil I Grundlagen
1 Android – eine offene, mobile Plattform
2 Hallo Android!
3 Von der Idee zur Veröffentlichung
Teil II Elementare Anwendungsbausteine
4 Wichtige Grundbausteine von Apps
5 Benutzeroberflächen
6 Multitasking
Teil III Gerätefunktionen nutzen
7 Telefonieren und surfen
8 Sensoren, GPS und Bluetooth
Teil IV Dateien und Datenbanken
9 Dateien lesen, schreiben und drucken
10 Datenbanken
Teil V Multimedia und Produktivität
11 Multimedia
12 Kontakte und Organizer
A Einführung in Kotlin
B Jetpack Compose
C Häufig benötigte Codebausteine
D Literaturverzeichnis
E Die Begleitmaterialien
Stichwortverzeichnis

Ihre Meinung?
Spacer
<< zurück
Android 11 von Thomas Künneth
Das Praxisbuch für App-Entwickler
Buch: Android 11

Android 11
Pfeil 7 Telefonieren und surfen
Pfeil 7.1 Telefonieren
Pfeil 7.1.1 Anrufe tätigen und SMS versenden
Pfeil 7.1.2 Auf eingehende Anrufe reagieren
Pfeil 7.2 Telefon- und Netzstatus
Pfeil 7.2.1 Systemeinstellungen auslesen
Pfeil 7.2.2 Netzwerkinformationen anzeigen
Pfeil 7.2.3 Carrier Services
Pfeil 7.3 Das Call Log
Pfeil 7.3.1 Entgangene Anrufe ermitteln
Pfeil 7.3.2 Änderungen vornehmen und erkennen
Pfeil 7.4 Webseiten mit WebView anzeigen
Pfeil 7.4.1 Einen einfachen Webbrowser programmieren
Pfeil 7.4.2 JavaScript nutzen
Pfeil 7.5 Webservices nutzen
Pfeil 7.5.1 Auf Webinhalte zugreifen
Pfeil 7.5.2 Senden von Daten
Pfeil 7.6 Zusammenfassung
 
Zum Seitenanfang

7.2    Telefon- und Netzstatus Zur vorigen ÜberschriftZur nächsten Überschrift

Android-Geräte haben am liebsten durchgehend Zugang zu Netzen. Die wichtigsten Informationen, beispielsweise die Art der Verbindung oder die Signalstärke, werden deshalb permanent in der Statusleiste angezeigt. Sie lassen sich aber auch durch eigene Apps ermitteln. Wie, zeige ich Ihnen im Folgenden.

 
Zum Seitenanfang

7.2.1    Systemeinstellungen auslesen Zur vorigen ÜberschriftZur nächsten Überschrift

Über android.provider.Settings.Secure ist der lesende Zugriff auf zahlreiche Systemeinstellungen möglich. Die Klasse enthält unter anderem ANDROID_ID, eine als Hex-String codierte 64-Bit-Zahl. Diese ist seit Oreo für die Kombination aus Benutzer, Gerät und Signierschlüssel eindeutig, kann sich aber durch das Zurücksetzen des Geräts oder den Austausch des Schlüssels ändern. In früheren Android-Versionen wurde ANDROID_ID beim erstmaligen Einrichten des Geräts als Zufallszahl erzeugt. Auf den aktuellen Wert kann mit folgendem Ausdruck zugegriffen werden:

Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)

Hierfür sind keine besonderen Berechtigungen erforderlich. Das gilt auch für den Integer-Wert SKIP_FIRST_USE_HINTS. Google hat ihn mit Android 5 eingeführt. Apps, die bei ihrem ersten Start Hinweise zur Benutzung anzeigen möchten, sollten ihn mit getInt() abfragen. 1 bedeutet, der Anwender möchte keine Einführung angezeigt bekommen. Bei 0 können Sie Ihre Onboarding-Informationen hingegen darstellen. Bitte beachten Sie, dass der Wert nicht gesetzt sein muss. Sie sollten deshalb die Ausnahme SettingNotFoundException fangen oder der Methode getInt() einen zusätzlichen Parameter übergeben, der den Standardwert repräsentiert.

Weitere Einstellungen lassen sich über Settings.Global auslesen. Die Klasse gibt es seit API-Level 17 (eine der vielen Jelly-Bean-Versionen). Mit dem folgenden Ausdruck prüfen Sie beispielsweise, ob Bluetooth verfügbar ist:

Settings.Global.getInt(contentResolver, Settings.Global.BLUETOOTH_ON, 0)

Settings bietet außerdem eine Reihe von Konstanten an, die Sie als Aktionen für Intents verwenden können.

Mit ACTION_SETTINGS rufen Sie die Systemeinstellungen auf:

val intent = Intent(Settings.ACTION_SETTINGS)
startActivity(intent)

Listing 7.5    Systemeinstellungen öffnen

 
Zum Seitenanfang

7.2.2    Netzwerkinformationen anzeigen Zur vorigen ÜberschriftZur nächsten Überschrift

Mein Projekt ConnectivityManagerDemo (Abbildung 7.3) zeigt Ihnen, wie Sie grundlegende Informationen über die aktuell bekannten Netzwerke auslesen. Die Klasse ConnectivityManagerDemoActivity ist in Listing 7.6 dargestellt.

Nach dem Laden und Anzeigen der Benutzeroberfläche wird mit getSystemService(ConnectivityManager::class.java) ein Objekt des Typs android.net.ConnectivityManager ermittelt. Anschließend iteriere ich über das von allNetworks zurückgelieferte Feld, das Elemente des Typs android.net.Network enthält. Die ConnectivityManager-Methode getNetworkInfo() liefert zwar in Objekten des Typs NetworkInfo die gewünschten Informationen, allerdings gilt sie seit API-Level 29 als veraltet und sollte deshalb nicht mehr verwendet werden. Stattdessen müssen wir uns die Werte aus verschiedenen Töpfen zusammensuchen.

Die App »ConnectivityManagerDemo«

Abbildung 7.3    Die App »ConnectivityManagerDemo«

getLinkProperties() liefert ein android.net.LinkProperties-Objekt. Es enthält wichtige Verbindungseinstellungen, beispielsweise den Namen der Schnittstelle (interfaceName), die Liste der DNS-Server und die MTU-Größe (Maximum Transmission Unit), also die maximale Paketgröße in Byte. getNetworkCapabilities() liefert eine android.net.NetworkCapabilities-Instanz. Mit ihr werden die Fähigkeiten eines aktiven Netzwerks beschrieben. Sie können eine Fähigkeit mit hasCapability() abfragen. Beispielsweise gibt NET_CAPABILITY_NOT_ROAMING an, ob Roaming inaktiv ist. Sonst könnte Ihre App Datenzugriffe einschränken oder ganz unterlassen. Eine andere Methode, den Roaming-Status zu ermitteln, zeige ich Ihnen in Abschnitt 7.2.3, »Carrier Services«.

Um zu prüfen, ob ein Netzwerk aktuell verwendet werden kann, verwenden Sie die Konstante NET_CAPABILITY_FOREGROUND. Ab Android 10 können Sie mit signalStrength die Signalstärke ermitteln. Ihr Wertebereich ist allerdings vom Verbindungstyp abhängig und war zum Zeitpunkt der Drucklegung nicht dokumentiert.

package com.thomaskuenneth.androidbuch.connectivitymanagerdemo

import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class ConnectivityManagerDemoActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mgr = getSystemService(ConnectivityManager::class.java)
mgr?.allNetworks?.forEach {
val properties = mgr.getLinkProperties(it)
textview.append("${properties?.interfaceName}\n")
val capabilities = mgr.getNetworkCapabilities(it)
val notRoaming = capabilities?.hasCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) ?: true
textview.append("Roaming ist ${if (notRoaming) "aus"
else "
ein"}\n")
// ab API-Level 29 vorhanden
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
textview.append("Signalstärke: ${
capabilities?.
signalStrength}\n")
}
val foreground = capabilities?.hasCapability(
NetworkCapabilities.NET_CAPABILITY_FOREGROUND)
?: false
textview.append("Nutzbar durch Apps: $foreground\n\n")
}
}
}

Listing 7.6    Die Klasse »ConnectivityManagerDemoActivity«

Um die Werte auslesen zu können, muss die Manifestdatei das Tag

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

enthalten. Anders als bei READ_PHONE_STATE handelt es sich hierbei um eine normale Berechtigung, die automatisch, also ohne Rückfrage beim Anwender, erteilt wird.

 
Zum Seitenanfang

7.2.3    Carrier Services Zur vorigen ÜberschriftZur nächsten Überschrift

Netzbetreiber können Carrier Services in ihren Apps einsetzen, um Wartungs- oder Provisionierungsaufgaben zu erledigen. Die Anwendungen können ganz regulär über Google Play vertrieben werden, müssen allerdings mit einem speziellen Zertifikat signiert werden. Das lässt sich mit der TelephonyManager-Methode hasCarrierPrivileges() prüfen. Die Klasse android.telephony.SubscriptionManager liefert (auch normalen Apps) Informationen über die aktive SIM-Karte sowie über das aktuelle Netzwerk. Sie können unter anderem abfragen, ob Roaming aktiv ist. Mithilfe eines OnSubscriptionsChangedListener übermittelt Android solche Statusänderungen automatisch. Wie Sie das in Ihren Apps nutzen, ist in Listing 7.7 zu sehen. Es gehört zur Beispiel-App SubscriptionManagerDemo.

package com.thomaskuenneth.androidbuch.subscriptionmanagerdemo

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.telephony.SubscriptionManager
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener
import android.util.Log
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

private const val REQUEST_READ_PHONE_STATE = 123
private val TAG = SubscriptionManagerDemoActivity::class.simpleName
class SubscriptionManagerDemoActivity : AppCompatActivity() {

private lateinit var manager: SubscriptionManager
private val listener = object : OnSubscriptionsChangedListener() {
override fun onSubscriptionsChanged() {
Log.d(TAG, "onSubscriptionsChanged()")
output()
}
}
private var listenerWasRegistered = false

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
try {
manager = getSystemService(SubscriptionManager::class.java)
} catch (ex: RuntimeException) {
Log.e(TAG, "getSystemService()", ex)
finish()
}
}

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
if (requestCode == REQUEST_READ_PHONE_STATE &&
grantResults.isNotEmpty() && grantResults[0] ==
PackageManager.PERMISSION_GRANTED
) {
output()
}
}

override fun onStart() {
super.onStart()
if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE)
== PackageManager.PERMISSION_GRANTED
) {
output()
} else {
requestPermissions(
arrayOf(Manifest.permission.READ_PHONE_STATE),
REQUEST_READ_PHONE_STATE
)
}
}

override fun onPause() {
super.onPause()
if (listenerWasRegistered) {
manager.removeOnSubscriptionsChangedListener(listener)
listenerWasRegistered = false
}
}

private fun output() {
if (!listenerWasRegistered) {
manager.addOnSubscriptionsChangedListener(listener)
listenerWasRegistered = true
}
layout.removeAllViews()
val params = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
try {
manager.activeSubscriptionInfoList?.forEach {
Log.d(
TAG, "getCarrierName(): ${it.carrierName}"
)
Log.d(
TAG, "getDisplayName(): ${it.displayName}"
)
Log.d(
TAG, "getDataRoaming(): ${it.dataRoaming}"
)
val imageview = ImageView(this)
imageview.layoutParams = params
imageview.setImageBitmap(it.createIconBitmap(this))
layout.addView(imageview)
}
} catch (ex: SecurityException) {
Log.e(TAG, "activeSubscriptionInfoList", ex)
}
layout.invalidate()
}
}

Listing 7.7    Die Klasse »SubscriptionManagerDemoActivity«

getSystemService(SubscriptionManager::class.java) liefert ein Objekt des Typs android.telephony.SubscriptionManager. Es enthält unter anderem die Methoden addOnSubscriptionsChangedListener() und removeOnSubscriptionsChangedListener(), mit denen Sie einen OnSubscriptionsChangedListener registrieren und wieder entfernen. In meinem Beispiel geschieht dies in onPause() und in der privaten Methode output(). activeSubscriptionInfoList liefert eine Liste von SubscriptionInfo-Objekten. Hiermit können Sie unter anderem den Roaming-Status abfragen (dataRoaming) und mit createIconBitmap() ein Symbol erzeugen, das die SubscriptionInfo repräsentiert.

Um die beschriebenen Werte auslesen zu können, ist die gefährliche Berechtigung READ_PHONE_STATE erforderlich. Sie muss in der Manifestdatei eingetragen und zur Laufzeit angefordert werden. Hierfür müssen Sie wie üblich checkSelfPermission() und requestPermissions() aufrufen und onRequestPermissionsResult() implementieren.

 


Ihre Meinung?

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de

<< zurück
Zur Rheinwerk-Konferenz für Kotlin
 Buchempfehlungen
Zum Rheinwerk-Shop: Kotlin

Kotlin


Zum Rheinwerk-Shop: Praxisbuch Usability und UX

Praxisbuch Usability und UX


Zum Rheinwerk-Shop: Flutter und Dart

Flutter und Dart


Zum Rheinwerk-Shop: App-Design

App-Design


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und in die Schweiz
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2023
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 
[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern