Migracja na Androida

Aktualizowanie importów Gradle

Nowy pakiet SDK wymaga tylko jednej zależności dla każdego interfejsu API ML Kit. Nie musisz określać popularnych bibliotek, takich jak firebase-ml-vision czy firebase-ml-natural-language. ML Kit używa przestrzeni nazw com.google.android.gms w przypadku bibliotek, które zależą od usług Google Play.

Interfejsy Vision API

Modele pakietowe są dostarczane w ramach aplikacji. Modele uproszczone muszą zostać pobrane. Niektóre interfejsy API są dostępne w wersji pakietowej i uproszczonej, a inne tylko w jednej z nich:

Interfejs APIŁączenie w pakietyCienka
Rozpoznawanie tekstux (beta)x
Wykrywanie twarzyxx
Skanowanie kodów kreskowychxx
Dodawanie etykiet do obrazówxx
Wykrywanie i śledzenie obiektówx-

Zaktualizuj zależności dla bibliotek ML Kit na Androida w pliku Gradle modułu (na poziomie aplikacji) (zwykle app/build.gradle) zgodnie z tymi tabelami:

Modele w pakiecie

Interfejs APIStare artefaktyNowy artefakt
Skanowanie kodów kreskowych com.google.firebase:firebase-ml-vision:24.0.1
com.google.firebase:firebase-ml-vision-barcode-model:16.0.1
com.google.mlkit:barcode-scanning:17.3.0
Kontur twarzy com.google.firebase:firebase-ml-vision:24.0.1
com.google.firebase:firebase-ml-vision-face-model:19.0.0
com.google.mlkit:face-detection:16.1.7
Dodawanie etykiet do obrazów com.google.firebase:firebase-ml-vision:24.0.1
com.google.firebase:firebase-ml-vision-image-label-model:19.0.0
com.google.mlkit:image-labeling:17.0.9
Wykrywanie obiektów com.google.firebase:firebase-ml-vision:24.0.1
com.google.firebase:firebase-ml-vision-object-detection-model:19.0.3
com.google.mlkit:object-detection:17.0.2

Cienkie modele

Interfejs APIStare artefaktyNowy artefakt
Skanowanie kodów kreskowych com.google.firebase:firebase-ml-vision:24.0.1 com.google.android.gms:play-services-mlkit-barcode-scanning:18.3.1
Wykrywanie twarzy com.google.firebase:firebase-ml-vision:24.0.1 com.google.android.gms:play-services-mlkit-face-detection:17.1.0
Rozpoznawanie tekstu com.google.firebase:firebase-ml-vision:24.0.1 com.google.android.gms:play-services-mlkit-text-recognition:19.0.1

AutoMLVision Edge

Interfejs APIStary artefaktNowy artefakt
AutoML bez pobierania com.google.firebase:firebase-ml-vision:24.0.1
com.google.firebase:firebase-ml-vision-automl:18.0.3
com.google.mlkit:image-labeling-custom:17.0.3
AutoML z pobieraniem com.google.firebase:firebase-ml-vision:24.0.1
com.google.firebase:firebase-ml-vision-automl:18.0.3
com.google.mlkit:image-labeling-custom:17.0.3
com.google.mlkit:linkfirebase:17.0.0

Interfejsy Natural Language API

Modele pakietowe są dostarczane w ramach aplikacji. Modele cienkie muszą zostać pobrane:

Interfejs APIŁączenie w pakietyCienka
Identyfikator językaxx
Inteligentna odpowiedźxx (beta)

Zaktualizuj zależności dla bibliotek ML Kit na Androida w pliku Gradle modułu (na poziomie aplikacji) (zwykle app/build.gradle) zgodnie z tymi tabelami:

Modele w pakiecie

Interfejs APIStare artefaktyNowy artefakt
Identyfikator języka com.google.firebase:firebase-ml-natural-language:22.0.0
com.google.firebase:firebase-ml-natural-language-language-id-model:20.0.7
com.google.mlkit:language-id:17.0.6
Inteligentna odpowiedź com.google.firebase:firebase-ml-natural-language:22.0.0
com.google.firebase:firebase-ml-natural-language-smart-reply-model:20.0.7
com.google.mlkit:smart-reply:17.0.4

Cienkie modele

Interfejs APIStare artefaktyNowy artefakt
Identyfikator języka com.google.firebase:firebase-ml-natural-language:22.0.0
com.google.firebase:firebase-ml-natural-language-language-id-model:20.0.7
com.google.android.gms:play-services-mlkit-language-id:17.0.0
Inteligentna odpowiedź com.google.firebase:firebase-ml-natural-language:22.0.0
com.google.firebase:firebase-ml-natural-language-smart-reply-model:20.0.7
com.google.android.gms:play-services-mlkit-smart-reply:16.0.0-beta1

