最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android?CameraX?打開攝像頭預(yù)覽功能

 更新時間:2021年12月10日 10:38:18   作者:AnRFDev  
這篇文章主要介紹了Android?CameraX?打開攝像頭預(yù)覽功能,模塊gradle的一些配置,使用的Android?SDK版本為31,啟用了databinding,具體實(shí)例代碼跟隨小編一起看看吧

目標(biāo)很簡單,用CameraX打開攝像頭預(yù)覽,實(shí)時顯示在界面上??纯碈ameraX有沒有Google說的那么好用。先按最簡單的來,把預(yù)覽顯示出來。

引入依賴

模塊gradle的一些配置,使用的Android SDK版本為31,啟用了databinding

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 31
    buildToolsVersion "31.0.0"
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 31
    }
    dataBinding {
        enabled = true
    }
}

引入CameraX依賴(CameraX 核心庫是用camera2實(shí)現(xiàn)的),目前主要用1.1.0-alpha11版本

dependencies {
    implementation "androidx.camera:camera-core:1.1.0-alpha11"
    implementation "androidx.camera:camera-camera2:1.1.0-alpha11"
    implementation "androidx.camera:camera-lifecycle:1.1.0-alpha11"
    implementation "androidx.camera:camera-view:1.0.0-alpha31"
    implementation "androidx.camera:camera-extensions:1.0.0-alpha31"
}

使用1.0.2版本的CameraX核心庫會報錯,找不到getOrCreateInstance方法。

??? bug "NoSuchMethodError getOrCreateInstance"

```log
CrashHandler: In thread: Thread[main,5,main]
    UncaughtException detected: java.lang.NoSuchMethodError: No static method getOrCreateInstance(Landroid/content/Context;)Lcom/google/common/util/concurrent/ListenableFuture; in class Landroidx/camera/core/CameraX; or its super classes (declaration of 'androidx.camera.core.CameraX' appears in /data/app/com.rustfisher.tutorial2020-1/base.apk)
    at androidx.camera.lifecycle.ProcessCameraProvider.getInstance(ProcessCameraProvider.java:149)
    at com.rustfisher.tutorial2020.camera.SimplePreviewXAct.onCreate(SimplePreviewXAct.java:36)
    at android.app.Activity.performCreate(Activity.java:6161)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2507)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2640)
    at android.app.ActivityThread.access$800(ActivityThread.java:182)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1493)
    at android.os.Handler.dispatchMessage(Handler.java:111)
    at android.os.Looper.loop(Looper.java:194)
    at android.app.ActivityThread.main(ActivityThread.java:5682)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:963)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:758)
```

權(quán)限

需要動態(tài)申請android.permission.CAMERA權(quán)限

<uses-permission android:name="android.permission.CAMERA" />

本文略過動態(tài)申請權(quán)限的地方

界面

CameraX為開發(fā)者貼心地準(zhǔn)備了androidx.camera.view.PreviewView

把它放在一個FrameLayout里,如下的act_simple_preivew_x.layout

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.camera.view.PreviewView
            android:id="@+id/previewView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </FrameLayout>
</layout>

開啟預(yù)覽

在activity中開啟相機(jī)預(yù)覽

// SimplePreviewXAct.java
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.LifecycleOwner;

import com.google.common.util.concurrent.ListenableFuture;
// import com.rustfisher.tutorial2020.R;
// import com.rustfisher.tutorial2020.databinding.ActSimplePreivewXBinding;

import java.util.concurrent.ExecutionException;

public class SimplePreviewXAct extends AppCompatActivity {

    private ActSimplePreivewXBinding mBinding;
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.act_simple_preivew_x);
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                bindPreview(cameraProvider);
            } catch (ExecutionException | InterruptedException e) {
                // 這里不用處理
            }
        }, ContextCompat.getMainExecutor(this));
    }

    void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
        Preview preview = new Preview.Builder().build();

        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build();

        preview.setSurfaceProvider(mBinding.previewView.getSurfaceProvider());

        Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);
    }
}

注意我們這里使用的是androidx.appcompat.app.AppCompatActivity

為了獲得ProcessCameraProvider,用ProcessCameraProvider.getInstance方法拿到一個cameraProviderFuture。
cameraProviderFuture完成后取出ProcessCameraProvider(cameraProvider)。

要開啟預(yù)覽,通過Preview.Builder構(gòu)建一個Preview。用CameraSelector來選擇后置攝像頭。
Preview的SurfaceProvider由layout中的androidx.camera.view.PreviewView提供。

