অ্যান্ড্রয়েড ক্যামেরা অ্যান্ড্রয়েড.হার্ডওয়্যার.ক্যামেরা হ্রাস পেয়েছে


97

যদি android.hardware.Cameraঅবচয় হয় এবং আপনি যদি ভেরিয়েবল ব্যবহার করতে না পারেন তবে Cameraএর বিকল্প কী হবে?



4
আমি একটি অ্যাপ্লিকেশন নিয়ে এই সমস্যা ছিল এবং এটি খুব সহায়ক বলে মনে হয়েছে। আপনি যদি অভিপ্রায় ব্যবহার করেন তবে আপনি সীমাবদ্ধ। সুতরাং এই টিউটোরিয়ালটি একটি বিকল্প ব্যাখ্যা করে: developer.android.com/guide/topics/media/…
রোনালদো বাহিয়া

উত্তর:


103

এপিআই ডকুমেন্টেশন

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

আপনি ডিআই ব্যবহার না করলে আপনি কেবল একটি ইউটিলিটি তৈরি করতে পারেন বা যথাযথটি তৈরি করতে কারখানার প্যাটার্ন ব্যবহার করতে পারেন। গুরুত্বপূর্ণ অংশটি হ'ল এপিআই স্তরটি চেক করা হয়।


25
আমার যদি 21 এর চেয়ে কম অ্যান্ড্রয়েড এপিআই লেভেল সমর্থন করা দরকার?
নিভিউসেভার্টো

4
@ অ্যাঞ্জেলিয়াস সম্ভবত এই ডকুমেন্টেশনটি ডেভেলপার.অ্যান্ড্রয়েড. com/guide/topics/media/camera.html সহায়ক হতে পারে - তবে এটি একটি পৃথক প্রশ্ন হতে পারে, বা অবচয়যুক্ত ভেরিয়েবল ব্যবহার সম্পর্কে প্রশ্নগুলির সন্ধান করতে পারে।

@Angelius এখানে সম্বন্ধে কিছু তথ্য আছে @SuppressWarningsএই QA তে মধ্যে stackoverflow.com/questions/7397996/...

4
আমি কেবল @ ডিপ্রেসিটেড ক্লাসগুলি ব্যবহার না করার কথা ভাবছি, তবে পশ্চাদপদ সামঞ্জস্যের সাথে অ্যাপটি কীভাবে তৈরি করব? এই বিষয়ে কোন অফিসিয়াল সহায়তা? আমার এই সম্পর্কে ধারণা আছে: আইসেমেরা ইন্টারফেস, যা বর্তমান ফোনের সংস্করণ অনুসারে ক্যামেরায় অবজেক্টের সাথে সমর্থনযুক্ত, তবে এটি কিছুটা সোজা এগিয়ে এবং বজায় রাখা শক্ত ...
নিভিউসেভারটো

@ অ্যাঞ্জেলিয়াস আপনি যা বর্ণনা করছেন তা আলাদা প্রশ্ন হতে পারে (এটি আগে জিজ্ঞাসা করা হয়েছে কিনা তা পরীক্ষা করে দেখুন)।

5

অবহেলিত ক্যামেরা 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(); } }তারপরে এটি
রবার্ট শেরম্যান

স্পষ্টত মন্তব্যগুলিতে কোনও লাইন বিরতি দেওয়া হয়নি ;-) তবে এটি সত্যিই কার্যকর।
রবার্ট শেরম্যান

4
মন্তব্যে কোডগুলি সরাসরি উত্তরে কেন যুক্ত করবেন না?
অ্যাঞ্জেল কোহ

@ রবার্টশেরমান হাই রবার্ট, আপনি কি দয়া করে নতুনটির জন্য এই ছোট্ট স্নিপেটটি আবার লিখতে আমাকে সহায়তা করতে পারেন camera2? আমি সত্যিই বিভ্রান্ত am ... আমি শুধু প্রয়োজন enableAutofocus: ক্যামেরা খুলুন এবং তার ফোকাস সেট করতে পদ্ধতি stackoverflow.com/questions/19076316/...

0

এখন আমাদের 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;
                    }


            }
        });
    }
}

0

কোন ক্যামেরা এপিআই ব্যবহার করা উচিত তা হিসাবে এখানে প্রদত্ত উত্তরগুলি ভুল। বা আরও ভাল তারা অপর্যাপ্ত বলা হয়।

কিছু ফোন (উদাহরণস্বরূপ স্যামসং গ্যালাক্সি এস 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 চেষ্টা করে দেখতে শুরু করতে ব্যর্থ হন এবং যদি এটির ব্যর্থ হয় তবে আপনি আপনার জন্য ডিফল্ট ক্যামেরা খোলার জন্য অ্যান্ড্রয়েডে কল করতে পারেন।


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


 }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.