Compare commits

...
13 Commits
Author SHA1 Message Date
Markus Fisch ee0f7c4529 Advance version number to 1.3.2 2017-12-08 22:28:41 +01:00
Markus Fisch 1b296ff83e Update to latest CameraView 2017-12-08 22:26:26 +01:00
Markus Fisch 1a635af7b7 Update to gradle 4 2017-12-08 22:07:05 +01:00
Markus Fisch 568530d470 Use safe calls instead of explicit null checks
Do it the Kotlin way.
2017-12-07 22:01:24 +01:00
Markus Fisch 6248b46fc8 Advance version number to 1.3.1 2017-11-13 21:10:10 +01:00
Markus Fisch 3083d2b625 Change primary colors
Was rejected because the launcher icon was too close to
another app with almost the same primary colors.
2017-11-13 21:03:37 +01:00
Markus Fisch e02420d446 Advance version number to 1.3.0 2017-11-12 21:43:55 +01:00
Markus Fisch e63fe0d601 Save chosen zoom level permanently 2017-11-12 21:42:54 +01:00
Markus Fisch 0803fdcac8 Check Intent.getStringExtra() for null before use 2017-11-12 21:36:05 +01:00
Markus Fisch e64dd2e972 Update to latest Kotlin version 2017-11-12 21:20:38 +01:00
Markus Fisch 418edd34a5 Support tap to focus
Focus that exact spot a user taps on. Helps getting a clear
image on some devices. After 3 seconds the app will return
to the best possible auto focus.
2017-11-12 21:14:51 +01:00
Markus Fisch af2a1dc940 Update CameraView library to latest version 2017-11-12 21:14:27 +01:00
Markus Fisch e0c420c29f Update ZXing to latest version 3.3.2 2017-11-11 14:11:50 +01:00
29 changed files with 146 additions and 35 deletions
+2 -2
View File
@@ -2,8 +2,8 @@ language: android
android:
components:
- platform-tools
- build-tools-26.0.0
- android-26
- build-tools-26.0.2
- android-27
- extra-android-m2repository
addons:
sonarcloud:
+11
View File
@@ -1,5 +1,16 @@
# Change Log
## 1.3.2
* Fixed crash when going back very fast
## 1.3.1
* Changed primary color
## 1.3.0
* Support tap to focus
* Save chose zoom level permanently
* Update ZXing to latest version (3.3.2)
## 1.2.0
* Added a camera zoom slider
* Added an unobtrusive wallpaper background
+1 -1
View File
@@ -1,5 +1,5 @@
PACKAGE = de.markusfisch.android.binaryeye
APK = app/build/outputs/apk/app-debug.apk
APK = app/build/outputs/apk/debug/app-debug.apk
all: debug install start
+2 -2
View File
@@ -14,8 +14,8 @@ android {
minSdkVersion 9
targetSdkVersion sdk_version
versionCode 5
versionName '1.2.0'
versionCode 8
versionName '1.3.2'
renderscriptTargetApi 24
renderscriptSupportModeEnabled true
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

+1
View File
@@ -17,6 +17,7 @@
tools:ignore="UnusedAttribute"
android:allowBackup="true"
android:fullBackupContent="true"
android:supportsRtl="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:theme="@style/AppTheme">
@@ -12,16 +12,19 @@ import de.markusfisch.android.binaryeye.R
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.SharedPreferences
import android.hardware.Camera
import android.net.Uri
import android.os.Bundle
import android.os.Vibrator
import android.preference.PreferenceManager
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.view.Menu
import android.view.MenuItem
import android.view.MotionEvent
import android.view.View
import android.widget.SeekBar
import android.widget.Toast
@@ -45,6 +48,7 @@ class CameraActivity : AppCompatActivity() {
}
}
private lateinit var preferences: SharedPreferences
private lateinit var vibrator: Vibrator
private lateinit var cameraView: CameraView
private lateinit var zoomBar: SeekBar
@@ -80,20 +84,24 @@ class CameraActivity : AppCompatActivity() {
initSystemBars(this)
setSupportActionBar(findViewById(R.id.toolbar) as Toolbar)
yuvToGray = YuvToGray(this)
preferences = PreferenceManager.getDefaultSharedPreferences(this)
vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
yuvToGray = YuvToGray(this)
cameraView = findViewById(R.id.camera_view) as CameraView
zoomBar = findViewById(R.id.zoom) as SeekBar
initCameraView()
setTapToFocus()
initZoomBar()
restoreZoom()
initFlashFab(findViewById(R.id.flash))
}
override fun onDestroy() {
super.onDestroy()
yuvToGray.destroy()
saveZoom()
}
override fun onNewIntent(intent: Intent) {
@@ -106,7 +114,7 @@ class CameraActivity : AppCompatActivity() {
System.gc()
if (hasCameraPermission()) {
cameraView.openAsync(CameraView.findCameraId(
Camera.CameraInfo.CAMERA_FACING_BACK))
Camera.CameraInfo.CAMERA_FACING_BACK))
startDecoding()
}
}
@@ -118,6 +126,7 @@ class CameraActivity : AppCompatActivity() {
}
override fun onRestoreInstanceState(savedState: Bundle) {
super.onRestoreInstanceState(savedState)
zoomBar.max = savedState.getInt(ZOOM_MAX)
zoomBar.progress = savedState.getInt(ZOOM_LEVEL)
}
@@ -159,7 +168,7 @@ class CameraActivity : AppCompatActivity() {
}
var text = intent.getStringExtra(Intent.EXTRA_TEXT)
if (text.isEmpty()) {
if (text == null || text.isEmpty()) {
return
}
@@ -191,6 +200,7 @@ class CameraActivity : AppCompatActivity() {
if (zoomBar.max != max) {
zoomBar.max = max
zoomBar.progress = max / 3
saveZoom()
}
parameters.setZoom(zoomBar.progress)
} else {
@@ -224,6 +234,24 @@ class CameraActivity : AppCompatActivity() {
})
}
private fun setTapToFocus() {
val runnable = Runnable {
cameraView.setFocusArea(null)
}
cameraView.setOnTouchListener({ v: View, event: MotionEvent ->
val camera = cameraView.getCamera()
camera?.cancelAutoFocus()
cameraView.setFocusArea(cameraView.calculateFocusRect(
event.getX(), event.getY(), 100))
camera?.autoFocus({ _: Boolean, _: Camera ->
cameraView.removeCallbacks(runnable)
cameraView.postDelayed(runnable, 3000)
})
v.performClick()
true
})
}
private fun initZoomBar() {
zoomBar.setOnSeekBarChangeListener(object :
SeekBar.OnSeekBarChangeListener {
@@ -251,6 +279,18 @@ class CameraActivity : AppCompatActivity() {
}
}
private fun saveZoom() {
val editor = preferences.edit()
editor.putInt(ZOOM_MAX, zoomBar.max)
editor.putInt(ZOOM_LEVEL, zoomBar.progress)
editor.apply()
}
private fun restoreZoom() {
zoomBar.max = preferences.getInt(ZOOM_MAX, zoomBar.max)
zoomBar.progress = preferences.getInt(ZOOM_LEVEL, zoomBar.progress)
}
private fun initFlashFab(fab: View) {
if (!packageManager.hasSystemFeature(
PackageManager.FEATURE_CAMERA_FLASH)) {
@@ -21,7 +21,7 @@ class MainActivity : AppCompatActivity() {
private val DECODE = "decode"
private val DECODE_FORMAT = "decode_format"
fun getEncodeIntent(context: Context, text: String = ""): Intent {
fun getEncodeIntent(context: Context, text: String? = ""): Intent {
val intent = Intent(context, MainActivity::class.java)
intent.putExtra(ENCODE, text)
return intent
@@ -55,12 +55,11 @@ class MainActivity : AppCompatActivity() {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
if (state == null) {
val intent = getIntent()
var fragment: Fragment
if (intent != null && intent.hasExtra(ENCODE)) {
if (intent?.hasExtra(ENCODE) == true) {
fragment = EncodeFragment.newInstance(
intent.getStringExtra(ENCODE))
} else if (intent != null && intent.hasExtra(DECODE)) {
} else if (intent?.hasExtra(DECODE) == true) {
fragment = DecodeFragment.newInstance(
intent.getStringExtra(DECODE),
intent.getSerializableExtra(
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

+2 -2
View File
@@ -3,8 +3,8 @@
<color name="primary_translucent">#8222</color>
<color name="primary_dark">#111</color>
<color name="primary_dark_translucent">#8111</color>
<color name="accent">#26e1cf</color>
<color name="accent_dark">#16d1bf</color>
<color name="accent">#b6d46f</color>
<color name="accent_dark">#a6c45f</color>
<color name="background_color">#111</color>
<color name="button_text">#fff</color>
</resources>
+8 -6
View File
@@ -1,12 +1,13 @@
buildscript {
ext.kotlin_version = '1.1.4-2'
ext.tools_version = '2.3.3'
ext.build_tools_version = '26.0.0'
ext.sdk_version = 26
ext.kotlin_version = '1.1.51'
ext.tools_version = '3.0.0'
ext.build_tools_version = '26.0.2'
ext.sdk_version = 27
ext.support_version = '25.3.1'
repositories {
jcenter()
google()
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
@@ -15,18 +16,19 @@ buildscript {
dependencies {
classpath "com.android.tools.build:gradle:$tools_version"
classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.8'
classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.10'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id 'org.sonarqube' version '2.5'
id 'org.sonarqube' version '2.6'
}
allprojects {
repositories {
jcenter()
google()
}
gradle.projectsEvaluated {
+3 -2
View File
@@ -1,6 +1,7 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
@@ -18,8 +19,8 @@ android {
minSdkVersion 9
targetSdkVersion sdk_version
versionCode 4
versionName '1.2.1'
versionCode 5
versionName '1.3.0'
}
}
@@ -15,6 +15,7 @@ import android.view.WindowManager;
import android.widget.FrameLayout;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class CameraView extends FrameLayout {
@@ -27,6 +28,7 @@ public class CameraView extends FrameLayout {
public final Rect previewRect = new Rect();
private boolean isOpen = false;
private Camera camera;
private int viewWidth;
private int viewHeight;
@@ -112,6 +114,7 @@ public class CameraView extends FrameLayout {
}
public void openAsync(final int cameraId) {
isOpen = true;
new AsyncTask<Void, Void, Camera>() {
@Override
protected Camera doInBackground(Void... nothings) {
@@ -129,8 +132,21 @@ public class CameraView extends FrameLayout {
@Override
protected void onPostExecute(Camera camera) {
if (!isOpen) {
// close() was called while Camera.open() was
// running on another thread
if (camera != null) {
// close the open camera that noone is
// interested in anymore
CameraView.this.camera = camera;
close();
}
return;
}
if (camera == null) {
if (onCameraListener != null &&
// run onCameraError() only if there
// isn't an open camera yet
CameraView.this.camera == null) {
onCameraListener.onCameraError();
}
@@ -151,6 +167,7 @@ public class CameraView extends FrameLayout {
}
public void close() {
isOpen = false;
if (camera != null) {
if (onCameraListener != null) {
onCameraListener.onCameraStopping(camera);
@@ -183,6 +200,43 @@ public class CameraView extends FrameLayout {
return frameOrientation;
}
public Rect calculateFocusRect(float x, float y, int radius) {
int cx = Math.round(2000f / viewWidth * x - 1000f);
int cy = Math.round(2000f / viewHeight * y - 1000f);
return new Rect(
Math.max(-1000, cx - radius),
Math.max(-1000, cy - radius),
Math.min(1000, cx + radius),
Math.min(1000, cy + radius));
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public boolean setFocusArea(Rect area) {
if (camera == null || Build.VERSION.SDK_INT <
Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return false;
}
try {
Camera.Parameters parameters = camera.getParameters();
if (parameters.getMaxNumFocusAreas() > 0) {
if (area != null) {
List<Camera.Area> focusAreas =
new ArrayList<Camera.Area>();
focusAreas.add(new Camera.Area(area, 1000));
parameters.setFocusAreas(focusAreas);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
} else {
parameters.setFocusAreas(null);
CameraView.setAutoFocus(parameters);
}
}
camera.setParameters(parameters);
return true;
} catch (RuntimeException e) {
return false;
}
}
@Override
protected void onLayout(
boolean changed,
@@ -316,6 +370,9 @@ public class CameraView extends FrameLayout {
int format,
int width,
int height) {
if (camera == null) {
return;
}
try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
+4 -4
View File
@@ -26,7 +26,7 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.7708333"
inkscape:zoom="0.74025241"
inkscape:cx="96"
inkscape:cy="96"
inkscape:document-units="px"
@@ -35,7 +35,7 @@
units="px"
inkscape:showpageshadow="false"
inkscape:window-width="1680"
inkscape:window-height="925"
inkscape:window-height="1005"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1"
@@ -64,9 +64,9 @@
cy="958.36218"
cx="96"
id="circle5439"
style="fill:#26af9d;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
style="fill:#a6c45f;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
style="fill:#26e1cf;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:#b6d46f;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path5437"
cx="96"
cy="956.36218"

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

+3 -3
View File
@@ -35,7 +35,7 @@
units="px"
inkscape:showpageshadow="false"
inkscape:window-width="1680"
inkscape:window-height="925"
inkscape:window-height="1005"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1"
@@ -60,14 +60,14 @@
id="layer1"
transform="translate(0,-552.36218)">
<rect
style="fill:#26e1cf;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:#b6d46f;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4139"
width="1024"
height="500"
x="0"
y="552.36218" />
<path
style="fill:#26af9d;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:#a6c45f;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 786.41602 28.683594 A 397.04337 397.04337 0 0 0 389.37305 425.72656 A 397.04337 397.04337 0 0 0 396.67383 500 L 1024 500 L 1024 108.21484 A 397.04337 397.04337 0 0 0 786.41602 28.683594 z "
transform="translate(0,552.36218)"
id="circle5439" />

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

+5 -5
View File
@@ -26,8 +26,8 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.7708333"
inkscape:cx="31.823204"
inkscape:zoom="1.046875"
inkscape:cx="96"
inkscape:cy="96"
inkscape:document-units="px"
inkscape:current-layer="layer1"
@@ -35,7 +35,7 @@
units="px"
inkscape:showpageshadow="false"
inkscape:window-width="1680"
inkscape:window-height="925"
inkscape:window-height="1005"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1"
@@ -64,9 +64,9 @@
cy="958.36218"
cx="96"
id="circle5439"
style="fill:#26af9d;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
style="fill:#a6c45f;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
style="fill:#26e1cf;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:#b6d46f;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path5437"
cx="96"
cy="956.36218"

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB