যদি android.hardware.Camera
অবচয় হয় এবং আপনি যদি ভেরিয়েবল ব্যবহার করতে না পারেন তবে Camera
এর বিকল্প কী হবে?
যদি android.hardware.Camera
অবচয় হয় এবং আপনি যদি ভেরিয়েবল ব্যবহার করতে না পারেন তবে Camera
এর বিকল্প কী হবে?
উত্তর:
মতে Android বিকাশকারীদের নির্দেশিকা জন্য android.hardware.Camera
, তারা রাজ্য:
আমরা নতুন অ্যাপ্লিকেশনগুলির জন্য নতুন android.hardware.camera2 API ব্যবহার করার পরামর্শ দিই ।
সম্পর্কিত তথ্যের পৃষ্ঠায় android.hardware.camera2
, (উপরে লিঙ্ক করা) বলা হয়েছে:
Android.hardware.camera2 প্যাকেজটি অ্যান্ড্রয়েড ডিভাইসে সংযুক্ত পৃথক ক্যামেরা ডিভাইসের একটি ইন্টারফেস সরবরাহ করে। এটি অবহেলিত ক্যামেরা শ্রেণীর স্থান করে।
আপনি যখন সেই ডকুমেন্টেশন পরীক্ষা করেন আপনি দেখতে পাবেন যে এই 2 ক্যামেরা এপিআই এর প্রয়োগটি খুব আলাদা।
উদাহরণস্বরূপ ক্যামেরা ওরিয়েন্টেশন চালু করা android.hardware.camera
@Override
public int getOrientation(final int cameraId) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
return info.orientation;
}
বনাম android.hardware.camera2
@Override
public int getOrientation(final int cameraId) {
try {
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String[] cameraIds = manager.getCameraIdList();
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraIds[cameraId]);
return characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
} catch (CameraAccessException e) {
// TODO handle error properly or pass it on
return 0;
}
}
এটি এক থেকে অন্যটিতে স্যুইচ করা এবং কোড লিখতে অসুবিধা সৃষ্টি করে যা উভয় বাস্তবায়ন পরিচালনা করতে পারে।
নোট করুন যে এই একক কোড উদাহরণে আমাকে ইতিমধ্যে এই কাজটি করতে হয়েছিল যে int
পুরাতন ক্যামেরা এপিআই ক্যামেরা আইডির জন্য আদিমদের সাথে কাজ করে যখন নতুন একটি String
বস্তুর সাথে কাজ করে। এই উদাহরণের জন্য আমি দ্রুত নতুন এপিআই-তে সূচক হিসাবে ইন্ট ব্যবহার করে তা স্থির করেছি। যদি ক্যামেরার ফিরে আসা সর্বদা একই ক্রমে না থাকে তবে এটি ইতিমধ্যে সমস্যার কারণ হবে। বিকল্প পদ্ধতি হ'ল স্ট্রিং অবজেক্ট এবং স্ট্রিং উপস্থাপনের সাথে পুরানো ইন ক্যামেরাআইডিগুলির প্রতিনিধিত্ব করা যা সম্ভবত নিরাপদ।
এখন এই বিশাল পার্থক্যটি নিয়ে কাজ করার জন্য আপনি প্রথমে একটি ইন্টারফেস প্রয়োগ করতে পারেন এবং আপনার কোডে সেই ইন্টারফেসটি উল্লেখ করতে পারেন।
এখানে আমি সেই ইন্টারফেস এবং 2 টি প্রয়োগের জন্য কিছু কোড তালিকাবদ্ধ করব। কাজের পরিমাণ সীমাবদ্ধ করতে আপনি বাস্তবে ক্যামেরা এপিআইয়ের ব্যবহারটি সীমাবদ্ধ করতে পারেন।
পরবর্তী বিভাগে আমি কীভাবে একে অপরকে লোড করব তা দ্রুত ব্যাখ্যা করব।
আপনার প্রয়োজন সমস্ত ইন্টারফেস মোড়ানো, এই উদাহরণটি সীমাবদ্ধ করার জন্য আমার কাছে এখানে কেবলমাত্র 2 টি পদ্ধতি রয়েছে।
public interface CameraSupport {
CameraSupport open(int cameraId);
int getOrientation(int cameraId);
}
পুরানো ক্যামেরা হার্ডওয়্যার এপিআইয়ের জন্য এখন একটি ক্লাস করুন:
@SuppressWarnings("deprecation")
public class CameraOld implements CameraSupport {
private Camera camera;
@Override
public CameraSupport open(final int cameraId) {
this.camera = Camera.open(cameraId);
return this;
}
@Override
public int getOrientation(final int cameraId) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
return info.orientation;
}
}
এবং নতুন হার্ডওয়্যার এপিআই এর জন্য অন্য একটি:
public class CameraNew implements CameraSupport {
private CameraDevice camera;
private CameraManager manager;
public CameraNew(final Context context) {
this.manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
}
@Override
public CameraSupport open(final int cameraId) {
try {
String[] cameraIds = manager.getCameraIdList();
manager.openCamera(cameraIds[cameraId], new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
CameraNew.this.camera = camera;
}
@Override
public void onDisconnected(CameraDevice camera) {
CameraNew.this.camera = camera;
// TODO handle
}
@Override
public void onError(CameraDevice camera, int error) {
CameraNew.this.camera = camera;
// TODO handle
}
}, null);
} catch (Exception e) {
// TODO handle
}
return this;
}
@Override
public int getOrientation(final int cameraId) {
try {
String[] cameraIds = manager.getCameraIdList();
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraIds[cameraId]);
return characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
} catch (CameraAccessException e) {
// TODO handle
return 0;
}
}
}
এখন আপনার CameraOld
বা CameraNew
শ্রেণীর লোড করতে আপনাকে এপিআই স্তরটি পরীক্ষা করতে হবে যেহেতু CameraNew
কেবলমাত্র এপিআই স্তর 21 থেকে পাওয়া যায়।
আপনার যদি ইতিমধ্যে নির্ভরতা ইনজেকশন সেট আপ থাকে তবে CameraSupport
বাস্তবায়ন সরবরাহ করার সময় আপনি আপনার মডিউলটিতে এটি করতে পারেন । উদাহরণ:
@Module public class CameraModule {
@Provides
CameraSupport provideCameraSupport(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return new CameraNew(context);
} else {
return new CameraOld();
}
}
}
আপনি ডিআই ব্যবহার না করলে আপনি কেবল একটি ইউটিলিটি তৈরি করতে পারেন বা যথাযথটি তৈরি করতে কারখানার প্যাটার্ন ব্যবহার করতে পারেন। গুরুত্বপূর্ণ অংশটি হ'ল এপিআই স্তরটি চেক করা হয়।
@SuppressWarnings
এই QA তে মধ্যে stackoverflow.com/questions/7397996/...
অবহেলিত ক্যামেরা API এর মাধ্যমে পুরানো ডিভাইসগুলিকে সমর্থন করা এবং বর্তমান ডিভাইসগুলির জন্য নতুন ক্যামেরা 2 এপিআইয়ের প্রয়োজন এবং ভবিষ্যতে সরিয়ে নেওয়া একই সমস্যাটির মুখোমুখি ; আমি একই বিষয় গাড়ীতে আঘাত - এবং আছে না যে 2 API গুলি সেতু, সম্ভবত, কারণ তারা খুব ভিন্ন, একটি 3rd পার্টি লাইব্রেরি পাওয়া আমি মৌলিক গলি প্রিন্সিপাল দিকে ফিরে ।
পুরানো এপিআই-তে উপস্থাপিত ইন্টারফেসের প্রত্যাশা করে ক্লায়েন্ট অবজেক্টগুলির জন্য 2 টি এপিআইগুলি তাদের আলাদা আলাদাভাবে ইন্টারকঞ্জিং তৈরি করে। নতুন এপিআই-তে বিভিন্ন পদ্ধতি সহ ভিন্ন ভিন্ন বস্তু রয়েছে, যা একটি ভিন্ন আর্কিটেকচার ব্যবহার করে নির্মিত হয়েছিল। গুগলের জন্য ভালোবাসা পেয়েছি, তবে রাগনাবিট! হতাশাজনক।
সুতরাং আমি আমার অ্যাপ্লিকেশনটির কেবলমাত্র ক্যামেরা কার্যকারিতা নিয়ে দৃষ্টি নিবদ্ধ করে একটি ইন্টারফেস তৈরি করেছি এবং উভয় এপিআইয়ের জন্য একটি সহজ মোড়ক তৈরি করেছি যা সেই ইন্টারফেসটি কার্যকর করে। এইভাবে আমার ক্যামেরার ক্রিয়াকলাপটি কোন প্ল্যাটফর্মটি চলছে তা নিয়ে চিন্তা করার দরকার নেই ...
আমি API (গুলি) পরিচালনা করতে একটি সিঙ্গলটনও স্থাপন করেছি; পুরানো এন্ড্রয়েড ওএস ডিভাইসগুলির জন্য আমার ইন্টারফেসের সাথে পুরানো এপিআইয়ের মোড়ক এবং নতুন এপিআই ব্যবহার করে নতুন ডিভাইসগুলির জন্য নতুন এপিআইয়ের র্যাপার শ্রেণি ইনস্ট্যান্স করছে। সিঙ্গলটনের এপিআই স্তরটি পেতে সাধারণ কোড থাকে এবং তারপরে সঠিক অবজেক্টটি দৃষ্টান্ত দেয়।
একই ইন্টারফেস উভয় র্যাপার ক্লাস দ্বারা ব্যবহৃত হয় , সুতরাং অ্যাপটি জেলিবিন বা মার্শমেলোতে চালিত হয় কিনা তা বিবেচ্য নয় - যতক্ষণ ইন্টারফেসটি একই অ্যাপ্লিকেশনটির স্বাক্ষর ব্যবহার করে ক্যামেরা এপিআই থেকে যেটির প্রয়োজন তা সরবরাহ করে; অ্যান্ড্রয়েডের নতুন এবং পুরানো সংস্করণ উভয়ের জন্যই ক্যামেরা অ্যাপে একইভাবে চলে।
সিঙ্গেলটন এপিআই-তে বাঁধা না থাকা সম্পর্কিত কিছু কিছু করতে পারে - যেমন ডিভাইসে কোনও ক্যামেরা রয়েছে তা সনাক্ত করা এবং মিডিয়া লাইব্রেরিতে সংরক্ষণ করা।
আমি আশা করি ধারণাটি আপনাকে সাহায্য করবে।
public interface AllCameraInterface { void open(); boolean setDirection(); Bitmap preview(); Bitmap takePhoto(); void close(); }
public interface AllCameraInterface { void open(); Bitmap takePhoto(); void close(); etc... }
public class NCamera implements AllCameraInterface...
public class OCamera implements AllCameraInterface...
public class AllCamera { private static AllCamera ourInstance = new AllCamera(); public static AllCamera getInstance() {...} private AllCameraInterface camera; private AllCamera() { if (android.os.Build.VERSION.SDK_INT <= 20) { camera = new OCamera(); } else { camera = new NCamera(); } }
তারপরে এটি
camera2
? আমি সত্যিই বিভ্রান্ত am ... আমি শুধু প্রয়োজন enableAutofocus
: ক্যামেরা খুলুন এবং তার ফোকাস সেট করতে পদ্ধতি stackoverflow.com/questions/19076316/...
এখন আমাদের android.hardware.camera2 কে android.hardware.Camera হিসাবে অবহিত করা হয়েছে যা কেবলমাত্র API> 23 ফ্ল্যাশলাইটে কাজ করবে
public class MainActivity extends AppCompatActivity {
Button button;
Boolean light=true;
CameraDevice cameraDevice;
private CameraManager cameraManager;
private CameraCharacteristics cameraCharacteristics;
String cameraId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button)findViewById(R.id.button);
cameraManager = (CameraManager)
getSystemService(Context.CAMERA_SERVICE);
try {
cameraId = cameraManager.getCameraIdList()[0];
} catch (CameraAccessException e) {
e.printStackTrace();
}
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(light){
try {
cameraManager.setTorchMode(cameraId,true);
} catch (CameraAccessException e) {
e.printStackTrace();
}
light=false;}
else {
try {
cameraManager.setTorchMode(cameraId,false);
} catch (CameraAccessException e) {
e.printStackTrace();
}
light=true;
}
}
});
}
}
কোন ক্যামেরা এপিআই ব্যবহার করা উচিত তা হিসাবে এখানে প্রদত্ত উত্তরগুলি ভুল। বা আরও ভাল তারা অপর্যাপ্ত বলা হয়।
কিছু ফোন (উদাহরণস্বরূপ স্যামসং গ্যালাক্সি এস 6) এপিআই স্তরের 21 এর উপরে হতে পারে তবে এখনও ক্যামেরা 2 এপিআই সমর্থন করে না।
CameraCharacteristics mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId);
Integer level = mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
if (level == null || level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
return false;
}
ক্যামেরা 2 এপি-তে ক্যামেরাম্যানেজার ক্লাসে ক্যামেরা বৈশিষ্ট্যগুলি পড়ার একটি পদ্ধতি রয়েছে। হার্ডওয়্যার ভিত্তিক ডিভাইস ক্যামেরা 2 এপিআই সমর্থন করছে কিনা তা আপনার পরীক্ষা করা উচিত।
তবে আপনি যদি সত্যিই এটি কোনও গুরুতর অ্যাপ্লিকেশনের জন্য কাজ করতে চান তবে হ্যান্ডেল করার জন্য আরও কিছু সমস্যা রয়েছে: যেমন, অটো-ফ্ল্যাশ বিকল্পটি কিছু ডিভাইসের জন্য কাজ করতে পারে না বা ফোনের ব্যাটারি স্তরের ক্যামেরায় একটি রানটাইম এক্সেকশন তৈরি করতে পারে বা ফোনে কোনও অবৈধ ফেরত আসতে পারে ক্যামেরা আইডি এবং ইত্যাদি
সুতরাং সর্বোত্তম পদ্ধতির ফ্যালব্যাক প্রক্রিয়া হ'ল কোনও কারণে ক্যামেরা 2 আপনি ক্যামেরা 1 চেষ্টা করে দেখতে শুরু করতে ব্যর্থ হন এবং যদি এটির ব্যর্থ হয় তবে আপনি আপনার জন্য ডিফল্ট ক্যামেরা খোলার জন্য অ্যান্ড্রয়েডে কল করতে পারেন।
if ( getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
CameraManager cameraManager=(CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
try {
String cameraId = cameraManager.getCameraIdList()[0];
cameraManager.setTorchMode(cameraId,true);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
android.hardware.camera2