จะใช้ API ของกล้องหรือ camera2 ของ Android เพื่อรองรับ API เวอร์ชันเก่าและเวอร์ชันใหม่โดยไม่มีบันทึกการเลิกใช้งานได้อย่างไร


135

camera2 API ใหม่ทำให้ฉันสับสน ฉันต้องการพัฒนาแอป(สำหรับ Android APIs 10 - 21)ซึ่งใช้กล้องของอุปกรณ์ ตามที่ระบุไว้ที่นี่ฉันควรใช้ API "กล้องถ่ายรูป"

แต่เมื่อฉันพยายามที่จะเพิ่ม "กล้อง" API (android.hardware.Camera)จะประจักษ์ของคุณสมบัติที่ใช้งาน, มันถูกทำเครื่องหมายว่าเลิก ในทางกลับกันฉันไม่สามารถเปลี่ยนเป็น API "camera2" (android.hardware.camera2) ได้เนื่องจากเข้ากันได้กับ Android API 21+ เท่านั้น (Android 5 - Lollipop) - จะเชื่อมโยงด้วย แต่ฉันสามารถเพิ่มได้เท่านั้น 2 ลิงค์

ฉันไม่เพียง แต่ต้องการให้แอปของฉันทำงานบน Android เวอร์ชันเก่าเท่านั้น แต่ยังเป็นแอปใหม่ล่าสุดด้วย ...

คำตอบ:


153

แม้ว่า API ของกล้องรุ่นเก่าจะถูกทำเครื่องหมายว่าเลิกใช้งานแล้ว แต่ก็ยังใช้งานได้อย่างสมบูรณ์และจะยังคงใช้งานได้อีกระยะหนึ่ง (เนื่องจากแอปพลิเคชันที่ใช้กล้องเกือบทั้งหมดใน Play Store ใช้อยู่ในปัจจุบัน)

คุณจะต้องเพิกเฉยต่อคำร้องเรียนของ Android Studio เกี่ยวกับการเลิกใช้งาน แต่ถ้าคุณต้องการรองรับ Android เวอร์ชันก่อนหน้า 21 คุณต้องใช้ API เก่า

ใน API ระดับ 21 คุณสามารถใช้ API ใหม่และคุณลักษณะใหม่ ๆ ได้อย่างแน่นอน แต่ปัจจุบันคุณจะต้องรักษาขั้นตอนที่แยกจากกันทั้งหมดในแอปของคุณหากคุณสลับไปมาระหว่าง API น่าเสียดายที่ API ทั้งสองมีมุมมองที่แตกต่างกันมากพอที่จะเขียนไลบรารีการสนับสนุนที่ช่วยให้คุณใช้บางอย่างเช่น API ใหม่บนอุปกรณ์รุ่นเก่าได้ยากเช่นกัน (โดยที่ไลบรารีจะแมปจาก API ใหม่ไปยัง API เก่าหากไม่มี บน API 21+)


1
คำตอบที่ดี. ดังนั้นหากคุณต้องการรองรับ API ระดับ 16 ขึ้นไปควรยึดติดกับกล้องรุ่นเก่าในตอนนี้ดีกว่าใช่ไหม?
— Loolooii

5
ดังนั้นวิธีเดียวคือใช้ if statement และ android.os.Build.VERSION.SDK_INT เพื่อแยกรหัส?
— hadi

ดังนั้นสำหรับนักพัฒนาหากคุณกำหนดเป้าหมายเฉพาะ API 21 ขึ้นไปให้ใช้ Camera2 แต่ถ้าคุณต้องการการสนับสนุนแบบเดิมให้ใช้ Camera? หรือคุณจะแนะนำให้ตรวจหาเวอร์ชันบิวด์และเข้ารหัส 2 วิธีที่แตกต่างกันโดยใช้ API ที่ต่างกัน
— john.weland

