Jak używać aparatu lub interfejsu API camera2 systemu Android do obsługi starych i nowych wersji interfejsu API bez uwag o wycofaniu?


135

Nowe API camera2 wprawia mnie w zakłopotanie. Chcę stworzyć aplikację (dla Android API 10-21), która korzysta z aparatu urządzenia. Jak wspomniano tutaj , powinno się używać „Aparat” API.

Jednak gdy próbuję dodać interfejs API „Camera” (android.hardware.Camera) do funkcji użytkownika manifestu, jest on oznaczany jako przestarzały . Z drugiej strony nie mogę go zmienić na API "camera2" (android.hardware.camera2), ponieważ jest kompatybilny tylko z Android API 21+ (Android 5 - Lollipop) - też bym go połączył, ale mogę tylko dodać 2 linki.

Chcę, aby moja aplikacja działała nie tylko na starszych wersjach Androida, ale także na najnowszej ...

Odpowiedzi:


152

Mimo że stary interfejs API aparatu jest oznaczony jako przestarzały, nadal jest w pełni funkcjonalny i pozostanie taki przez dłuższy czas (ponieważ obecnie używają go prawie wszystkie aplikacje korzystające z aparatu w Sklepie Play).

Będziesz musiał zignorować skargi Android Studio na to, że jest przestarzałe, ale jeśli chcesz obsługiwać wersje Androida wcześniejsze niż 21, musisz użyć starego interfejsu API.

Na poziomie API 21 z pewnością możesz korzystać z nowego interfejsu API i jego nowych funkcji, ale obecnie będziesz musiał utrzymywać całkowicie oddzielny przepływ w swojej aplikacji, jeśli przełączysz się między interfejsami API. Niestety, oba interfejsy API mają na tyle inny światopogląd, że trudno jest napisać bibliotekę wsparcia, która pozwoliłaby na użycie czegoś takiego jak nowe API również na starszych urządzeniach (gdzie biblioteka mapuje z nowego API na stare API, jeśli nie na API 21+).


1
Dobra odpowiedź. Więc jeśli chcesz obsługiwać API na poziomie 16 i wyższym, lepiej na razie trzymać się starego aparatu, prawda?
Loolooii

5
więc jedynym sposobem jest użycie instrukcji if i android.os.Build.VERSION.SDK_INT do oddzielenia kodu?
hadi

Tak więc dla programisty, jeśli celujesz tylko w API 21 i nowsze, użyj Camera2, ale jeśli potrzebujesz starszej obsługi, użyj aparatu? A może zaleciłbyś wykrywanie wersji kompilacji i kodowanie 2 różnych metod przy użyciu różnych interfejsów API?
john.weland

2
To zależy od tego, co robi Twoja aplikacja. Jeśli funkcja aparatu jest prosta i chcesz nakierować na stare interfejsy API, po prostu użyj starego interfejsu Camera API. Ale jeśli chcesz zrobić coś więcej niż tylko pobrać pliki JPEG i narysować podgląd, lub jeśli celujesz tylko w nowe interfejsy API, skorzystaj z camera2. W (twardym) środku znajdują się aplikacje, które chcą oferować fantazyjne opcjonalne funkcje w aparacie 2, ale działają również na starych urządzeniach. Tam musisz zbudować dwie oddzielne ścieżki kodowe, po jednej dla każdego interfejsu API.
Eddy Talvala,

21
Wycofanie Camera API było błędem, powinni byli wprowadzić zaawansowane API Camera (dla zaawansowanych aplikacji, takich jak pełnoprawne aplikacje do aparatów) - w przeciwnym razie (większość) aplikacji, które używają aparatu tylko do zrobienia zdjęcia, musiałyby obsługiwać 2 interfejsy API. Google powinien był przynajmniej wprowadzić kompaktową bibliotekę (jak zawsze)
Sudara

38

Umieść wszystkie potrzebne metody z kamery w interfejsie, a następnie utwórz taką instancję kamery

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Log.d(TAG, "camera2 selected");
        this.camera = new Camera2(getContext());
    } else {
        Log.d(TAG, "camera1 selected");
        this.camera = new Camera1(getContext());
    }

W ten sposób wszystko się rozdzieli, a to znacznie ułatwi ci życie.

Mała rada - życie z aparatem camera2 nie jest takie wspaniałe. Sprzedawcy nadal robią badziewne implementacje, więc będziesz musiał dodać wiele warunków i obejść.

Przykład 1 - S6 zgłasza, że ​​nie obsługuje Flasha :) Przykład 2 - Urządzenie LG zgłasza listę obsługiwanych rozmiarów obrazów - jednak nie wszystkie z nich są faktycznie obsługiwane !!


