Kopia zapasowa poączeń

Projekt B4A: Backup i przywracanie połączeń, SMS i MMS

Dla Androida 15/16 i prywatnego pliku APK proponuję zbudować aplikację etapami, w B4A 14.00, bez przenoszenia projektu do Android Studio.

Najważniejsza decyzja techniczna: aplikacja ma odtwarzać dane w systemowych rejestrach, a nie tylko wyświetlać ich kopię. Android pozwala czytać dostawcę SMS/MMS, ale zapisywać wiadomości bezpośrednio do systemowej bazy może tylko aplikacja z rolą domyślnej aplikacji SMS. Android Developers +1

Historia połączeń jest osobnym mechanizmem. W przypadku pełnego przywracania trzeba też obsłużyć uprawnienia do zapisu historii połączeń oraz sprawdzić zachowanie konkretnego telefonu.

Plan projektu

Etap 1. Szkielet aplikacji i uprawnienia Zaczynamy tutaj Projekt B4A, ekran główny, sprawdzanie uprawnień, katalog kopii zapasowych i diagnostyka.

Etap 2. Historia połączeń Odczyt CallLog, eksport numerów, dat, typów połączeń i czasu trwania; następnie import.

Etap 3. SMS Odczyt i zapis wiadomości, zachowanie dat, wątków, statusów i kierunku wiadomości.

Etap 4. MMS Odczyt nagłówków, uczestników, tekstu i załączników. Przywracanie z kontrolą poprawności plików.

Etap 5. Archiwum i odtwarzanie Jeden plik ZIP, manifest wersji, kontrola integralności, raport importu i ochrona przed duplikatami.

Jak będzie wyglądać aplikacja?

Etap 1 — tworzymy projekt w B4A Na początek uruchomimy aplikację i sprawdzimy, czy Android zezwala jej na odczyt historii połączeń. Nie będziemy jeszcze niczego zapisywać ani modyfikować w telefonie.

Krok 1. Utwórz projekt

W B4A wybierz File → New Project → Default. Ustaw nazwę projektu, np. PhoneBackup. W Designerze dodaj:

Element Nazwa Tekst
Label lblStatus Gotowy
Button btnPermissions Sprawdź uprawnienia
Button btnTestCalls Test odczytu połączeń
Label lblResult Wynik testu pojawi się tutaj

Na razie wystarczy prosty układ pionowy.

Krok 2. Dodaj uprawnienia

W edytorze manifestu B4A dodaj:

AddPermission(android.permission.READ_CALL_LOG)
AddPermission(android.permission.WRITE_CALL_LOG)

Do sprawdzenia historii wystarczy READ_CALL_LOG. WRITE_CALL_LOG będzie potrzebne na etapie przywracania i samo zadeklarowanie go nie gwarantuje, że Android zezwoli na zapis.

W zakładce Libraries zaznacz bibliotekę RuntimePermissions.

Krok 3. Kod modułu Main

Poniższy kod zakłada, że korzystasz z klasycznego projektu Default, a nie B4XPages. Wklej go do Main i dopasuj nazwy kontrolek do tych z Designera.


Sub Process_Globals
    Private rp As RuntimePermissions
End Sub

Sub Globals
    Private lblStatus As Label
    Private lblResult As Label
    Private btnPermissions As Button
    Private btnTestCalls As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Main")
    lblStatus.Text = "Phone Backup - gotowy"
    lblResult.Text = "Nie wykonano jeszcze testu."
End Sub

Sub btnPermissions_Click
    rp.CheckAndRequest("android.permission.READ_CALL_LOG")
End Sub

Sub Activity_PermissionResult (Permission As String, Result As Boolean)
    If Permission = "android.permission.READ_CALL_LOG" Then
        If Result Then
            lblStatus.Text = "Dostęp do historii połączeń przyznany"
        Else
            lblStatus.Text = "Brak dostępu do historii połączeń"
        End If
    End If
End Sub

Sub btnTestCalls_Click
    If rp.Check("android.permission.READ_CALL_LOG") = False Then
        lblResult.Text = "Najpierw przyznaj uprawnienie."
        Return
    End If

    Try
        Dim jo As JavaObject
        jo.InitializeContext

        Dim resolver As JavaObject
        resolver = jo.RunMethod("getContentResolver", Null)

        Dim uri As JavaObject
        uri.InitializeStatic("android.net.Uri")
        Dim callsUri As Object = uri.RunMethod( _
            "parse", Array("content://call_log/calls"))

        Dim cursor As JavaObject
        cursor = resolver.RunMethod("query", Array( _
            callsUri, Null, Null, Null, "date DESC"))

        If cursor.IsInitialized = False Then
            lblResult.Text = "Nie udało się odczytać danych."
            Return
        End If

        Dim count As Int = cursor.RunMethod("getCount", Null)
        cursor.RunMethod("close", Null)

        lblResult.Text = "Liczba wpisów historii: " & count

    Catch
        lblResult.Text = "Błąd odczytu: " & LastException.Message
        Log(LastException)
    End Try
End Sub

W kodzie wykorzystujemy również bibliotekę JavaObject — zaznacz ją w Libraries, jeśli nie jest już aktywna.

Krok 4. Uruchom test

  1. Skompiluj projekt i zainstaluj APK na telefonie.
  2. Naciśnij „Sprawdź uprawnienia”.
  3. Zaakceptuj dostęp, jeśli Android wyświetli odpowiednie pytanie.
  4. Naciśnij „Test odczytu połączeń”.

Jeśli wszystko działa, zobaczysz liczbę wpisów w historii. Na tym etapie nie odczytujemy jeszcze treści wiadomości i nie zapisujemy kopii.

Ważna uwaga dotycząca SMS/MMS Pełne przywracanie wiadomości wymaga kolejnego, większego kroku: przygotowania aplikacji zgodnej z rolą domyślnej aplikacji SMS, a następnie poproszenia użytkownika o jej aktywowanie. Android wymaga tego do zapisu w systemowym rejestrze SMS/MMS.

W praktyce nie będziemy próbować omijać tych zabezpieczeń przez bezpośrednią modyfikację systemowej bazy.

Zróbmy teraz tylko ten pierwszy test. Jeśli projekt się skompiluje i pokaże liczbę połączeń, przejdziemy do Etapu 2: odczytania pełnych rekordów historii i zapisania ich do pliku kopii zapasowej.