2
ขึ้นอยู่กับว่าแอปของคุณทำอะไร หากการทำงานของกล้องตรงไปตรงมาและคุณต้องการกำหนดเป้าหมาย API เก่าให้ใช้ Camera API แบบเก่า แต่ถ้าคุณต้องการทำบางสิ่งที่มากกว่าแค่คว้า JPEG และวาดภาพตัวอย่างหรือถ้าคุณแค่กำหนดเป้าหมาย API ใหม่ให้ไปกับ camera2 ตรงกลาง (ยาก) คือแอพที่ต้องการนำเสนอคุณสมบัติเสริมแฟนซีใน camera2 แต่ใช้งานได้กับอุปกรณ์รุ่นเก่าด้วย คุณต้องสร้าง codepath สองรายการแยกกันหนึ่งรายการสำหรับแต่ละ API
— Eddy Talvala

22
การเลิกใช้ Camera API เป็นความผิดพลาดพวกเขาควรเปิดตัว Camera ขั้นสูง API (สำหรับแอพขั้นสูงเช่นแอพกล้องถ่ายรูปเต็มรูปแบบ) มิฉะนั้นแอพ (ส่วนใหญ่) ที่ใช้กล้องเพื่อถ่ายภาพจะต้องคงไว้ 2 apis อย่างน้อย Google ควรเปิดตัวห้องสมุดขนาดกะทัดรัด (เช่นเคย)
— Sudara

38

ใส่วิธีการทั้งหมดจากกล้องที่คุณต้องการในอินเทอร์เฟซจากนั้นสร้างอินสแตนซ์กล้องแบบนี้

    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());
    }

วิธีนี้จะทำให้ทุกอย่างแตกแยกและจะทำให้ชีวิตของคุณง่ายขึ้นมาก

คำแนะนำ - ชีวิตกับ camera2 ไม่ได้ยอดเยี่ยมขนาดนั้น ผู้ขายยังคงใช้งานอึและคุณจะต้องเพิ่มเงื่อนไขและวิธีแก้ปัญหามากมาย

ตัวอย่างที่ 1 - S6 รายงานว่าไม่รองรับแฟลช :) ตัวอย่างที่ 2 - อุปกรณ์ LG รายงานกลับรายการขนาดภาพที่รองรับ - แต่ไม่รองรับทั้งหมดจริง !!


14
นี่คือเรื่องจริง Camera 2 API แบ่งอุปกรณ์กล้องออกเป็นสามประเภท: LEGACY, LIMITED และ FULL หากกล้องถูกจัดประเภทเป็น LEGACY การเรียกใช้ Camera2 API ทั้งหมดจะถูกแปลเป็น camera1 ภายใต้ฝากระโปรงดังนั้นจึงไม่คุ้มค่ากับความยุ่งยาก คำแนะนำของฉันคือโทรCameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraID); if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)... และเลือก API เก่าหากเป็นจริง
— panonski

9

ในการรองรับ api ที่คุณต้องการให้ใช้รหัสด้านล่าง เพียงกำหนดชื่อที่เหมาะสมที่สอดคล้องกับระดับ API ตัวอย่างเช่น API 21 คือ LOLLIPOP และ API 15 คือ 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
ซึ่งแทบจะไม่สามารถใช้งานได้จริงสำหรับการใช้งานกล้องเต็มรูปแบบ บวกกับตอนนี้คุณต้องรักษาสอง codepaths การตรวจสอบเวอร์ชันมีการใช้งานในการพัฒนา Android แต่นี่ไม่ใช่
— katzenhut

5
จะเกิดอะไรขึ้นหากผู้ใช้กำลังเรียกใช้ Build.VERSION_CODES.LOLLIPOP_MR1 หรือสิ่งที่เหนือกว่านั้น? ฉันคิดว่าการตรวจสอบครั้งที่สองของคุณควรเป็น "else if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP)"
— Ralph Pina

กลัวฉันจะสร้างใน apk camera2 และ api เดิมได้อย่างไรถ้าแอพของฉันควรจะทำงานใน API 16 และใหม่กว่า รสชาติดีสำหรับงานนี้?
— Mateus

คุณต้องใช้ทั้ง apis เพียงแค่เก็บอินเทอร์เฟซและสองคลาสไว้ซึ่งฟังก์ชันกล้องจะถูกนำมาใช้ ก่อนที่จะสร้างหนึ่งของกรณีสำหรับการทำงานกล้องเรียกวิธีการดังกล่าวข้างต้นเพื่อที่จะสามารถหาที่เรียนและการทำงานเพื่อโทร
— user0770