14
To prawda. Camera 2 API faktycznie dzieli urządzenia kamer na trzy kategorie: LEGACY, LIMITED i FULL. Jeśli kamera jest sklasyfikowana jako LEGACY, wszystkie wywołania API camera2 są tłumaczone na camera1 pod maską, więc naprawdę nie warto się tym przejmować. Moją sugestią jest wywołanie CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraID); if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)... i wybranie starego API, jeśli jest prawdziwe.
panonski

9

Aby obsługiwać żądany interfejs API, użyj poniższego kodu. Po prostu określ odpowiednie nazwy odpowiadające poziomom API. Na przykład API 21 to LOLLIPOP, a API 15 to ICE_CREAM_SANDWICH_MR1.

 if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)  
                                    && ((Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP))) {
           // your code here - is between 15-21

 } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
           // your code here - is api 21
 }

33
jest to mało praktyczne w przypadku pełnej implementacji aparatu. plus, teraz musisz zachować dwie ścieżki kodowe. Sprawdzanie wersji ma swoje zastosowanie w programowaniu na Androida, ale to nie jest to.
katzenhut

5
Co się stanie, jeśli użytkownik uruchomi Build.VERSION_CODES.LOLLIPOP_MR1? Czy coś ponad tym? Myślę, że drugie sprawdzenie powinno brzmieć „else if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP)”
Ralph Pina,

Kochani, jak mogę zbudować ten sam apk camera2 i stary interfejs API, jeśli moje aplikacje powinny działać w 16 i nowszych api? Smaki są dobre do tej pracy?
Mateus,

Musisz zaimplementować oba API. Wystarczy zachować interfejs i dwie klasy, w których zaimplementowano funkcjonalność aparatu. Przed utworzeniem jednej z instancji do uruchamiania kamery wywołaj powyższą metodę, aby mogła dowiedzieć się, którą klasę i funkcję wywołać
user0770

3

Chociaż to, co zaleca Google, użyj Camera2 Api> = 21, ale możesz mieć problem z ustawieniami ręcznymi.

Kiedy potrzebujesz aplikacji do robienia zdjęć w trybie ustawień automatycznych, będzie działać dobrze. Ale! W razie potrzeby utwórz aplikację z implementacją trybu ustawień ręcznych, dla urządzeń, które mają API> = 21, najpierw sprawdź obsługiwany POZIOM SPRZĘTU:

Wybierz kamerę (przód, twarz), uzyskaj jej charakterystykę i sprawdź POZIOM SPRZĘTU.

mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId)

val level = mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)

CameraCharacteristics reprezentują kolejne obsługiwane poziomy: LIMITED, FULL, LEGACY, LEVEL_3, EXTERNAL.

Na wysokim poziomie poziomy to:

Urządzenia LEGACY działają w trybie kompatybilności wstecznej dla starszych urządzeń z Androidem i mają bardzo ograniczone możliwości.

Urządzenia OGRANICZONE reprezentują podstawowy zestaw funkcji i mogą również obejmować dodatkowe możliwości, które stanowią podzbiory FULL.

PEŁNE urządzenia dodatkowo obsługują ręczne sterowanie dla poszczególnych klatek ustawieniami czujnika, lampy błyskowej, obiektywu i przetwarzania końcowego oraz przechwytywanie obrazu z dużą szybkością.

Urządzenia LEVEL_3 dodatkowo obsługują ponowne przetwarzanie YUV i przechwytywanie obrazu RAW, a także dodatkowe konfiguracje strumienia wyjściowego.

Jeśli masz poziom supprot LEGACY , powinieneś użyć starego interfejsu Camera Api .



0

Plz read link Obsługa wersji kamery Stwierdzają, że ....
Camera API1
Android 5.0 jest przestarzały Camera API1, który nadal jest wycofywany, ponieważ rozwój nowej platformy koncentruje się na Camera API2. Jednak okres wycofywania będzie długi, a wersje Androida będą przez pewien czas nadal obsługiwać aplikacje Camera API1. W szczególności wsparcie jest kontynuowane dla:

  • Interfejsy Camera API1 dla aplikacji. Aplikacje aparatu utworzone w oparciu o Camera API1 powinny działać tak samo, jak na urządzeniach z wcześniejszymi wersjami Androida.
  • Wersje HAL aparatu. Obejmuje obsługę aparatu HAL1.0.

  • -1

    Dowiedziałem się, że najlepszą opcją jest utworzenie dwóch zajęć. Użyj ogólnego sposobu, aby sprawdzić bieżący interfejs API urządzenia

    Intent i;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        i = new Intent(context,camera2.class)
    } else {
        i = new Intent(context,camera.class);
    }
    startActivity(i);

    W ten sposób nie muszę mieć dużo zamieszania, gdy patrzę wstecz na kod. Kod można łatwo modyfikować, ponieważ został oddzielony.

    Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
    Licensed under cc by-sa 3.0 with attribution required.