Aktualizowanie nazw klas

Jeśli Twoja klasa jest widoczna w tej tabeli, wprowadź wskazaną zmianę:

Stara klasaNowe zajęcia
com.google.firebase.ml.common.FirebaseMLException com.google.mlkit.common.MlKitException
com.google.firebase.ml.vision.common.FirebaseVisionImage com.google.mlkit.vision.common.InputImage
com.google.firebase.ml.vision.barcode.FirebaseVisionBarcodeDetector com.google.mlkit.vision.barcode.BarcodeScanner
com.google.firebase.ml.vision.labeler.FirebaseVisionImageLabel com.google.mlkit.vision.label.ImageLabeler
com.google.firebase.ml.vision.barcode.FirebaseVisionBarcodeDetector com.google.mlkit.vision.barcode.BarcodeScanner
com.google.firebase.ml.vision.automl.FirebaseAutoMLLocalModel com.google.mlkit.common.model.LocalModel
com.google.firebase.ml.vision.automl.FirebaseAutoMLRemoteModel com.google.mlkit.common.model.CustomRemoteModel
com.google.firebase.ml.vision.label.FirebaseVisionOnDeviceImageLabelerOptions com.google.mlkit.vision.label.defaults.ImageLabelerOptions
com.google.firebase.ml.vision.label.FirebaseVisionImageLabel com.google.mlkit.vision.label.ImageLabel
com.google.firebase.ml.vision.label.FirebaseVisionOnDeviceAutoMLImageLabelerOptions com.google.mlkit.vision.label.custom.CustomImageLabelerOptions
com.google.firebase.ml.vision.objects.FirebaseVisionObjectDetectorOptions com.google.mlkit.vision.objects.defaults.ObjectDetectorOptions

W przypadku innych klas postępuj zgodnie z tymi regułami:

  • Usuń prefiks FirebaseVision z nazwy zajęć.
  • Usuń z nazwy zajęć inne prefiksy zaczynające się od prefiksu Firebase.

W nazwach pakietów zastąp prefiks com.google.firebase.ml prefiksem com.google.mlkit.

Aktualizowanie nazw metod

Wymaga to minimalnych zmian w kodzie:

  • Zmieniono instancję wykrywacza, skanera, etykietującego lub tłumacza. Każda funkcja ma teraz własny punkt wejścia. Na przykład: BarcodeScanning, TextRecognition, ImageLabeling, Translation… Wywołania usługi Firebase getInstance() są zastępowane wywołaniami metody getClient() punktu wejścia funkcji.
  • Domyślne tworzenie instancji klasy TextRecognizer zostało usunięte, ponieważ wprowadziliśmy dodatkowe biblioteki do rozpoznawania innych skryptów, takich jak chiński i koreański. Aby używać opcji domyślnych z modelem rozpoznawania tekstu w alfabecie łacińskim, zadeklaruj zależność od com.google.android.gms:play-services-mlkit-text-recognition i użyj TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS).
  • Usunęliśmy domyślne tworzenie instancji dla funkcji ImageLabeler i ObjectDetector, ponieważ wprowadziliśmy obsługę modeli niestandardowych w przypadku tych 2 funkcji. Jeśli na przykład chcesz użyć opcji domyślnych z modelem podstawowym w usłudze ImageLabeling, zadeklaruj zależność od com.google.mlkit:image-labeling i użyj ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS) w Javie.
  • Wszystkie uchwyty (detektor, skaner, etykietujący, tłumacz…) można zamknąć. Upewnij się, że metoda close() jest wywoływana, gdy te obiekty nie będą już używane. Jeśli używasz ich we fragmencie lub w klasie AppCompatActivity, możesz to zrobić, wywołując LifecycleOwner.getLifecycle() we fragmencie lub w klasie AppCompatActivity, a następnie wywołując Lifecycle.addObserver.
  • processImage()detectInImage() w interfejsach Vision API zostały zmienione na process() w celu zachowania spójności.
  • Interfejsy Natural Language API używają teraz terminu „tag języka” (zgodnie z standardem BCP 47) zamiast „kodu języka”.
  • Usunięto metody pobierania w klasach xxxOptions.
  • Metoda getBitmap() w klasie InputImage(zastępująca FirebaseVisionImage) nie jest już obsługiwana w ramach interfejsu publicznego. Aby uzyskać mapę bitową przekonwertowaną z różnych danych wejściowych, zapoznaj się z BitmapUtils.javaprzykładowym projekcie ML Kit.
  • Klasa FirebaseVisionImageMetadata została usunięta. Możesz po prostu przekazywać metadane obrazu, takie jak szerokość, wysokość, rotationDegrees i format, do metod konstrukcyjnych klasy InputImage.

Oto kilka przykładów starych i nowych metod w języku Kotlin:

Stary

// Construct image labeler with base model and default options.
val imageLabeler = FirebaseVision.getInstance().onDeviceImageLabeler

// Construct object detector with base model and default options.
val objectDetector = FirebaseVision.getInstance().onDeviceObjectDetector

// Construct face detector with given options
val faceDetector = FirebaseVision.getInstance().getVisionFaceDetector(options)

// Construct image labeler with local AutoML model
val localModel =
    FirebaseAutoMLLocalModel.Builder()
      .setAssetFilePath("automl/manifest.json")
      .build()
val autoMLImageLabeler =
    FirebaseVision.getInstance()
      .getOnDeviceAutoMLImageLabeler(
          FirebaseVisionOnDeviceAutoMLImageLabelerOptions.Builder(localModel)
            .setConfidenceThreshold(0.3F)
            .build()
    )

Nowy

// Construct image labeler with base model and default options.
val imageLabeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)
// Optional: add life cycle observer
lifecycle.addObserver(imageLabeler)

// Construct object detector with base model and default options.
val objectDetector = ObjectDetection.getClient(ObjectDetectorOptions.DEFAULT_OPTIONS)

// Construct face detector with given options
val faceDetector = FaceDetection.getClient(options)

// Construct image labeler with local AutoML model
val localModel =
  LocalModel.Builder()
    .setAssetManifestFilePath("automl/manifest.json")
    .build()
val autoMLImageLabeler =
  ImageLabeling.getClient(
    CustomImageLabelerOptions.Builder(localModel)
    .setConfidenceThreshold(0.3F).build())
  

Oto przykłady starych i nowych metod Javy:

Stary

// Construct image labeler with base model and default options.
FirebaseVisionImageLabeler imagelLabeler =
     FirebaseVision.getInstance().getOnDeviceImageLabeler();

// Construct object detector with base model and default options.
FirebaseVisionObjectDetector objectDetector =
     FirebaseVision.getInstance().getOnDeviceObjectDetector();

// Construct face detector with given options
FirebaseVisionFaceDetector faceDetector =
     FirebaseVision.getInstance().getVisionFaceDetector(options);

// Construct image labeler with local AutoML model
FirebaseAutoMLLocalModel localModel =
    new FirebaseAutoMLLocalModel.Builder()
      .setAssetFilePath("automl/manifest.json")
      .build();
FirebaseVisionImageLabeler autoMLImageLabeler =
    FirebaseVision.getInstance()
      .getOnDeviceAutoMLImageLabeler(
          FirebaseVisionOnDeviceAutoMLImageLabelerOptions.Builder(localModel)
            .setConfidenceThreshold(0.3F)
            .build());

Nowy

// Construct image labeler with base model and default options.
ImageLabeler imageLabeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS);
// Optional: add life cycle observer
getLifecycle().addObserver(imageLabeler);

// Construct object detector with base model and default options.
ObjectDetector objectDetector = ObjectDetection.getClient(ObjectDetectorOptions.DEFAULT_OPTIONS);

// Construct face detector with given options
FaceDetector faceDetector = FaceDetection.getClient(options);

// Construct image labeler with local AutoML model
LocalModel localModel =
  new LocalModel.Builder()
    .setAssetManifestFilePath("automl/manifest.json")
    .build();
ImageLabeler autoMLImageLabeler =
  ImageLabeling.getClient(
    new CustomImageLabelerOptions.Builder(localModel)
    .setConfidenceThreshold(0.3F).build());
  

Zmiany dotyczące interfejsu API

Skanowanie kodów kreskowych

W przypadku interfejsu Barcode Scanning API modele mogą być teraz dostarczane na 2 sposoby:

  • Za pomocą Usług Google Play, czyli „cienki” (zalecane) – zmniejsza rozmiar aplikacji, a model jest współdzielony między aplikacjami. Deweloperzy będą jednak musieli zadbać o to, aby model został pobrany przed pierwszym użyciem.
  • W pliku APK aplikacji, czyli „w pakiecie” – zwiększa to rozmiar aplikacji, ale model jest od razu gotowy do użycia.

Obie implementacje nieco się od siebie różnią. Wersja „pakietowa” ma kilka ulepszeń w porównaniu z wersją „uproszczoną”. Szczegółowe informacje o tych różnicach znajdziesz we wskazówkach dotyczących interfejsu Barcode Scanning API.

Wykrywanie twarzy

W przypadku interfejsu Face Detection API modele można udostępniać na 2 sposoby:

  • Za pomocą Usług Google Play, czyli „cienki” (zalecane) – zmniejsza rozmiar aplikacji, a model jest współdzielony między aplikacjami. Deweloperzy będą jednak musieli zadbać o to, aby model został pobrany przed pierwszym użyciem.
  • Z plikiem APK aplikacji, czyli „w pakiecie” – zwiększa to rozmiar pobieranej aplikacji, ale oznacza, że model jest od razu gotowy do użycia.