3

แม้ว่าสิ่งที่ Google แนะนำให้ใช้ Camera2 Api> = 21 แต่คุณอาจมีปัญหากับการตั้งค่าด้วยตนเอง

เมื่อคุณต้องการใช้แอพสำหรับถ่ายภาพด้วยโหมดตั้งค่าอัตโนมัติมันจะทำงานได้ดี แต่! หากต้องการสร้างแอปโดยใช้โหมดการตั้งค่าด้วยตนเองสำหรับอุปกรณ์ที่มี API> = 21 ประการแรกต้องตรวจสอบระดับฮาร์ดแวร์ที่รองรับ:

เลือกกล้อง (ด้านหน้า, ใบหน้า), ดูลักษณะและตรวจสอบระดับฮาร์ดแวร์

mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId)

val level = mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)

CameraCharacteristics แสดงถึงระดับที่รองรับต่อไป: LIMITED, FULL, LEGACY, LEVEL_3, EXTERNAL

ในระดับสูงระดับ ได้แก่ :

อุปกรณ์LEGACYทำงานในโหมดความเข้ากันได้แบบย้อนกลับสำหรับอุปกรณ์ Android รุ่นเก่าและมีความสามารถที่ จำกัด มาก

อุปกรณ์จำกัดแสดงถึงชุดคุณลักษณะพื้นฐานและอาจรวมถึงความสามารถเพิ่มเติมที่เป็นส่วนย่อยของ FULL

นอกจากนี้อุปกรณ์FULLยังรองรับการควบคุมเซ็นเซอร์แฟลชเลนส์และการตั้งค่าหลังการประมวลผลแบบแมนนวลต่อเฟรมและการจับภาพในอัตราที่สูง

อุปกรณ์LEVEL_3ยังรองรับการประมวลผลใหม่ YUV และการจับภาพ RAW พร้อมกับการกำหนดค่าสตรีมเอาต์พุตเพิ่มเติม

หากคุณมีLEGACYระดับ supprot คุณควรใช้กล้อง Api


1

ใช้คำอธิบายประกอบการสนับสนุน

    @TargetApi(21)

เพื่อหลีกเลี่ยงการตรวจสอบ


1
ดังนั้นคุณจึงไม่รองรับอุปกรณ์ Android ก่อน 21!
— Mina F. Beshay

0

ฉันพบว่าตัวเลือกที่ดีที่สุดคือสร้างกิจกรรมสองอย่าง ใช้วิธีทั่วไปในการตรวจสอบ API อุปกรณ์ปัจจุบัน

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);

วิธีนี้ทำให้ฉันไม่ต้องสับสนเมื่อมองย้อนกลับไปที่รหัส รหัสนี้แก้ไขได้ง่ายเนื่องจากแยกออกจากกัน


0

โปรดอ่านลิงค์การสนับสนุนเวอร์ชันของกล้อง พวกเขาระบุว่า ....
Camera API1
Android 5.0 เลิกใช้งาน Camera API1 ซึ่งจะยังคงหยุดให้บริการเนื่องจากการพัฒนาแพลตฟอร์มใหม่มุ่งเน้นไปที่ Camera API2 อย่างไรก็ตามระยะเวลาการหยุดใช้งานจะยาวนานและ Android รุ่นต่างๆจะยังคงรองรับแอป Camera API1 ต่อไป โดยเฉพาะการสนับสนุนยังคงดำเนินต่อไปสำหรับ:

  • อินเทอร์เฟซ Camera API1 สำหรับแอพ แอปกล้องที่สร้างขึ้นจาก Camera API1 ควรทำงานได้เหมือนกับที่ทำงานบนอุปกรณ์ที่ใช้ Android เวอร์ชันก่อนหน้า
  • กล้องรุ่น HAL รวมถึงการรองรับกล้อง HAL1.0
  • โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
    Licensed under cc by-sa 3.0 with attribution required.