cameraProvider.bindToLifecycle綁定上后,啟動攝像頭預(yù)覽

運(yùn)行測試

運(yùn)行到手機(jī)上,打開這個Activity就可以看到攝像頭預(yù)覽。圖像寬高比正常,沒有拉伸現(xiàn)象。

  • 榮耀 EMUI 3.1 Lite,Android 5.1 運(yùn)行正常
  • Redmi 9A,MIUI 12.5.1穩(wěn)定版,Android 10 運(yùn)行正常
  • 一加5,H2OS 10.0.3,Android 10 運(yùn)行正常

增加開關(guān)

在layout里加2個按鈕,控制相機(jī)開關(guān)

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimaryDark"
            android:gravity="center"
            android:orientation="horizontal"
            android:padding="4dp">

            <Button
                android:id="@+id/start"
                style="@style/NormalBtn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="打開" />

            <Button
                android:id="@+id/end"
                style="@style/NormalBtn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="12dp"
                android:text="關(guān)閉" />
        </LinearLayout>

        <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <androidx.camera.view.PreviewView
                android:id="@+id/previewView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </FrameLayout>

    </LinearLayout>
</layout>

根layout換成LinearLayout

修改bindPreview方法,先檢查傳入的ProcessCameraProvider是否為空

private void bindPreview(ProcessCameraProvider cameraProvider) {
    if (cameraProvider == null) {
        Toast.makeText(getApplicationContext(), "沒獲取到相機(jī)", Toast.LENGTH_SHORT).show();
        return;
    }
    Preview preview = new Preview.Builder().build();

    CameraSelector cameraSelector = new CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build();

    preview.setSurfaceProvider(mBinding.previewView.getSurfaceProvider());

    Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);
}

修改后的activity部分代碼

import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;

import com.google.common.util.concurrent.ListenableFuture;
// import com.rustfisher.tutorial2020.R;
// import com.rustfisher.tutorial2020.databinding.ActSimplePreivewXBinding;

import java.util.concurrent.ExecutionException;

public class SimplePreviewXAct extends AppCompatActivity {

    private ActSimplePreivewXBinding mBinding;
    private ListenableFuture<ProcessCameraProvider> mCameraProviderFuture;
    private ProcessCameraProvider mCameraProvider;
    private boolean mRunning = false;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.act_simple_preivew_x);
        mCameraProviderFuture = ProcessCameraProvider.getInstance(this);
        mCameraProviderFuture.addListener(() -> {
            try {
                mCameraProvider = mCameraProviderFuture.get();
            } catch (ExecutionException | InterruptedException e) {
                // 這里不用處理
            }
        }, ContextCompat.getMainExecutor(this));
        mBinding.start.setOnClickListener(v -> {
            if (mCameraProvider != null && !mRunning) {
                bindPreview(mCameraProvider);
            }
        });
        mBinding.end.setOnClickListener(v -> {
            mCameraProvider.unbindAll();
            mRunning = false;
        });
    }

    private void bindPreview(ProcessCameraProvider cameraProvider) {
        if (cameraProvider == null) {
            Toast.makeText(getApplicationContext(), "沒獲取到相機(jī)", Toast.LENGTH_SHORT).show();
            return;
        }
        Preview preview = new Preview.Builder().build();

        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build();

        preview.setSurfaceProvider(mBinding.previewView.getSurfaceProvider());

        Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);
        mRunning = true;
    }
}

拿到mCameraProvider后不要立刻綁定生命周期。

如果要開啟預(yù)覽,則調(diào)用bindPreview(mCameraProvider)。記錄一下現(xiàn)在相機(jī)已經(jīng)開啟預(yù)覽mRunning = true。

如果要停止預(yù)覽,則解綁生命周期mCameraProvider.unbindAll()。這個方法需要在主線程調(diào)用。

運(yùn)行起來后,可以用按鈕來控制相機(jī)預(yù)覽的開關(guān)。相比之前,PreviewView的高度變小了一點(diǎn)(讓了點(diǎn)位置給按鈕)。
但視頻寬高比例正常,沒有被拉伸。默認(rèn)的配置下,還有自動對焦的功能。

小結(jié)

從簡單的打開相機(jī)預(yù)覽來看,CameraX簡化了開發(fā)者的工作。提供了PreviewView,開發(fā)者不需要自定義SurfaceView或者TextureView。實(shí)時預(yù)覽中,相機(jī)能夠自動對焦。本文用的是1.1.0-alpha11,而CameraX還在發(fā)展之中。