Działanie tych implementacji jest takie samo.

Tłumaczenie

  • TranslateLanguage używa teraz czytelnych nazw stałych (np. ENGLISH) zamiast tagów języka (EN). Są one też teraz @StringDef zamiast @IntDef, a wartością stałej jest pasujący tag języka BCP 47.

  • Jeśli Twoja aplikacja korzysta z opcji warunku pobierania „urządzenie nie jest używane”, pamiętaj, że została ona usunięta i nie można jej już używać. Nadal możesz korzystać z opcji „Ładowanie urządzenia”. Jeśli chcesz uzyskać bardziej złożone działanie, możesz opóźnić wywołanie funkcji RemoteModelManager.download za pomocą własnej logiki.

AutoML Image Labeling

Jeśli Twoja aplikacja korzysta z opcji warunku pobierania „urządzenie jest nieaktywne”, pamiętaj, że ta opcja została usunięta i nie można jej już używać. Nadal możesz korzystać z opcji „ładowanie urządzenia”.

Jeśli chcesz uzyskać bardziej złożone działanie, możesz opóźnić wywołanie funkcji RemoteModelManager.download za pomocą własnej logiki.

Wykrywanie i śledzenie obiektów

Jeśli Twoja aplikacja korzysta z wykrywania obiektów z grubym podziałem na kategorie, pamiętaj, że nowy pakiet SDK zmienił sposób zwracania kategorii klasyfikacji wykrytych obiektów.

Kategoria klasyfikacji jest zwracana jako instancja DetectedObject.Label, a nie jako liczba całkowita. Wszystkie możliwe kategorie klasyfikatora zgrubnego są uwzględnione w klasie PredefinedCategory.

Oto przykład starego i nowego kodu w Kotlinie:

Stary

if (object.classificationCategory == FirebaseVisionObject.CATEGORY_FOOD) {
    ...
}

Nowy

if (!object.labels.isEmpty() && object.labels[0].text == PredefinedCategory.FOOD) {
    ...
}
// or
if (!object.labels.isEmpty() && object.labels[0].index == PredefinedCategory.FOOD_INDEX) {
    ...
}

Oto przykład starego i nowego kodu w Javie:

Stary

if (object.getClassificationCategory() == FirebaseVisionObject.CATEGORY_FOOD) {
    ...
}

Nowy

if (!object.getLabels().isEmpty()
    && object.getLabels().get(0).getText().equals(PredefinedCategory.FOOD)) {
    ...
}
// or
if (!object.getLabels().isEmpty()
    && object.getLabels().get(0).getIndex() == PredefinedCategory.FOOD_INDEX) {
    ...
}

Kategoria „Nieznane” została usunięta. Gdy ufność klasyfikacji obiektu jest niska, nie zwracamy żadnej etykiety.

Usuwanie zależności Firebase (opcjonalnie)

Ten krok jest wykonywany tylko wtedy, gdy są spełnione te warunki:

  • Firebase ML Kit to jedyny komponent Firebase, którego używasz.
  • Używasz tylko interfejsów API na urządzeniu.
  • Nie używasz obsługi modelu.

W takim przypadku po migracji możesz usunąć zależności Firebase. Wykonaj te czynności:

  • Usuń plik konfiguracyjny Firebase, usuwając plik konfiguracyjny google-services.json w katalogu modułu (na poziomie aplikacji) aplikacji.
  • Zastąp wtyczkę Gradle usług Google w pliku Gradle na poziomie modułu (aplikacji) (zwykle app/build.gradle) wtyczką Strict Version Matcher:

Przed

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'  // Google Services plugin

android {
  // …
}

Po

apply plugin: 'com.android.application'
apply plugin: 'com.google.android.gms.strict-version-matcher-plugin'

android {
  // …
}
  • Zastąp ścieżkę klasy wtyczki Gradle usług Google w pliku Gradle projektu (na poziomie głównym) (build.gradle) ścieżką klasy wtyczki Strict Version Matcher:

Przed

buildscript {
  dependencies {
    // ...

    classpath 'com.google.gms:google-services:4.3.3'  // Google Services plugin
  }
}

Po

buildscript {
  dependencies {
    // ...

    classpath 'com.google.android.gms:strict-version-matcher-plugin:1.2.1'
  }
}

Usuń aplikację Firebase w konsoli Firebase zgodnie z instrukcjami na stronie pomocy Firebase.

Uzyskiwanie pomocy

Jeśli napotkasz jakiekolwiek problemy, zajrzyj na naszą stronę społeczności, na której opisujemy kanały, za pomocą których możesz się z nami skontaktować.