kopia lustrzana https://github.com/ryukoposting/Signal-Android
Fix QR processing resolution and allow front camera use for device linking.
rodzic
9e4449924d
commit
c9cb8c3cd7
|
@ -10,6 +10,8 @@ import android.os.Bundle;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.transition.TransitionInflater;
|
import android.transition.TransitionInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
@ -54,6 +56,7 @@ public class DeviceActivity extends PassphraseRequiredActivity
|
||||||
private DeviceAddFragment deviceAddFragment;
|
private DeviceAddFragment deviceAddFragment;
|
||||||
private DeviceListFragment deviceListFragment;
|
private DeviceListFragment deviceListFragment;
|
||||||
private DeviceLinkFragment deviceLinkFragment;
|
private DeviceLinkFragment deviceLinkFragment;
|
||||||
|
private MenuItem cameraSwitchItem = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPreCreate() {
|
public void onPreCreate() {
|
||||||
|
@ -102,6 +105,18 @@ public class DeviceActivity extends PassphraseRequiredActivity
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.device_add, menu);
|
||||||
|
cameraSwitchItem = menu.findItem(R.id.device_add_camera_switch);
|
||||||
|
cameraSwitchItem.setVisible(false);
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MenuItem getCameraSwitchItem() {
|
||||||
|
return cameraSwitchItem;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Permissions.with(this)
|
Permissions.with(this)
|
||||||
|
|
|
@ -2,24 +2,23 @@ package org.thoughtcrime.securesms;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewAnimationUtils;
|
import android.view.ViewAnimationUtils;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
|
|
||||||
import org.signal.qr.QrScannerView;
|
import org.signal.qr.QrScannerView;
|
||||||
import org.signal.qr.kitkat.ScanListener;
|
import org.signal.qr.kitkat.ScanListener;
|
||||||
import org.thoughtcrime.securesms.mediasend.camerax.CameraXModelBlocklist;
|
import org.thoughtcrime.securesms.mediasend.camerax.CameraXModelBlocklist;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
|
||||||
import org.thoughtcrime.securesms.util.LifecycleDisposable;
|
import org.thoughtcrime.securesms.util.LifecycleDisposable;
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
|
@ -32,12 +31,13 @@ public class DeviceAddFragment extends LoggingFragment {
|
||||||
|
|
||||||
private ImageView devicesImage;
|
private ImageView devicesImage;
|
||||||
private ScanListener scanListener;
|
private ScanListener scanListener;
|
||||||
|
private QrScannerView scannerView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle) {
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle) {
|
||||||
ViewGroup container = ViewUtil.inflate(inflater, viewGroup, R.layout.device_add_fragment);
|
ViewGroup container = ViewUtil.inflate(inflater, viewGroup, R.layout.device_add_fragment);
|
||||||
|
|
||||||
QrScannerView scannerView = container.findViewById(R.id.scanner);
|
this.scannerView = container.findViewById(R.id.scanner);
|
||||||
this.devicesImage = container.findViewById(R.id.devices);
|
this.devicesImage = container.findViewById(R.id.devices);
|
||||||
ViewCompat.setTransitionName(devicesImage, "devices");
|
ViewCompat.setTransitionName(devicesImage, "devices");
|
||||||
|
|
||||||
|
@ -77,6 +77,19 @@ public class DeviceAddFragment extends LoggingFragment {
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
MenuItem switchCamera = ((DeviceActivity) requireActivity()).getCameraSwitchItem();
|
||||||
|
|
||||||
|
if (switchCamera != null) {
|
||||||
|
switchCamera.setVisible(true);
|
||||||
|
switchCamera.setOnMenuItemClickListener(v -> {
|
||||||
|
scannerView.toggleCamera();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ImageView getDevicesImage() {
|
public ImageView getDevicesImage() {
|
||||||
return devicesImage;
|
return devicesImage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<item android:id="@+id/device_add_camera_switch"
|
||||||
|
android:icon="@drawable/ic_switch_camera_24"
|
||||||
|
android:title="@string/CameraXFragment_change_camera_description"
|
||||||
|
app:iconTint="@color/signal_icon_tint_primary"
|
||||||
|
app:showAsAction="always"/>
|
||||||
|
</menu>
|
|
@ -4,6 +4,8 @@ import android.annotation.SuppressLint
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.EditText
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
@ -12,16 +14,63 @@ import com.google.zxing.PlanarYUVLuminanceSource
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||||
import org.signal.core.util.ThreadUtil
|
import org.signal.core.util.ThreadUtil
|
||||||
|
import org.signal.core.util.logging.AndroidLogger
|
||||||
|
import org.signal.core.util.logging.Log
|
||||||
import org.signal.qr.ImageProxyLuminanceSource
|
import org.signal.qr.ImageProxyLuminanceSource
|
||||||
import org.signal.qr.QrProcessor
|
import org.signal.qr.QrProcessor
|
||||||
import org.signal.qr.QrScannerView
|
import org.signal.qr.QrScannerView
|
||||||
|
|
||||||
class QrMainActivity : AppCompatActivity() {
|
class QrMainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
|
||||||
|
private lateinit var text: EditText
|
||||||
|
|
||||||
@SuppressLint("NewApi", "SetTextI18n")
|
@SuppressLint("NewApi", "SetTextI18n")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
Log.initialize(AndroidLogger(), object : Log.Logger() {
|
||||||
|
override fun v(tag: String, message: String?, t: Throwable?, keepLonger: Boolean) {
|
||||||
|
printlnFormatted('v', tag, message, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun d(tag: String, message: String?, t: Throwable?, keepLonger: Boolean) {
|
||||||
|
printlnFormatted('d', tag, message, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun i(tag: String, message: String?, t: Throwable?, keepLonger: Boolean) {
|
||||||
|
printlnFormatted('i', tag, message, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun w(tag: String, message: String?, t: Throwable?, keepLonger: Boolean) {
|
||||||
|
printlnFormatted('w', tag, message, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun e(tag: String, message: String?, t: Throwable?, keepLonger: Boolean) {
|
||||||
|
printlnFormatted('e', tag, message, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun flush() {}
|
||||||
|
|
||||||
|
private fun printlnFormatted(level: Char, tag: String, message: String?, t: Throwable?) {
|
||||||
|
ThreadUtil.runOnMain {
|
||||||
|
val allText = text.text.toString() + "\n" + format(level, tag, message, t)
|
||||||
|
text.setText(allText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun format(level: Char, tag: String, message: String?, t: Throwable?): String {
|
||||||
|
return if (t != null) {
|
||||||
|
String.format("%c[%s] %s %s:%s", level, tag, message, t.javaClass.simpleName, t.message)
|
||||||
|
} else {
|
||||||
|
String.format("%c[%s] %s", level, tag, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
|
text = findViewById(R.id.log)
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
requestPermissions(arrayOf(android.Manifest.permission.CAMERA), 1)
|
requestPermissions(arrayOf(android.Manifest.permission.CAMERA), 1)
|
||||||
}
|
}
|
||||||
|
@ -56,5 +105,9 @@ class QrMainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findViewById<View>(R.id.camera_switch).setOnClickListener {
|
||||||
|
scanner.toggleCamera()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,57 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<Button
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/camera_switch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:text="Change Camera" />
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_qr_data"
|
android:id="@+id/text_qr_data"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_size"
|
android:id="@+id/text_size"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/teal_200">
|
||||||
|
|
||||||
<org.signal.qr.QrScannerView
|
<org.signal.qr.QrScannerView
|
||||||
android:id="@+id/scanner"
|
android:id="@+id/scanner"
|
||||||
android:layout_width="240dp"
|
android:layout_width="240dp"
|
||||||
android:layout_height="240dp" />
|
android:layout_height="240dp" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/teal_700">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/scanner_source"
|
android:id="@+id/scanner_source"
|
||||||
android:layout_width="240dp"
|
android:layout_width="240dp"
|
||||||
android:layout_height="240dp" />
|
android:layout_height="240dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:rotation="90"
|
||||||
|
tools:src="@tools:sample/backgrounds/scenic" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
<androidx.appcompat.widget.AppCompatEditText
|
||||||
|
android:id="@+id/log"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="100dp" />
|
||||||
|
|
||||||
</FrameLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -67,7 +67,7 @@ class QrProcessor {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = Log.tag(QrProcessor::class.java)
|
private val TAG = Log.tag(QrProcessor::class.java)
|
||||||
|
/** For debugging only */
|
||||||
var listener: ((LuminanceSource) -> Unit)? = null
|
var listener: ((LuminanceSource) -> Unit)? = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,11 @@ class QrScannerView @JvmOverloads constructor(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toggleCamera() {
|
||||||
|
Log.d(TAG, "Toggling camera")
|
||||||
|
scannerView?.toggleCamera()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = Log.tag(QrScannerView::class.java)
|
private val TAG = Log.tag(QrScannerView::class.java)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,5 @@ import androidx.lifecycle.LifecycleOwner
|
||||||
*/
|
*/
|
||||||
interface ScannerView {
|
interface ScannerView {
|
||||||
fun start(lifecycleOwner: LifecycleOwner)
|
fun start(lifecycleOwner: LifecycleOwner)
|
||||||
|
fun toggleCamera()
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,27 @@ internal class ScannerView19 constructor(
|
||||||
private val scanListener: ScanListener
|
private val scanListener: ScanListener
|
||||||
) : FrameLayout(context), ScannerView {
|
) : FrameLayout(context), ScannerView {
|
||||||
|
|
||||||
|
private var lifecycleOwner: LifecycleOwner? = null
|
||||||
private var scanningThread: ScanningThread? = null
|
private var scanningThread: ScanningThread? = null
|
||||||
private val cameraView: QrCameraView
|
private lateinit var cameraView: QrCameraView
|
||||||
|
|
||||||
|
private val lifecycleObserver = object : DefaultLifecycleObserver {
|
||||||
|
override fun onResume(owner: LifecycleOwner) {
|
||||||
|
val scanningThread = ScanningThread()
|
||||||
|
scanningThread.setScanListener(scanListener)
|
||||||
|
cameraView.onResume()
|
||||||
|
cameraView.setPreviewCallback(scanningThread)
|
||||||
|
scanningThread.start()
|
||||||
|
|
||||||
|
this@ScannerView19.scanningThread = scanningThread
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause(owner: LifecycleOwner) {
|
||||||
|
cameraView.onPause()
|
||||||
|
scanningThread?.stopScanning()
|
||||||
|
scanningThread = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
cameraView = QrCameraView(context)
|
cameraView = QrCameraView(context)
|
||||||
|
@ -28,22 +47,16 @@ internal class ScannerView19 constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun start(lifecycleOwner: LifecycleOwner) {
|
override fun start(lifecycleOwner: LifecycleOwner) {
|
||||||
lifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
|
this.lifecycleOwner?.lifecycle?.removeObserver(lifecycleObserver)
|
||||||
override fun onResume(owner: LifecycleOwner) {
|
this.lifecycleOwner = lifecycleOwner
|
||||||
val scanningThread = ScanningThread()
|
lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
|
||||||
scanningThread.setScanListener(scanListener)
|
}
|
||||||
cameraView.onResume()
|
|
||||||
cameraView.setPreviewCallback(scanningThread)
|
|
||||||
scanningThread.start()
|
|
||||||
|
|
||||||
this@ScannerView19.scanningThread = scanningThread
|
override fun toggleCamera() {
|
||||||
}
|
cameraView.toggleCamera()
|
||||||
|
lifecycleOwner?.let {
|
||||||
override fun onPause(owner: LifecycleOwner) {
|
lifecycleObserver.onPause(it)
|
||||||
cameraView.onPause()
|
lifecycleObserver.onResume(it)
|
||||||
scanningThread?.stopScanning()
|
}
|
||||||
scanningThread = null
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ package org.signal.qr
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.util.Size
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.camera.core.AspectRatio
|
|
||||||
import androidx.camera.core.Camera
|
import androidx.camera.core.Camera
|
||||||
import androidx.camera.core.CameraSelector
|
import androidx.camera.core.CameraSelector
|
||||||
import androidx.camera.core.ImageAnalysis
|
import androidx.camera.core.ImageAnalysis
|
||||||
|
@ -28,19 +28,42 @@ internal class ScannerView21 constructor(
|
||||||
private val listener: ScanListener
|
private val listener: ScanListener
|
||||||
) : FrameLayout(context), ScannerView {
|
) : FrameLayout(context), ScannerView {
|
||||||
|
|
||||||
|
private var lifecyleOwner: LifecycleOwner? = null
|
||||||
private val analyzerExecutor = Executors.newSingleThreadExecutor()
|
private val analyzerExecutor = Executors.newSingleThreadExecutor()
|
||||||
private var cameraProvider: ProcessCameraProvider? = null
|
private var cameraProvider: ProcessCameraProvider? = null
|
||||||
|
private var cameraSelector: CameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
|
||||||
private var camera: Camera? = null
|
private var camera: Camera? = null
|
||||||
private var previewView: PreviewView
|
private var previewView: PreviewView
|
||||||
private val qrProcessor = QrProcessor()
|
private val qrProcessor = QrProcessor()
|
||||||
|
|
||||||
|
private val lifecycleObserver: DefaultLifecycleObserver = object : DefaultLifecycleObserver {
|
||||||
|
override fun onDestroy(owner: LifecycleOwner) {
|
||||||
|
cameraProvider = null
|
||||||
|
camera = null
|
||||||
|
analyzerExecutor.shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
previewView = PreviewView(context)
|
previewView = PreviewView(context)
|
||||||
previewView.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
previewView.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
||||||
addView(previewView)
|
addView(previewView)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toggleCamera() {
|
||||||
|
cameraSelector = if (cameraSelector == CameraSelector.DEFAULT_BACK_CAMERA) {
|
||||||
|
CameraSelector.DEFAULT_FRONT_CAMERA
|
||||||
|
} else {
|
||||||
|
CameraSelector.DEFAULT_BACK_CAMERA
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecyleOwner?.let { start(it) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun start(lifecycleOwner: LifecycleOwner) {
|
override fun start(lifecycleOwner: LifecycleOwner) {
|
||||||
|
this.lifecyleOwner?.lifecycle?.removeObserver(lifecycleObserver)
|
||||||
|
this.lifecyleOwner = lifecycleOwner
|
||||||
|
|
||||||
previewView.post {
|
previewView.post {
|
||||||
Log.i(TAG, "Starting")
|
Log.i(TAG, "Starting")
|
||||||
ProcessCameraProvider.getInstance(context).apply {
|
ProcessCameraProvider.getInstance(context).apply {
|
||||||
|
@ -54,13 +77,7 @@ internal class ScannerView21 constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
|
lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
|
||||||
override fun onDestroy(owner: LifecycleOwner) {
|
|
||||||
cameraProvider = null
|
|
||||||
camera = null
|
|
||||||
analyzerExecutor.shutdown()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onCameraProvider(lifecycle: LifecycleOwner, cameraProvider: ProcessCameraProvider?) {
|
private fun onCameraProvider(lifecycle: LifecycleOwner, cameraProvider: ProcessCameraProvider?) {
|
||||||
|
@ -71,10 +88,14 @@ internal class ScannerView21 constructor(
|
||||||
|
|
||||||
Log.i(TAG, "Initializing use cases")
|
Log.i(TAG, "Initializing use cases")
|
||||||
|
|
||||||
val preview = Preview.Builder().build()
|
val resolution = Size(480, 640)
|
||||||
|
|
||||||
|
val preview = Preview.Builder()
|
||||||
|
.setTargetResolution(resolution)
|
||||||
|
.build()
|
||||||
|
|
||||||
val imageAnalysis = ImageAnalysis.Builder()
|
val imageAnalysis = ImageAnalysis.Builder()
|
||||||
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
|
.setTargetResolution(resolution)
|
||||||
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
|
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
@ -88,10 +109,13 @@ internal class ScannerView21 constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
cameraProvider.unbindAll()
|
cameraProvider.unbindAll()
|
||||||
camera = cameraProvider.bindToLifecycle(lifecycle, CameraSelector.DEFAULT_BACK_CAMERA, preview, imageAnalysis)
|
camera = cameraProvider.bindToLifecycle(lifecycle, cameraSelector, preview, imageAnalysis)
|
||||||
|
|
||||||
preview.setSurfaceProvider(previewView.surfaceProvider)
|
preview.setSurfaceProvider(previewView.surfaceProvider)
|
||||||
|
|
||||||
|
Log.d(TAG, "Preview: ${preview.resolutionInfo}")
|
||||||
|
Log.d(TAG, "Analysis: ${imageAnalysis.resolutionInfo}")
|
||||||
|
|
||||||
this.cameraProvider = cameraProvider
|
this.cameraProvider = cameraProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class QrCameraView extends ViewGroup {
|
||||||
private final OnOrientationChange onOrientationChange;
|
private final OnOrientationChange onOrientationChange;
|
||||||
|
|
||||||
private volatile Optional<Camera> camera = Optional.empty();
|
private volatile Optional<Camera> camera = Optional.empty();
|
||||||
private final int cameraId = CameraInfo.CAMERA_FACING_BACK;
|
private volatile int cameraId = CameraInfo.CAMERA_FACING_BACK;
|
||||||
private volatile int displayOrientation = -1;
|
private volatile int displayOrientation = -1;
|
||||||
|
|
||||||
private @NonNull State state = State.PAUSED;
|
private @NonNull State state = State.PAUSED;
|
||||||
|
@ -161,6 +161,14 @@ public class QrCameraView extends ViewGroup {
|
||||||
return state != State.PAUSED;
|
return state != State.PAUSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void toggleCamera() {
|
||||||
|
if (cameraId == CameraInfo.CAMERA_FACING_BACK) {
|
||||||
|
cameraId = CameraInfo.CAMERA_FACING_FRONT;
|
||||||
|
} else {
|
||||||
|
cameraId = CameraInfo.CAMERA_FACING_BACK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("SuspiciousNameCombination")
|
@SuppressWarnings("SuspiciousNameCombination")
|
||||||
@Override
|
@Override
|
||||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||||
|
|
Ładowanie…
Reference in New Issue