參考

camerax實(shí)現(xiàn)預(yù)覽 - developer.android.com

https://developer.android.com/jetpack/androidx/releases/camera

NoSuchMethodError - stackoverflow

原文鏈接CameraX 打開攝像頭預(yù)覽

到此這篇關(guān)于Android CameraX 打開攝像頭預(yù)覽的文章就介紹到這了,更多相關(guān)Android CameraX 攝像頭預(yù)覽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android冷啟動優(yōu)化的3個小案例分享

    Android冷啟動優(yōu)化的3個小案例分享

    為了提高App的冷啟動耗時,除了在常規(guī)的業(yè)務(wù)側(cè)進(jìn)行耗時代碼優(yōu)化之外,為了進(jìn)一步縮短啟動耗時,需要在純技術(shù)測做一些優(yōu)化探索,本期我們從類預(yù)加載、Retrofit 、ARouter方面進(jìn)行了進(jìn)一步的優(yōu)化,感興趣的同學(xué)跟著小編一起來看看吧
    2023-07-07
  • Android編譯的注意事項(xiàng)

    Android編譯的注意事項(xiàng)

    今天小編就為大家分享一篇關(guān)于Android編譯的注意事項(xiàng),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Android 彈出軟鍵盤所遇到的坑及解決方法

    Android 彈出軟鍵盤所遇到的坑及解決方法

    這篇文章主要介紹了Android 彈出軟鍵盤所遇到的坑及解決方法,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2017-01-01
  • Android中dataBinding使用的簡單封裝

    Android中dataBinding使用的簡單封裝

    前面一段時間學(xué)習(xí)了一下Android中的DataBinding,但是只是很簡單地實(shí)現(xiàn)了一下,DataBinding中最強(qiáng)大的地方還沒有認(rèn)真地學(xué)習(xí)過,有很多地方還不理解,下面這篇文章主要給大家介紹了關(guān)于Android中dataBinding使用的簡單封裝,需要的朋友可以參考下
    2023-06-06
  • 淺談Android串口通訊SerialPort原理

    淺談Android串口通訊SerialPort原理

    這篇文章主要介紹了淺談Android串口通訊SerialPort原理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Android 給空白包簽名并上傳審核

    Android 給空白包簽名并上傳審核

    之前公司app在騰訊開放平臺認(rèn)領(lǐng)應(yīng)用時,涉及了一個問題:就是給空白包簽名。然后再上傳上去審核,通過本文給大家介紹android 給空白包簽名并上傳審核,對android空白包簽名相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • 詳解Android:向服務(wù)器提供數(shù)據(jù)之get、post方式

    詳解Android:向服務(wù)器提供數(shù)據(jù)之get、post方式

    本篇文章主要介紹了詳解Android:向服務(wù)器提供數(shù)據(jù)之get、post方式,具有一定的參考價值,有興趣的可以了解一下。
    2017-03-03
  • Android?Java?try?catch?失效問題及解決

    Android?Java?try?catch?失效問題及解決

    這篇文章主要介紹了Android?Java?try?catch?失效問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 簡單實(shí)現(xiàn)Android應(yīng)用的啟動頁

    簡單實(shí)現(xiàn)Android應(yīng)用的啟動頁

    這篇文章主要介紹了簡單實(shí)現(xiàn)Android應(yīng)用的啟動頁,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Android開發(fā)實(shí)現(xiàn)圖片的上傳下載

    Android開發(fā)實(shí)現(xiàn)圖片的上傳下載

    這篇文章主要為大家詳細(xì)介紹了Android開發(fā)實(shí)現(xiàn)圖片的上傳下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09

最新評論

永胜县| 九寨沟县| 平陆县| 永州市| 英吉沙县| 涿州市| 广东省| 陵水| 阿尔山市| 丁青县| 上栗县| 沂水县| 海林市| 唐山市| 乐都县| 中江县| 兴宁市| 万宁市| 阳朔县| 曲沃县| 通州市| 阿拉尔市| 淳化县| 新和县| 大安市| 乌恰县| 邳州市| 大邑县| 金华市| 兴宁市| 宿州市| 黎平县| 常德市| 吉首市| 和硕县| 宁蒗| 青浦区| 突泉县| 湖口县| 莱阳市| 鄂伦春自治旗|