จะใช้ 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.