Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9abc01fc4f | ||
|
|
d10a33c1b7 | ||
|
|
357b2b5d59 | ||
|
|
dfd64405da | ||
|
|
045daf9deb | ||
|
|
46b9ef516c | ||
|
|
0265909fd7 | ||
|
|
ceef92bb7c | ||
|
|
46785bab01 | ||
|
|
ccbb0f9e8a | ||
|
|
833d8e93d3 | ||
|
|
6dff9992d8 | ||
|
|
0b3dfe93cf | ||
|
|
e79ad49d15 | ||
|
|
38f7ba1ec6 | ||
|
|
4d268240fd | ||
|
|
1131f749a9 | ||
|
|
93a3cd2620 | ||
|
|
a866a2eab3 | ||
|
|
c5d6bfa4b2 | ||
|
|
6a63bc4e06 | ||
|
|
09ff334c4c | ||
|
|
45a2ac0647 | ||
|
|
425f3a7b80 | ||
|
|
f895b42cfe | ||
|
|
ecd4c487e3 | ||
|
|
750671c408 | ||
|
|
ead856221f | ||
|
|
34f14d0ff0 | ||
|
|
1b21297d83 | ||
|
|
53cb6fe007 | ||
|
|
f1daa19056 | ||
|
|
bd9da5889c | ||
|
|
d5949e557a | ||
|
|
51079e5208 | ||
|
|
09f3368bf0 | ||
|
|
84e03e3cc8 | ||
|
|
cff299771a | ||
|
|
7a327ab7c4 | ||
|
|
72b8924574 | ||
|
|
527b7a6a59 | ||
|
|
e9267e4e5a | ||
|
|
ac18733368 | ||
|
|
300c3bfd26 | ||
|
|
6449d9962d | ||
|
|
12554e63e2 | ||
|
|
af60ee6edb | ||
|
|
fe31fc6df2 | ||
|
|
6d4f3cafbf | ||
|
|
fa23b8078c | ||
|
|
e3c0fe8857 | ||
|
|
fa568686b6 | ||
|
|
304357b43c | ||
|
|
1e76b14038 | ||
|
|
d0777350a2 | ||
|
|
c7c1e74240 | ||
|
|
c793e1399b | ||
|
|
c550a6ff51 | ||
|
|
05b0f719e0 | ||
|
|
4326df5069 | ||
|
|
ba24287f04 | ||
|
|
bd8f1b17dd | ||
|
|
2c21aeb83a | ||
|
|
9ccff808bc | ||
|
|
32e936dd71 | ||
|
|
58eebacd4f | ||
|
|
75b945e842 | ||
|
|
a9ea77f74f | ||
|
|
3df658165b | ||
|
|
40a6a77b8d | ||
|
|
301a33a176 | ||
|
|
8d6623786c | ||
|
|
a225eab6f2 | ||
|
|
9f2efeb001 | ||
|
|
105c81d409 | ||
|
|
4e1eb28ca4 | ||
|
|
b72ed746bf | ||
|
|
1aaee3c85a | ||
|
|
eb0218e733 | ||
|
|
bef7365f28 | ||
|
|
c72b6a2e5f | ||
|
|
a7e358852c | ||
|
|
7cf8cbe6d8 | ||
|
|
e379e55570 | ||
|
|
a55795a7b6 | ||
|
|
83c0cd0293 | ||
|
|
d138148cb8 | ||
|
|
c3c08879e0 | ||
|
|
d0f02faca7 | ||
|
|
c9db3514d1 | ||
|
|
f2a0e1a392 | ||
|
|
f4de041407 | ||
|
|
73ba2914e8 | ||
|
|
2907c8c49c | ||
|
|
f28f956a8d | ||
|
|
972eb6a0b0 | ||
|
|
08bb3f2127 | ||
|
|
b28e939f58 | ||
|
|
2edb8112b7 | ||
|
|
cf5a6dc8b8 | ||
|
|
3ec6f18fe0 | ||
|
|
3a8f6cb827 | ||
|
|
65c7fe52ee | ||
|
|
5d3b3eb195 | ||
|
|
0e4c2963a5 | ||
|
|
791c50cd4a | ||
|
|
c04b08ab87 | ||
|
|
f07c4ac0f4 | ||
|
|
05d63bd73f | ||
|
|
558fd5212d | ||
|
|
b918be76e4 | ||
|
|
2136a8c73e | ||
|
|
959c6e7d4d | ||
|
|
50930d07a6 | ||
|
|
36e7aab27c | ||
|
|
bb4fc8ed08 | ||
|
|
7a33ebd1a3 | ||
|
|
c8444b8935 | ||
|
|
4c6d66a4aa | ||
|
|
39f95a1c04 | ||
|
|
9e30b108e7 | ||
|
|
1b6b1cefe3 | ||
|
|
b634370a0b | ||
|
|
f32d44c3a1 | ||
|
|
2e060d1ca8 | ||
|
|
6acdce32f2 | ||
|
|
092ec694f6 | ||
|
|
7fed7877a0 | ||
|
|
b17393d5ef | ||
|
|
319ae53b3b | ||
|
|
6a47a7e477 | ||
|
|
19fb733182 | ||
|
|
ce6c6f26d2 | ||
|
|
3633af5e0a | ||
|
|
87502f7226 | ||
|
|
f4af35ad46 | ||
|
|
60f0d8bd87 | ||
|
|
1ccfcfcb8f | ||
|
|
213689e9f9 | ||
|
|
6e2f2cab92 | ||
|
|
4b3d745154 | ||
|
|
a2bcd67568 | ||
|
|
072eec5306 | ||
|
|
d505c6b07d | ||
|
|
dbfbaab030 | ||
|
|
3d1402add4 | ||
|
|
1d2bd8d778 | ||
|
|
2bb413e3e8 | ||
|
|
75a59bc3e9 | ||
|
|
9a15bf0871 | ||
|
|
53248fd23d |
@@ -1,5 +1,98 @@
|
||||
# Change Log
|
||||
|
||||
## 1.58.2
|
||||
* Fix parsing WiFi network suggestions
|
||||
|
||||
## 1.58.1
|
||||
* Update zh-rCn translation
|
||||
* Fix monochrome launcher icon
|
||||
|
||||
## 1.58.0
|
||||
* Improve detection of inverted barcodes
|
||||
* Optionally allow duplicates in bulk scan
|
||||
* Add Danish translation
|
||||
* Update Italian translation
|
||||
* Update Japanese translation
|
||||
* Update Russian translation
|
||||
* Fix charset decoding for PDF 417
|
||||
* Fix monochrome icon
|
||||
|
||||
## 1.57.0
|
||||
* Add optional audio feedback for scanning
|
||||
* Allow removing individual WiFi network suggestions
|
||||
* Recognize incomplete and malformed WiFi barcodes
|
||||
* Fix using shared text for encoding
|
||||
* Add Korean language
|
||||
* Update Chinese translation
|
||||
* Update Português/Brasil translation
|
||||
* Update Russian translation
|
||||
|
||||
## 1.56.3
|
||||
* Fix parsing URLs in barcodes
|
||||
* Update French, Portuguese, Turkish and Taiwan translation
|
||||
|
||||
## 1.56.2
|
||||
* Fix generating 1D barcode text output
|
||||
|
||||
## 1.56.1
|
||||
* Allow pinching a barcode to its generated size
|
||||
* Fix view/frame transformation matrix
|
||||
* Fix handling of tab characters
|
||||
* Update Indonesian translation
|
||||
* Update Russian translation
|
||||
|
||||
## 1.56.0
|
||||
* Add an action item to lock/unlock free rotation
|
||||
* Support setting fore and background colors when creating barcodes
|
||||
* Fix creating barcodes with UTF-8 content
|
||||
|
||||
## 1.55.0
|
||||
* Make recreated barcode interactive
|
||||
* Update to latest ZXing C++
|
||||
* Update Italian translation
|
||||
|
||||
## 1.54.1
|
||||
* Update Russian translation
|
||||
* Update Turkish translation
|
||||
* Update Italian translation
|
||||
* Fix handling GS1 and ISO15434 content types
|
||||
* Fix VerifyError on Android 4
|
||||
|
||||
## 1.54.0
|
||||
* Recreate and show barcode from read contents if possible
|
||||
* Add ebay, Amazon and barcodelookup.com to search engines
|
||||
|
||||
## 1.53.1
|
||||
* Fix proguard configuration
|
||||
|
||||
## 1.53.0
|
||||
* Migrate to ZXing-C++ and add support for Micro QR Codes
|
||||
* Multi-select scans in history listing
|
||||
* Remove preset content for Encode shortcut
|
||||
* Always show QR Code version and remove setting
|
||||
* Fix PDF-417 UTF-8 text encoding
|
||||
* Hide sensitive content from clipboard
|
||||
* Remove setting a custom language on Android 13+
|
||||
* Condense text output of generated barcodes
|
||||
* Update Russian translation
|
||||
* Update Spanish translation
|
||||
* Add Persian translation
|
||||
|
||||
## 1.52.0
|
||||
* Fix parsing timezone in calendar dates
|
||||
* Update French translation
|
||||
|
||||
## 1.51.1
|
||||
* Fix extraction of raw bytes for some barcodes
|
||||
|
||||
## 1.51.0
|
||||
* Add support for Deutsche Post Matrixcode stamp
|
||||
* Allow free image rotation for scanning from images
|
||||
* Fix setting TO field in MATMSG format
|
||||
* Update Italian translation
|
||||
* Update zh-rCN translation
|
||||
* Update pt-br translation
|
||||
|
||||
## 1.50.0
|
||||
* Add support for MATMSG format
|
||||
* Add a setting to show the QR Code version
|
||||
|
||||
+1
-1
@@ -17,4 +17,4 @@ Then write a [good commit message][commit_messages] to keep the history
|
||||
meaningful and useful. One feature, one commit.
|
||||
|
||||
[android_best_practices]: https://developer.android.com/distribute/best-practices/develop/
|
||||
[commit_messages]: https://juffalow.com/other/write-good-git-commit-message
|
||||
[commit_messages]: https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines
|
||||
|
||||
@@ -20,9 +20,6 @@ infer: clean
|
||||
test:
|
||||
./gradlew test
|
||||
|
||||
cat:
|
||||
./gradlew test cAT
|
||||
|
||||
testview:
|
||||
adb shell am start -W -a android.intent.action.VIEW -d 'binaryeye://scan'
|
||||
|
||||
|
||||
+8
-3
@@ -12,7 +12,7 @@ hesitate to contact me.
|
||||
Required to add a WiFi network from a barcode (usually a QR Code).
|
||||
|
||||
Before Android Q, this feature requires using
|
||||
[WifiManager.getConfiguredNetworks][configuredNetworks]
|
||||
[WifiManager.getConfiguredNetworks][getConfiguredNetworks]
|
||||
which requires `ACCESS_FINE_LOCATION`.
|
||||
|
||||
On Android Q an better, this permission is not requested nor required.
|
||||
@@ -46,9 +46,13 @@ which requires `CHANGE_WIFI_STATE`.
|
||||
Required to add a WiFi network from a barcode (usually a QR Code).
|
||||
|
||||
Before Android Q, this feature requires using
|
||||
[WifiManager.getConfiguredNetworks][configuredNetworks]
|
||||
[WifiManager.getConfiguredNetworks][getConfiguredNetworks]
|
||||
which requires `ACCESS_WIFI_STATE`.
|
||||
|
||||
From Android R, `ACCESS_WIFI_STATE` is required for
|
||||
[WifiManager.getNetworkSuggestions][getNetworkSuggestions]
|
||||
which is used to remove individual network suggestions.
|
||||
|
||||
[ACCESS_FINE_LOCATION]: https://developer.android.com/reference/android/Manifest.permission#ACCESS_FINE_LOCATION
|
||||
[CAMERA]: https://developer.android.com/reference/android/Manifest.permission#CAMERA
|
||||
[INTERNET]: https://developer.android.com/reference/android/Manifest.permission#INTERNET
|
||||
@@ -56,5 +60,6 @@ which requires `ACCESS_WIFI_STATE`.
|
||||
[WRITE_EXTERNAL_STORAGE]: https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE
|
||||
[CHANGE_WIFI_STATE]: https://developer.android.com/reference/android/Manifest.permission#CHANGE_WIFI_STATE
|
||||
[ACCESS_WIFI_STATE]: https://developer.android.com/reference/android/Manifest.permission#ACCESS_FINE_LOCATION
|
||||
[configuredNetworks]: https://developer.android.com/reference/android/net/wifi/WifiManager#getConfiguredNetworks()
|
||||
[getConfiguredNetworks]: https://developer.android.com/reference/android/net/wifi/WifiManager#getConfiguredNetworks()
|
||||
[addNetworkSuggestions]: https://developer.android.com/reference/android/net/wifi/WifiManager#addNetworkSuggestions(java.util.List%3Candroid.net.wifi.WifiNetworkSuggestion%3E)
|
||||
[getNetworkSuggestions]: https://developer.android.com/reference/android/net/wifi/WifiManager#getNetworkSuggestions()
|
||||
|
||||
@@ -7,8 +7,8 @@ This one is free, without any ads and open source.
|
||||
Works in portrait and landscape orientation, can read inverted codes,
|
||||
comes in Material Design and can also generate barcodes.
|
||||
|
||||
Binary Eye uses the [ZXing][zxing] ("Zebra Crossing") barcode scanning
|
||||
library.
|
||||
Binary Eye uses the [ZXing-C++][zxing_cpp] ("Zebra Crossing") barcode
|
||||
scanning library.
|
||||
|
||||
## Screenshots
|
||||
|
||||
@@ -39,10 +39,10 @@ ZXing can read the following barcode formats:
|
||||
* [EAN 8][ean_8]
|
||||
* [EAN 13][ean_13]
|
||||
* [ITF][itf]
|
||||
* [MAXICODE][maxicode] (only when unrotated and unskewed, see [77][77],
|
||||
because of which Binary Eye *cannot* read this barcode)
|
||||
* [MAXICODE][maxicode] (partial)
|
||||
* [PDF417][pdf417]
|
||||
* [QR CODE][qr_code]
|
||||
* [Micro QR Code][micro_qr_code]
|
||||
* [RSS 14][rss]
|
||||
* [RSS EXPANDED][rss]
|
||||
* [UPC A][upc_a]
|
||||
@@ -84,7 +84,6 @@ Supported symbols are:
|
||||
* `RESULT` - scanned content
|
||||
* `RESULT_BYTES` - raw result as a hex string
|
||||
* `FORMAT` - barcode format
|
||||
* `META` - the meta data, if available
|
||||
|
||||
### SCAN Intent
|
||||
|
||||
@@ -135,37 +134,8 @@ class YourActivity : Activity() {
|
||||
}
|
||||
```
|
||||
|
||||
## RenderScript
|
||||
|
||||
This app uses [RenderScript][rs] to resize and rotate the camera image.
|
||||
Unfortunately, RenderScript has some nasty gotchas.
|
||||
|
||||
### RenderScript.forceCompat()
|
||||
|
||||
It's necessary to call `RenderScript.forceCompat()` on some devices/roms.
|
||||
|
||||
`RenderScript.forceCompat()` needs to be run before any other RenderScript
|
||||
function and unfortunately there is no way to know if invoking `forceCompat()`
|
||||
is necessary or not.
|
||||
|
||||
If `RenderScript.forceCompat()` is necessary, a `RSRuntimeException` will
|
||||
be thrown and the only option is to restart the app, this time with calling
|
||||
`forceCompat()` first.
|
||||
|
||||
Calling `RenderScript.forceCompat()` means the processing is done in
|
||||
software so you probably don't want to enable it by default.
|
||||
|
||||
### 2D barcodes
|
||||
|
||||
If you want to fork this and are only interested in reading 2D barcodes
|
||||
(like QR or Aztec), you may want to remove the custom rotation kernel
|
||||
altogether as ZXing can read 2D barcodes in any orientation.
|
||||
|
||||
This will make your app a bit simpler and saves you from compiling a
|
||||
custom RenderScript kernel for each architecture you want to support.
|
||||
|
||||
[play]: https://play.google.com/store/search?q=barcode%20scanner&c=apps
|
||||
[zxing]: https://github.com/zxing/zxing
|
||||
[zxing_cpp]: https://github.com/zxing-cpp/zxing-cpp
|
||||
[kotlin]: http://kotlinlang.org/
|
||||
[aztec]: https://en.wikipedia.org/wiki/Aztec_Code
|
||||
[codabar]: https://en.wikipedia.org/wiki/Codabar
|
||||
@@ -179,12 +149,11 @@ custom RenderScript kernel for each architecture you want to support.
|
||||
[maxicode]: https://en.wikipedia.org/wiki/MaxiCode
|
||||
[pdf417]: https://en.wikipedia.org/wiki/PDF417
|
||||
[qr_code]: https://en.wikipedia.org/wiki/QR_code
|
||||
[micro_qr_code]: https://en.wikipedia.org/wiki/QR_code#Micro_QR_code
|
||||
[rss]: https://en.wikipedia.org/wiki/GS1_DataBar
|
||||
[upc_a]: https://en.wikipedia.org/wiki/Universal_Product_Code
|
||||
[upc_e]: https://en.wikipedia.org/wiki/Universal_Product_Code#UPC-E
|
||||
[upc_ean]: https://en.wikipedia.org/wiki/Universal_Product_Code#EAN-13
|
||||
[77]: https://github.com/markusfisch/BinaryEye/issues/77
|
||||
[rs]: https://developer.android.com/guide/topics/renderscript/compute
|
||||
[start_activity]: https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent,%20int)
|
||||
[on_activity_result]: https://developer.android.com/reference/android/app/Activity#onActivityResult(int,%20int,%20android.content.Intent)
|
||||
[intent_result]: https://developer.android.com/training/basics/intents/result
|
||||
|
||||
+5
-37
@@ -9,19 +9,8 @@ android {
|
||||
minSdkVersion 9
|
||||
targetSdkVersion sdk_version
|
||||
|
||||
versionCode 97
|
||||
versionName '1.50.0'
|
||||
|
||||
// Required for desugaring.
|
||||
multiDexEnabled true
|
||||
|
||||
// It's recommended to set this value to the lowest API level
|
||||
// able to provide all the functionality.
|
||||
renderscriptTargetApi 24
|
||||
renderscriptSupportModeEnabled true
|
||||
renderscriptSupportModeBlasEnabled true
|
||||
|
||||
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
|
||||
versionCode 115
|
||||
versionName '1.58.2'
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
@@ -64,39 +53,18 @@ android {
|
||||
enableSplit = false
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
// To desugar fancy Java features in ZXing 3.4.+ that don't
|
||||
// work on SDK < 24. See:
|
||||
// https://github.com/zxing/zxing/issues/1170
|
||||
coreLibraryDesugaringEnabled true
|
||||
}
|
||||
|
||||
lint {
|
||||
// Because at the time of writing, even the latest version
|
||||
// of RenderScript is raising this error no matter if
|
||||
// renderscriptTargetApi matches targetSdkVersion.
|
||||
disable 'GradleCompatible'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
androidTestImplementation('com.android.support.test:runner:1.0.2') {
|
||||
exclude module: 'support-annotations'
|
||||
}
|
||||
androidTestImplementation('com.android.support.test:rules:1.0.2') {
|
||||
exclude module: 'support-annotations'
|
||||
}
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1"
|
||||
implementation "com.android.support:appcompat-v7:$support_version"
|
||||
implementation "com.android.support:design:$support_version"
|
||||
implementation "com.android.support:preference-v7:$support_version"
|
||||
implementation "com.android.support:preference-v14:$support_version"
|
||||
implementation 'com.google.zxing:core:3.5.0'
|
||||
implementation 'com.github.markusfisch:CameraView:1.9.1'
|
||||
implementation 'com.github.markusfisch:ScalingImageView:1.3.0'
|
||||
implementation 'com.github.markusfisch:ScalingImageView:1.4.1'
|
||||
implementation 'com.github.markusfisch:zxing-cpp:v2.0.0.0'
|
||||
}
|
||||
|
||||
Vendored
+2
-1
@@ -3,4 +3,5 @@
|
||||
-dontwarn android.support.v8.**
|
||||
|
||||
-keep class android.support.v7.widget.SearchView { *; }
|
||||
-keep class android.support.v8.renderscript.** { *; }
|
||||
|
||||
-keep class de.markusfisch.android.zxingcpp.** { *; }
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 97 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 88 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 77 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 47 KiB |
@@ -1,107 +0,0 @@
|
||||
package de.markusfisch.android.binaryeye
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.support.test.InstrumentationRegistry
|
||||
import android.support.test.runner.AndroidJUnit4
|
||||
import android.support.v8.renderscript.RenderScript
|
||||
import de.markusfisch.android.binaryeye.rs.Preprocessor
|
||||
import de.markusfisch.android.binaryeye.zxing.Zxing
|
||||
import org.junit.Assert.fail;
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class PreprocessorTest {
|
||||
@Test
|
||||
fun processSamples() {
|
||||
val assets = InstrumentationRegistry.getInstrumentation()
|
||||
.context.assets
|
||||
val samples = assets.list("samples")
|
||||
checkNotNull(samples) { "no samples found" }
|
||||
val pattern = Pattern.compile(
|
||||
"[0-9]+-([0-9]+)deg.jpg"
|
||||
)
|
||||
val rs = RenderScript.create(
|
||||
InstrumentationRegistry.getTargetContext(),
|
||||
)
|
||||
val zxing = Zxing()
|
||||
for (sample in samples) {
|
||||
val m = pattern.matcher(sample)
|
||||
if (!m.find() || m.groupCount() < 1) {
|
||||
fail("invalid sample: $sample")
|
||||
}
|
||||
val bitmap = BitmapFactory.decodeStream(
|
||||
assets.open("samples/$sample")
|
||||
)
|
||||
val frameData = getNV21(bitmap)
|
||||
val frameWidth = bitmap.width
|
||||
val frameHeight = bitmap.height
|
||||
val frameOrientation = m.group(1) ?: return
|
||||
val preprocessor = Preprocessor(
|
||||
rs,
|
||||
frameWidth,
|
||||
frameHeight,
|
||||
null
|
||||
)
|
||||
val outWidth: Int
|
||||
val outHeight: Int
|
||||
val orientation = frameOrientation.toInt()
|
||||
if (orientation == 90 || orientation == 270) {
|
||||
preprocessor.resizeAndRotate(frameData)
|
||||
outWidth = preprocessor.outHeight
|
||||
outHeight = preprocessor.outWidth
|
||||
} else {
|
||||
preprocessor.resizeOnly(frameData)
|
||||
outWidth = preprocessor.outWidth
|
||||
outHeight = preprocessor.outHeight
|
||||
}
|
||||
val result = zxing.decode(frameData, outWidth, outHeight)
|
||||
preprocessor.destroy()
|
||||
checkNotNull(result) { "no barcode found in $sample" }
|
||||
}
|
||||
rs.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
fun getNV21(bitmap: Bitmap): ByteArray {
|
||||
val width = bitmap.width
|
||||
val height = bitmap.height
|
||||
val argb = IntArray(width * height)
|
||||
bitmap.getPixels(argb, 0, width, 0, 0, width, height)
|
||||
return encodeYUV420SP(argb, width, height)
|
||||
}
|
||||
|
||||
private fun encodeYUV420SP(argb: IntArray, width: Int, height: Int): ByteArray {
|
||||
val yuv = ByteArray(ceilIfUneven(width) * ceilIfUneven(height) * 3 / 2)
|
||||
var yIndex = 0
|
||||
var uvIndex = width * height
|
||||
var r: Int
|
||||
var g: Int
|
||||
var b: Int
|
||||
var y: Int
|
||||
var u: Int
|
||||
var v: Int
|
||||
var index = 0
|
||||
for (t in 0 until height) {
|
||||
for (s in 0 until width) {
|
||||
val pixel = argb[index]
|
||||
r = pixel and 0xff0000 shr 16
|
||||
g = pixel and 0xff00 shr 8
|
||||
b = pixel and 0xff
|
||||
y = (66 * r + 129 * g + 25 * b + 128 shr 8) + 16
|
||||
u = (-38 * r - 74 * g + 112 * b + 128 shr 8) + 128
|
||||
v = (112 * r - 94 * g - 18 * b + 128 shr 8) + 128
|
||||
yuv[yIndex++] = (if (y < 0) 0 else if (y > 255) 255 else y).toByte()
|
||||
if (t % 2 == 0 && index % 2 == 0) {
|
||||
yuv[uvIndex++] = (if (v < 0) 0 else if (v > 255) 255 else v).toByte()
|
||||
yuv[uvIndex++] = (if (u < 0) 0 else if (u > 255) 255 else u).toByte()
|
||||
}
|
||||
++index
|
||||
}
|
||||
}
|
||||
return yuv
|
||||
}
|
||||
|
||||
private fun ceilIfUneven(n: Int) = if (n and 1 == 1) n + 1 else n
|
||||
@@ -12,8 +12,7 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="28"/>
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"
|
||||
android:maxSdkVersion="28"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-feature android:name="android.hardware.camera"/>
|
||||
<uses-feature android:name="android.hardware.camera.autofocus"/>
|
||||
<uses-sdk tools:overrideLibrary="android.support.v14.preference"/>
|
||||
@@ -64,15 +63,6 @@
|
||||
<action android:name="com.google.zxing.client.android.SCAN"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<data android:host="markusfisch.de"/>
|
||||
<data android:pathPrefix="/BinaryEye"/>
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
|
||||
@@ -39,8 +39,10 @@ abstract class SchemeAction : IAction {
|
||||
final override fun canExecuteOn(data: ByteArray): Boolean {
|
||||
val content = String(data)
|
||||
return if (buildRegex) {
|
||||
content.matches("""^$scheme://[\w\W]+$""".toRegex(
|
||||
RegexOption.IGNORE_CASE)
|
||||
content.matches(
|
||||
"""^$scheme://[\w\W]+$""".toRegex(
|
||||
RegexOption.IGNORE_CASE
|
||||
)
|
||||
)
|
||||
} else {
|
||||
content.startsWith("$scheme://", ignoreCase = true)
|
||||
|
||||
@@ -19,31 +19,37 @@ object MatMsgAction : IntentAction() {
|
||||
context: Context,
|
||||
data: ByteArray
|
||||
): Intent? {
|
||||
val encoded = String(data)
|
||||
// Allow arbitrary order.
|
||||
val to = encoded.extractFirst("""[:;]TO:([\w.%@+-]+);""")
|
||||
val sub = encoded.extractFirst("""[:;]SUB:([^;]+);""")
|
||||
val body = encoded.extractFirst("""[:;]BODY:([^;]+);""")
|
||||
val mm = MatMsg(String(data))
|
||||
// Allow incomplete but not completely missing data.
|
||||
if (to == null && sub == null && body == null) {
|
||||
if (mm.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
return Intent(
|
||||
Intent.ACTION_SENDTO,
|
||||
Uri.parse("mailto:")
|
||||
).apply {
|
||||
to?.let {
|
||||
putExtra(Intent.EXTRA_EMAIL, to)
|
||||
mm.to?.let {
|
||||
putExtra(Intent.EXTRA_EMAIL, arrayOf(mm.to))
|
||||
}
|
||||
sub?.let {
|
||||
putExtra(Intent.EXTRA_SUBJECT, sub)
|
||||
mm.sub?.let {
|
||||
putExtra(Intent.EXTRA_SUBJECT, mm.sub)
|
||||
}
|
||||
body?.let {
|
||||
putExtra(Intent.EXTRA_TEXT, body)
|
||||
mm.body?.let {
|
||||
putExtra(Intent.EXTRA_TEXT, mm.body)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Public so this can be tested.
|
||||
class MatMsg(encoded: String) {
|
||||
// Allow arbitrary order.
|
||||
val to = encoded.extractFirst("""[:;]TO:([\w.%@+-]+);""")
|
||||
val sub = encoded.extractFirst("""[:;]SUB:([^;]+);""")
|
||||
val body = encoded.extractFirst("""[:;]BODY:([^;]+);""")
|
||||
|
||||
fun isEmpty() = to == null && sub == null && body == null
|
||||
}
|
||||
|
||||
private fun String.extractFirst(regex: String) =
|
||||
regex.toRegex().find(this)?.groupValues?.get(1)
|
||||
|
||||
+2
-2
@@ -4,9 +4,9 @@ import android.content.Context
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.actions.IAction
|
||||
import de.markusfisch.android.binaryeye.app.alertDialog
|
||||
import de.markusfisch.android.binaryeye.app.urlEncode
|
||||
import de.markusfisch.android.binaryeye.app.prefs
|
||||
import de.markusfisch.android.binaryeye.content.openUrl
|
||||
import de.markusfisch.android.binaryeye.net.urlEncode
|
||||
|
||||
object OpenOrSearchAction : IAction {
|
||||
override val iconResId: Int = R.drawable.ic_action_search
|
||||
@@ -23,7 +23,7 @@ object OpenOrSearchAction : IAction {
|
||||
url: String,
|
||||
search: Boolean
|
||||
) {
|
||||
if (!context.openUrl(url) && search) {
|
||||
if (!context.openUrl(url, silent = true) && search) {
|
||||
openSearch(context, url)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.actions.IntentAction
|
||||
import de.markusfisch.android.binaryeye.app.parseAndNormalizeUri
|
||||
import de.markusfisch.android.binaryeye.content.parseAndNormalizeUri
|
||||
|
||||
object TelAction : IntentAction() {
|
||||
private val telRegex = """^tel:(\+?[0-9]+)$""".toRegex(
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.actions.IntentAction
|
||||
import de.markusfisch.android.binaryeye.actions.vtype.VTypeParser
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
object VCardAction : IntentAction() {
|
||||
override val iconResId: Int
|
||||
|
||||
+29
-28
@@ -1,6 +1,5 @@
|
||||
package de.markusfisch.android.binaryeye.actions.vtype.vevent
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
@@ -47,7 +46,7 @@ object VEventAction : IntentAction() {
|
||||
dateFormats.simpleFindParse(eventStart.value)?.also {
|
||||
putExtra(
|
||||
CalendarContract.EXTRA_EVENT_BEGIN_TIME,
|
||||
it.localTime()
|
||||
it.time
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -55,37 +54,39 @@ object VEventAction : IntentAction() {
|
||||
dateFormats.simpleFindParse(eventEnd.value)?.also {
|
||||
putExtra(
|
||||
CalendarContract.EXTRA_EVENT_END_TIME,
|
||||
it.localTime()
|
||||
it.time
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We definitely don't wan't the local format.
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
private val dateFormats = listOf(
|
||||
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"),
|
||||
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"),
|
||||
SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'"),
|
||||
SimpleDateFormat("yyyyMMdd'T'HHmmss"),
|
||||
SimpleDateFormat("yyyy-MM-dd"),
|
||||
SimpleDateFormat("yyyyMMdd")
|
||||
)
|
||||
|
||||
private fun List<SimpleDateFormat>.simpleFindParse(data: String): Date? {
|
||||
for (simpleDataFormat in this) {
|
||||
return simpleDataFormat.simpleParse(data) ?: continue
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun SimpleDateFormat.simpleParse(data: String): Date? = try {
|
||||
this.parse(data)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun Date.localTime() = time - timezoneOffset * 60000L
|
||||
private val dateFormats = listOf(
|
||||
"yyyy-MM-dd'T'HH:mm:ssXXX",
|
||||
"yyyy-MM-dd'T'HH:mm:ssZ",
|
||||
"yyyy-MM-dd'T'HH:mm:ssz",
|
||||
"yyyy-MM-dd'T'HH:mm:ss",
|
||||
"yyyyMMdd'T'HHmmssXXX",
|
||||
"yyyyMMdd'T'HHmmssZ",
|
||||
"yyyyMMdd'T'HHmmssz",
|
||||
"yyyyMMdd'T'HHmmss",
|
||||
"yyyy-MM-dd",
|
||||
"yyyyMMdd"
|
||||
)
|
||||
|
||||
private fun List<String>.simpleFindParse(date: String): Date? {
|
||||
for (pattern in this) {
|
||||
return SimpleDateFormat(
|
||||
pattern,
|
||||
Locale.getDefault()
|
||||
).simpleParse(date) ?: continue
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun SimpleDateFormat.simpleParse(date: String): Date? = try {
|
||||
parse(date)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
@@ -6,9 +6,8 @@ import de.markusfisch.android.binaryeye.actions.IAction
|
||||
import de.markusfisch.android.binaryeye.content.openUrl
|
||||
|
||||
object WebAction : IAction {
|
||||
private val colloquialRegex = """^(http[s]*://)*([a-z0-9]+[a-z0-9-]*[a-z0-9]+[.])+[a-z]{2,}([?#/]+[\w/=&;._-]*)*$""".toRegex(
|
||||
RegexOption.IGNORE_CASE
|
||||
)
|
||||
private val colloquialRegex =
|
||||
"^(http[s]*://)*[A-Za-z0-9]{3,}\\.[A-Za-z]{2,}[^ \t\r\n]*$".toRegex()
|
||||
|
||||
override val iconResId: Int = R.drawable.ic_action_open
|
||||
override val titleResId: Int = R.string.open_url
|
||||
|
||||
+44
-37
@@ -10,12 +10,6 @@ import android.support.annotation.RequiresApi
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import java.util.*
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.Q)
|
||||
fun removeNetworkSuggestions(context: Context): Int =
|
||||
(context.applicationContext.getSystemService(
|
||||
Context.WIFI_SERVICE
|
||||
) as WifiManager).removeNetworkSuggestions(listOf())
|
||||
|
||||
/**
|
||||
* Normal:
|
||||
* WIFI:S:[network SSID];T:<WPA|WEP|nopass|>;P:[network password];H:<true|false|>;;
|
||||
@@ -50,8 +44,10 @@ object WifiConnector {
|
||||
passwordBlock?.apply {
|
||||
invoke(parsedData.password)
|
||||
}
|
||||
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
// WifiConfiguration is deprecated in Android Q.
|
||||
return if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
||||
// WifiConfiguration is deprecated in Android Q but
|
||||
// because it's only possible in R to query network
|
||||
// suggestions, we still use the deprecated API on Q.
|
||||
@Suppress("DEPRECATION")
|
||||
WifiConfiguration().apply(parsedData)
|
||||
} else {
|
||||
@@ -63,33 +59,23 @@ object WifiConnector {
|
||||
val wifiManager = context.applicationContext.getSystemService(
|
||||
Context.WIFI_SERVICE
|
||||
) as WifiManager
|
||||
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
// WifiConfiguration is deprecated in Android Q.
|
||||
@Suppress("DEPRECATION")
|
||||
val wifiConfig = config as WifiConfiguration
|
||||
if (wifiManager.enableWifi() &&
|
||||
wifiManager.removeOldNetwork(wifiConfig) &&
|
||||
wifiManager.enableNewNetwork(wifiConfig)
|
||||
) {
|
||||
R.string.wifi_added
|
||||
} else {
|
||||
R.string.wifi_config_failed
|
||||
}
|
||||
// WifiConfiguration is deprecated in Android Q.
|
||||
@Suppress("DEPRECATION")
|
||||
return if ((config is WifiConfiguration &&
|
||||
wifiManager.enableWifi() &&
|
||||
wifiManager.removeOldNetwork(config) &&
|
||||
wifiManager.enableNewNetwork(config)) ||
|
||||
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
|
||||
config is WifiNetworkSuggestion.Builder &&
|
||||
wifiManager.addNetworkFromBuilder(config))
|
||||
) {
|
||||
R.string.wifi_added
|
||||
} else {
|
||||
val suggestion = (config as WifiNetworkSuggestion.Builder).build()
|
||||
val suggestions = listOf(suggestion)
|
||||
// Remove previous conflicting network suggestion.
|
||||
wifiManager.removeNetworkSuggestions(suggestions)
|
||||
val result = wifiManager.addNetworkSuggestions(suggestions)
|
||||
if (result == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
|
||||
R.string.wifi_added
|
||||
} else {
|
||||
R.string.wifi_config_failed
|
||||
}
|
||||
R.string.wifi_config_failed
|
||||
}
|
||||
}
|
||||
|
||||
internal fun parseMap(string: String): Map<String, String>? {
|
||||
internal fun parseMap(input: String): Map<String, String>? {
|
||||
// Normally those codes should have the last semicolon, but many
|
||||
// generators don't add it.
|
||||
val wifiRegex = """^WIFI:((?:.+?:(?:[^\\;]|\\.)*;)+);?$""".toRegex()
|
||||
@@ -97,7 +83,7 @@ object WifiConnector {
|
||||
// and : because many QR Code creators don't escape properly.
|
||||
val pairRegex = """(.+?):((?:[^\\;]|\\.)*);""".toRegex()
|
||||
return wifiRegex.matchEntire(
|
||||
string
|
||||
input.trimAndTerminate()
|
||||
)?.groupValues?.get(1)?.let { pairs ->
|
||||
pairRegex.findAll(pairs).map { pair ->
|
||||
pair.groupValues[1].uppercase(Locale.US) to pair.groupValues[2]
|
||||
@@ -126,7 +112,7 @@ object WifiConnector {
|
||||
requireSdk(Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
WifiEnterpriseConfig.Eap.NONE
|
||||
}
|
||||
} else when (inputMap["E"]) {
|
||||
} else when (inputMap["E"]?.uppercase()) {
|
||||
"AKA" -> requireSdk(Build.VERSION_CODES.LOLLIPOP) { WifiEnterpriseConfig.Eap.AKA }
|
||||
"AKA_PRIME" -> requireSdk(Build.VERSION_CODES.M) { WifiEnterpriseConfig.Eap.AKA_PRIME }
|
||||
"NONE" -> requireSdk(Build.VERSION_CODES.JELLY_BEAN_MR2) { WifiEnterpriseConfig.Eap.NONE }
|
||||
@@ -143,7 +129,7 @@ object WifiConnector {
|
||||
requireSdk(Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
WifiEnterpriseConfig.Phase2.NONE
|
||||
}
|
||||
} else when (inputMap["PH2"]) {
|
||||
} else when (inputMap["PH2"]?.uppercase()) {
|
||||
"AKA" -> requireSdk(Build.VERSION_CODES.O) { WifiEnterpriseConfig.Phase2.AKA }
|
||||
"AKA_PRIME" -> requireSdk(Build.VERSION_CODES.O) { WifiEnterpriseConfig.Phase2.AKA_PRIME }
|
||||
"GTC" -> requireSdk(Build.VERSION_CODES.JELLY_BEAN_MR2) { WifiEnterpriseConfig.Phase2.GTC }
|
||||
@@ -179,7 +165,7 @@ object WifiConnector {
|
||||
data: SimpleDataAccessor
|
||||
): WifiNetworkSuggestion.Builder? {
|
||||
try {
|
||||
when (data.securityType) {
|
||||
when (data.securityType.uppercase()) {
|
||||
"WPA", "WPA2" -> {
|
||||
data.password?.let { setWpa2Passphrase(it) }
|
||||
}
|
||||
@@ -240,8 +226,8 @@ object WifiConnector {
|
||||
fun WifiConfiguration.applySecurity(
|
||||
data: SimpleDataAccessor
|
||||
): WifiConfiguration? {
|
||||
when (data.securityType) {
|
||||
"", "nopass" -> allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
|
||||
when (data.securityType.uppercase()) {
|
||||
"", "NOPASS" -> allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
|
||||
"WEP" -> @Suppress("DEPRECATION") /* WEP as insecure */ {
|
||||
passwordWithQuotes?.let {
|
||||
wepKeys[0] = it
|
||||
@@ -303,6 +289,27 @@ object WifiConnector {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.Q)
|
||||
private fun WifiManager.addNetworkFromBuilder(
|
||||
builder: WifiNetworkSuggestion.Builder
|
||||
): Boolean {
|
||||
val suggestion = builder.build()
|
||||
val suggestions = listOf(suggestion)
|
||||
// Remove previous conflicting network suggestion.
|
||||
removeNetworkSuggestions(suggestions)
|
||||
val result = addNetworkSuggestions(suggestions)
|
||||
return result == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS
|
||||
}
|
||||
|
||||
// Make sure the string ends with a semicolon.
|
||||
private fun String.trimAndTerminate(): String {
|
||||
var trimmed = trim()
|
||||
if (trimmed.isNotEmpty() && trimmed.last() != ';') {
|
||||
trimmed += ";"
|
||||
}
|
||||
return trimmed
|
||||
}
|
||||
|
||||
// Keep possibility of wrongly unescaped \ by explicitly searching
|
||||
// for special chars.
|
||||
private val escapedRegex = """\\([\\;,":])""".toRegex()
|
||||
|
||||
@@ -7,76 +7,60 @@ import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.hardware.Camera
|
||||
import android.media.AudioManager
|
||||
import android.media.ToneGenerator
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Vibrator
|
||||
import android.support.design.widget.FloatingActionButton
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.support.v8.renderscript.RSRuntimeException
|
||||
import android.support.v8.renderscript.RenderScript
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.SeekBar
|
||||
import com.google.zxing.Result
|
||||
import com.google.zxing.ResultMetadataType
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.adapter.prettifyFormatName
|
||||
import de.markusfisch.android.binaryeye.app.*
|
||||
import de.markusfisch.android.binaryeye.content.copyToClipboard
|
||||
import de.markusfisch.android.binaryeye.content.execShareIntent
|
||||
import de.markusfisch.android.binaryeye.content.openUrl
|
||||
import de.markusfisch.android.binaryeye.content.toHexString
|
||||
import de.markusfisch.android.binaryeye.database.toScan
|
||||
import de.markusfisch.android.binaryeye.graphics.getFrameToViewMatrix
|
||||
import de.markusfisch.android.binaryeye.graphics.map
|
||||
import de.markusfisch.android.binaryeye.graphics.FrameMetrics
|
||||
import de.markusfisch.android.binaryeye.graphics.mapPosition
|
||||
import de.markusfisch.android.binaryeye.graphics.setFrameRoi
|
||||
import de.markusfisch.android.binaryeye.graphics.setFrameToView
|
||||
import de.markusfisch.android.binaryeye.media.releaseToneGenerators
|
||||
import de.markusfisch.android.binaryeye.net.sendAsync
|
||||
import de.markusfisch.android.binaryeye.os.error
|
||||
import de.markusfisch.android.binaryeye.os.getVibrator
|
||||
import de.markusfisch.android.binaryeye.os.vibrate
|
||||
import de.markusfisch.android.binaryeye.rs.Preprocessor
|
||||
import de.markusfisch.android.binaryeye.net.urlEncode
|
||||
import de.markusfisch.android.binaryeye.view.errorFeedback
|
||||
import de.markusfisch.android.binaryeye.view.initSystemBars
|
||||
import de.markusfisch.android.binaryeye.view.scanFeedback
|
||||
import de.markusfisch.android.binaryeye.view.setPaddingFromWindowInsets
|
||||
import de.markusfisch.android.binaryeye.widget.DetectorView
|
||||
import de.markusfisch.android.binaryeye.widget.toast
|
||||
import de.markusfisch.android.binaryeye.zxing.Zxing
|
||||
import de.markusfisch.android.cameraview.widget.CameraView
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Binarizer
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.DecodeHints
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Format
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Result
|
||||
import java.nio.charset.Charset
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class CameraActivity : AppCompatActivity() {
|
||||
private val zxing = Zxing { point ->
|
||||
point ?: return@Zxing
|
||||
val matrix = getMappingMatrix() ?: return@Zxing
|
||||
detectorView.post {
|
||||
detectorView.update(
|
||||
matrix.map(
|
||||
arrayOf(point),
|
||||
detectorView.coordinates
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
private val frameRoi = Rect()
|
||||
private val matrix = Matrix()
|
||||
|
||||
private lateinit var rs: RenderScript
|
||||
private lateinit var vibrator: Vibrator
|
||||
private lateinit var cameraView: CameraView
|
||||
private lateinit var detectorView: DetectorView
|
||||
private lateinit var zoomBar: SeekBar
|
||||
private lateinit var flashFab: FloatingActionButton
|
||||
|
||||
private var preprocessor: Preprocessor? = null
|
||||
private var nativeMappingMatrix: Matrix? = null
|
||||
private var rotatedMappingMatrix: Matrix? = null
|
||||
private var recreatePreprocessor = false
|
||||
private var rotate = false
|
||||
private var invert = false
|
||||
private var formatsToRead = setOf<String>()
|
||||
private var frameMetrics = FrameMetrics()
|
||||
private var decoding = true
|
||||
private var returnResult = false
|
||||
private var returnUrlTemplate: String? = null
|
||||
@@ -132,9 +116,6 @@ class CameraActivity : AppCompatActivity() {
|
||||
// custom locale.
|
||||
setTitle(R.string.scan_code)
|
||||
|
||||
rs = RenderScript.create(this)
|
||||
vibrator = getVibrator()
|
||||
|
||||
initSystemBars(this)
|
||||
setSupportActionBar(findViewById(R.id.toolbar) as Toolbar)
|
||||
|
||||
@@ -156,11 +137,10 @@ class CameraActivity : AppCompatActivity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
resetPreProcessor()
|
||||
fallbackBuffer = null
|
||||
saveZoom()
|
||||
detectorView.saveCropHandlePos()
|
||||
rs.destroy()
|
||||
releaseToneGenerators()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@@ -180,7 +160,7 @@ class CameraActivity : AppCompatActivity() {
|
||||
|
||||
private fun updateHints() {
|
||||
val restriction = restrictFormat
|
||||
val formats = if (restriction != null) {
|
||||
formatsToRead = if (restriction != null) {
|
||||
title = getString(
|
||||
R.string.scan_format,
|
||||
prettifyFormatName(restriction)
|
||||
@@ -190,7 +170,6 @@ class CameraActivity : AppCompatActivity() {
|
||||
setTitle(R.string.scan_code)
|
||||
prefs.barcodeFormats
|
||||
}
|
||||
zxing.updateHints(prefs.tryHarder, formats)
|
||||
}
|
||||
|
||||
private fun setReturnTarget(intent: Intent?) {
|
||||
@@ -205,11 +184,6 @@ class CameraActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetPreProcessor() {
|
||||
preprocessor?.destroy()
|
||||
preprocessor = null
|
||||
}
|
||||
|
||||
private fun openCamera() {
|
||||
cameraView.openAsync(
|
||||
CameraView.findCameraId(
|
||||
@@ -441,22 +415,42 @@ class CameraActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
override fun onCameraReady(camera: Camera) {
|
||||
// Reset preprocessor to make sure it always fits the current
|
||||
// frame orientation. Important for landscape to landscape
|
||||
// orientation changes.
|
||||
resetPreProcessor()
|
||||
val frameWidth = cameraView.frameWidth
|
||||
val frameHeight = cameraView.frameHeight
|
||||
val frameOrientation = cameraView.frameOrientation
|
||||
frameMetrics = FrameMetrics(
|
||||
cameraView.frameWidth,
|
||||
cameraView.frameHeight,
|
||||
cameraView.frameOrientation
|
||||
)
|
||||
updateFrameRoiAndMappingMatrix()
|
||||
ignoreNext = null
|
||||
decoding = true
|
||||
// These settings can't change while the camera is open.
|
||||
val decodeHints = DecodeHints(
|
||||
tryHarder = prefs.tryHarder,
|
||||
tryRotate = prefs.autoRotate,
|
||||
tryInvert = true,
|
||||
tryDownscale = true
|
||||
)
|
||||
var useLocalAverage = false
|
||||
camera.setPreviewCallback { frameData, _ ->
|
||||
if (decoding) {
|
||||
decodeFrame(
|
||||
useLocalAverage = useLocalAverage xor true
|
||||
ZxingCpp.readByteArray(
|
||||
frameData,
|
||||
frameWidth,
|
||||
frameHeight,
|
||||
frameOrientation
|
||||
frameMetrics.width,
|
||||
frameRoi.left, frameRoi.top,
|
||||
frameRoi.width(), frameRoi.height(),
|
||||
frameMetrics.orientation,
|
||||
decodeHints.apply {
|
||||
// By default, ZXing uses LOCAL_AVERAGE, but
|
||||
// this does not work well with inverted
|
||||
// barcodes on low-contrast backgrounds.
|
||||
binarizer = if (useLocalAverage) {
|
||||
Binarizer.LOCAL_AVERAGE
|
||||
} else {
|
||||
Binarizer.GLOBAL_HISTOGRAM
|
||||
}
|
||||
formats = formatsToRead.joinToString()
|
||||
}
|
||||
)?.let { result ->
|
||||
if (result.text != ignoreNext) {
|
||||
postResult(result)
|
||||
@@ -526,12 +520,23 @@ class CameraActivity : AppCompatActivity() {
|
||||
}
|
||||
detectorView.onRoiChanged = {
|
||||
decoding = true
|
||||
recreatePreprocessor = true
|
||||
updateFrameRoiAndMappingMatrix()
|
||||
}
|
||||
detectorView.setPaddingFromWindowInsets()
|
||||
detectorView.restoreCropHandlePos()
|
||||
}
|
||||
|
||||
private fun updateFrameRoiAndMappingMatrix() {
|
||||
val viewRect = cameraView.previewRect
|
||||
val viewRoi = if (detectorView.roi.width() < 1) {
|
||||
viewRect
|
||||
} else {
|
||||
detectorView.roi
|
||||
}
|
||||
frameRoi.setFrameRoi(frameMetrics, viewRect, viewRoi)
|
||||
matrix.setFrameToView(frameMetrics, viewRect, viewRoi)
|
||||
}
|
||||
|
||||
private fun updateFlashFab(unavailable: Boolean) {
|
||||
if (unavailable) {
|
||||
flashFab.setImageResource(R.drawable.ic_action_create)
|
||||
@@ -560,162 +565,15 @@ class CameraActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun decodeFrame(
|
||||
frameData: ByteArray?,
|
||||
frameWidth: Int,
|
||||
frameHeight: Int,
|
||||
frameOrientation: Int
|
||||
): Result? {
|
||||
frameData ?: return null
|
||||
rotate = if (prefs.autoRotate) {
|
||||
rotate xor true
|
||||
} else {
|
||||
invert = invert xor true
|
||||
isPortrait(frameOrientation)
|
||||
}
|
||||
return try {
|
||||
if (recreatePreprocessor) {
|
||||
resetPreProcessor()
|
||||
recreatePreprocessor = false
|
||||
}
|
||||
val pp = preprocessor ?: createPreprocessorAndMapping(
|
||||
frameWidth,
|
||||
frameHeight,
|
||||
frameOrientation
|
||||
)
|
||||
val w: Int
|
||||
val h: Int
|
||||
if (rotate) {
|
||||
pp.resizeAndRotate(frameData)
|
||||
w = pp.outHeight
|
||||
h = pp.outWidth
|
||||
} else {
|
||||
invert = invert xor true
|
||||
pp.resizeOnly(frameData)
|
||||
w = pp.outWidth
|
||||
h = pp.outHeight
|
||||
}
|
||||
preprocessor = pp
|
||||
zxing.decode(frameData, w, h, invert)
|
||||
} catch (e: RSRuntimeException) {
|
||||
prefs.forceCompat = prefs.forceCompat xor true
|
||||
// Now the only option is to restart the app because
|
||||
// RenderScript.forceCompat() needs to be called before
|
||||
// RenderScript is initialized.
|
||||
restartApp()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPreprocessorAndMapping(
|
||||
frameWidth: Int,
|
||||
frameHeight: Int,
|
||||
frameOrientation: Int
|
||||
): Preprocessor {
|
||||
val frameRoi = calculateFrameRect(
|
||||
frameWidth,
|
||||
frameHeight,
|
||||
frameOrientation
|
||||
)
|
||||
val pp = Preprocessor(
|
||||
rs,
|
||||
frameWidth,
|
||||
frameHeight,
|
||||
frameRoi
|
||||
)
|
||||
val viewRect = if (frameRoi != null) {
|
||||
detectorView.roi
|
||||
} else {
|
||||
cameraView.previewRect
|
||||
}
|
||||
nativeMappingMatrix = getFrameToViewMatrix(
|
||||
pp.outWidth,
|
||||
pp.outHeight,
|
||||
frameOrientation,
|
||||
viewRect
|
||||
)
|
||||
rotatedMappingMatrix = getFrameToViewMatrix(
|
||||
pp.outHeight,
|
||||
pp.outWidth,
|
||||
(frameOrientation - 90 + 360) % 360,
|
||||
viewRect
|
||||
)
|
||||
return pp
|
||||
}
|
||||
|
||||
private fun calculateFrameRect(
|
||||
frameWidth: Int,
|
||||
frameHeight: Int,
|
||||
frameOrientation: Int
|
||||
): Rect? {
|
||||
val viewRoi = detectorView.roi
|
||||
return if (
|
||||
viewRoi.width() == 0 ||
|
||||
viewRoi.height() == 0
|
||||
) {
|
||||
null
|
||||
} else {
|
||||
// Map ROI in detectorView to cameraView.
|
||||
val previewRect = cameraView.previewRect
|
||||
// previewRect may be larger than the screen (and thus as the
|
||||
// detectorView) in which case its left and/or top coordinate
|
||||
// will be negative which must then be clamped to the
|
||||
// screen/DetectorView.
|
||||
val previewLeft = max(0, previewRect.left)
|
||||
val previewTop = max(0, previewRect.top)
|
||||
val previewRoi = Rect(
|
||||
previewLeft + viewRoi.left,
|
||||
previewTop + viewRoi.top,
|
||||
previewLeft + viewRoi.right,
|
||||
previewTop + viewRoi.bottom
|
||||
)
|
||||
val previewRectWidth = previewRect.width().toFloat()
|
||||
val previewRectHeight = previewRect.height().toFloat()
|
||||
val normalizedRoi = RectF(
|
||||
previewRoi.left.toFloat() / previewRectWidth,
|
||||
previewRoi.top.toFloat() / previewRectHeight,
|
||||
previewRoi.right.toFloat() / previewRectWidth,
|
||||
previewRoi.bottom.toFloat() / previewRectHeight
|
||||
)
|
||||
// Since the ROI is always centered and symmetric, we don't
|
||||
// need to distinguish between 0 and 180 or 90 and 270 degree.
|
||||
val errectedRoi = if (isPortrait(frameOrientation)) {
|
||||
RectF(
|
||||
normalizedRoi.top,
|
||||
normalizedRoi.left,
|
||||
normalizedRoi.bottom,
|
||||
normalizedRoi.right
|
||||
)
|
||||
} else {
|
||||
normalizedRoi
|
||||
}
|
||||
Rect(
|
||||
(errectedRoi.left * frameWidth.toFloat()).roundToInt(),
|
||||
(errectedRoi.top * frameHeight.toFloat()).roundToInt(),
|
||||
(errectedRoi.right * frameWidth.toFloat()).roundToInt(),
|
||||
(errectedRoi.bottom * frameHeight.toFloat()).roundToInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun postResult(result: Result) {
|
||||
// Get matrix for the current rotate value.
|
||||
val matrix = getMappingMatrix()
|
||||
val resultPoints = result.resultPoints
|
||||
if (matrix == null ||
|
||||
resultPoints == null ||
|
||||
resultPoints.isEmpty()
|
||||
) {
|
||||
return
|
||||
}
|
||||
cameraView.post {
|
||||
detectorView.update(
|
||||
matrix.map(
|
||||
resultPoints,
|
||||
matrix.mapPosition(
|
||||
result.position,
|
||||
detectorView.coordinates
|
||||
)
|
||||
)
|
||||
vibrator.vibrate()
|
||||
scanFeedback()
|
||||
val returnUri = returnUrlTemplate?.let {
|
||||
try {
|
||||
completeUrl(it, result)
|
||||
@@ -738,7 +596,6 @@ class CameraActivity : AppCompatActivity() {
|
||||
showResult(
|
||||
this@CameraActivity,
|
||||
result,
|
||||
vibrator,
|
||||
bulkMode
|
||||
)
|
||||
// If this app was invoked via a deep link but without
|
||||
@@ -750,7 +607,9 @@ class CameraActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
if (bulkMode) {
|
||||
ignoreNext = result.text
|
||||
if (prefs.ignoreConsecutiveDuplicates) {
|
||||
ignoreNext = result.text
|
||||
}
|
||||
if (prefs.showToastInBulkMode) {
|
||||
toast(result.text)
|
||||
}
|
||||
@@ -761,12 +620,6 @@ class CameraActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMappingMatrix() = if (rotate) {
|
||||
rotatedMappingMatrix
|
||||
} else {
|
||||
nativeMappingMatrix
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PICK_FILE_RESULT_CODE = 1
|
||||
private const val ZOOM_MAX = "zoom_max"
|
||||
@@ -780,7 +633,6 @@ class CameraActivity : AppCompatActivity() {
|
||||
fun showResult(
|
||||
activity: Activity,
|
||||
result: Result,
|
||||
vibrator: Vibrator,
|
||||
bulkMode: Boolean = false,
|
||||
) {
|
||||
if (prefs.copyImmediately) {
|
||||
@@ -802,10 +654,7 @@ fun showResult(
|
||||
prefs.sendScanType
|
||||
) { code, body ->
|
||||
if (code == null || code < 200 || code > 299) {
|
||||
vibrator.error()
|
||||
if (!activity.isSilent()) {
|
||||
beepBeepBeep()
|
||||
}
|
||||
activity.errorFeedback()
|
||||
}
|
||||
if (body != null && body.isNotEmpty()) {
|
||||
activity.toast(body)
|
||||
@@ -821,45 +670,14 @@ fun showResult(
|
||||
}
|
||||
}
|
||||
|
||||
fun getReturnIntent(result: Result): Intent {
|
||||
val intent = Intent()
|
||||
intent.putExtra("SCAN_RESULT", result.text)
|
||||
intent.putExtra(
|
||||
"SCAN_RESULT_FORMAT",
|
||||
result.barcodeFormat.toString()
|
||||
)
|
||||
if (result.rawBytes?.isNotEmpty() == true) {
|
||||
intent.putExtra("SCAN_RESULT_BYTES", result.rawBytes)
|
||||
private fun getReturnIntent(result: Result) = Intent().apply {
|
||||
putExtra("SCAN_RESULT", result.text)
|
||||
putExtra("SCAN_RESULT_FORMAT", result.format)
|
||||
putExtra("SCAN_RESULT_ORIENTATION", result.orientation)
|
||||
putExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL", result.ecLevel)
|
||||
if (result.rawBytes.isNotEmpty()) {
|
||||
putExtra("SCAN_RESULT_BYTES", result.rawBytes)
|
||||
}
|
||||
result.resultMetadata?.let { metadata ->
|
||||
metadata[ResultMetadataType.ORIENTATION]?.let {
|
||||
intent.putExtra(
|
||||
"SCAN_RESULT_ORIENTATION",
|
||||
it.toString()
|
||||
)
|
||||
}
|
||||
metadata[ResultMetadataType.ERROR_CORRECTION_LEVEL]?.let {
|
||||
intent.putExtra(
|
||||
"SCAN_RESULT_ERROR_CORRECTION_LEVEL",
|
||||
it.toString()
|
||||
)
|
||||
}
|
||||
metadata[ResultMetadataType.UPC_EAN_EXTENSION]?.let {
|
||||
intent.putExtra(
|
||||
"SCAN_RESULT_UPC_EAN_EXTENSION",
|
||||
it.toString()
|
||||
)
|
||||
}
|
||||
metadata[ResultMetadataType.BYTE_SEGMENTS]?.let {
|
||||
var i = 0
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
for (seg in it as Iterable<ByteArray>) {
|
||||
intent.putExtra("SCAN_RESULT_BYTE_SEGMENTS_$i", seg)
|
||||
++i
|
||||
}
|
||||
}
|
||||
}
|
||||
return intent
|
||||
}
|
||||
|
||||
private fun String.isReturnUrl() = listOf(
|
||||
@@ -871,33 +689,10 @@ private fun String.isReturnUrl() = listOf(
|
||||
private fun completeUrl(urlTemplate: String, result: Result) = Uri.parse(
|
||||
urlTemplate
|
||||
.replace("{RESULT}", result.text.urlEncode())
|
||||
.replace("{RESULT_BYTES}", result.rawBytes?.toHexString() ?: "")
|
||||
.replace("{RESULT_BYTES}", result.rawBytes.toHexString())
|
||||
.replace(
|
||||
"{FORMAT}", result.barcodeFormat.toString().urlEncode()
|
||||
)
|
||||
.replace(
|
||||
"{META}", result.resultMetadata?.toString()?.urlEncode() ?: ""
|
||||
"{FORMAT}", result.format.urlEncode()
|
||||
)
|
||||
// And support {CODE} from the old ZXing app, too.
|
||||
.replace("{CODE}", result.text.urlEncode())
|
||||
)
|
||||
|
||||
private fun Context.isSilent(): Boolean {
|
||||
val am = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
return when (am.ringerMode) {
|
||||
AudioManager.RINGER_MODE_SILENT,
|
||||
AudioManager.RINGER_MODE_VIBRATE -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun beepBeepBeep() {
|
||||
ToneGenerator(AudioManager.STREAM_ALARM, 100).startTone(
|
||||
ToneGenerator.TONE_CDMA_CONFIRM,
|
||||
1000
|
||||
)
|
||||
}
|
||||
|
||||
private fun isPortrait(
|
||||
orientation: Int
|
||||
) = orientation == 90 || orientation == 270
|
||||
|
||||
@@ -81,7 +81,7 @@ class MainActivity : AppCompatActivity() {
|
||||
intent.hasExtra(PREFERENCES) -> PreferencesFragment()
|
||||
intent.hasExtra(HISTORY) -> HistoryFragment()
|
||||
intent.hasExtra(ENCODE) -> EncodeFragment.newInstance(
|
||||
intent.getStringExtra(ENCODE)!!
|
||||
intent.getStringExtra(ENCODE)
|
||||
)
|
||||
intent.hasExtra(DECODED) -> DecodeFragment.newInstance(
|
||||
intent.getParcelableExtra(DECODED)!!
|
||||
|
||||
@@ -3,46 +3,52 @@ package de.markusfisch.android.binaryeye.activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.os.Vibrator
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.support.v8.renderscript.RenderScript
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import com.google.zxing.Result
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.app.applyLocale
|
||||
import de.markusfisch.android.binaryeye.app.prefs
|
||||
import de.markusfisch.android.binaryeye.graphics.crop
|
||||
import de.markusfisch.android.binaryeye.graphics.fixTransparency
|
||||
import de.markusfisch.android.binaryeye.graphics.loadImageUri
|
||||
import de.markusfisch.android.binaryeye.graphics.mapResultToView
|
||||
import de.markusfisch.android.binaryeye.os.getVibrator
|
||||
import de.markusfisch.android.binaryeye.os.vibrate
|
||||
import de.markusfisch.android.binaryeye.rs.fixTransparency
|
||||
import de.markusfisch.android.binaryeye.view.colorSystemAndToolBars
|
||||
import de.markusfisch.android.binaryeye.view.initSystemBars
|
||||
import de.markusfisch.android.binaryeye.view.recordToolbarHeight
|
||||
import de.markusfisch.android.binaryeye.view.setPaddingFromWindowInsets
|
||||
import de.markusfisch.android.binaryeye.graphics.mapPosition
|
||||
import de.markusfisch.android.binaryeye.media.releaseToneGenerators
|
||||
import de.markusfisch.android.binaryeye.view.*
|
||||
import de.markusfisch.android.binaryeye.widget.CropImageView
|
||||
import de.markusfisch.android.binaryeye.widget.DetectorView
|
||||
import de.markusfisch.android.binaryeye.widget.toast
|
||||
import de.markusfisch.android.binaryeye.zxing.Zxing
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Binarizer
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.DecodeHints
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Result
|
||||
import kotlinx.coroutines.*
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class PickActivity : AppCompatActivity() {
|
||||
private val zxing = Zxing()
|
||||
private val matrix = Matrix()
|
||||
private val parentJob = Job()
|
||||
private val scope = CoroutineScope(Dispatchers.IO + parentJob)
|
||||
private val decodeHints = DecodeHints(
|
||||
tryHarder = true,
|
||||
tryRotate = true,
|
||||
tryInvert = true,
|
||||
tryDownscale = true,
|
||||
formats = prefs.barcodeFormats.joinToString()
|
||||
)
|
||||
|
||||
private lateinit var rs: RenderScript
|
||||
private lateinit var vibrator: Vibrator
|
||||
private lateinit var cropImageView: CropImageView
|
||||
private lateinit var detectorView: DetectorView
|
||||
private lateinit var freeRotationItem: MenuItem
|
||||
|
||||
private var result: Result? = null
|
||||
|
||||
@@ -59,13 +65,6 @@ class PickActivity : AppCompatActivity() {
|
||||
// locale.
|
||||
setTitle(R.string.pick_code_to_scan)
|
||||
|
||||
zxing.updateHints(
|
||||
true,
|
||||
prefs.barcodeFormats
|
||||
)
|
||||
rs = RenderScript.create(this)
|
||||
vibrator = getVibrator()
|
||||
|
||||
initSystemBars(this)
|
||||
val toolbar = findViewById(R.id.toolbar) as Toolbar
|
||||
recordToolbarHeight(toolbar)
|
||||
@@ -75,7 +74,7 @@ class PickActivity : AppCompatActivity() {
|
||||
colorSystemAndToolBars(this@PickActivity)
|
||||
}
|
||||
|
||||
val bitmap = fixTransparency(rs, getBitmapFromIntent())
|
||||
val bitmap = getBitmapFromIntent()?.fixTransparency()
|
||||
if (bitmap == null) {
|
||||
applicationContext.toast(R.string.error_no_content)
|
||||
finish()
|
||||
@@ -84,6 +83,7 @@ class PickActivity : AppCompatActivity() {
|
||||
|
||||
cropImageView = findViewById(R.id.image) as CropImageView
|
||||
cropImageView.restrictTranslation = false
|
||||
cropImageView.freeRotation = prefs.freeRotation
|
||||
cropImageView.setImageBitmap(bitmap)
|
||||
cropImageView.onScan = {
|
||||
scanWithinBounds(bitmap)
|
||||
@@ -116,38 +116,45 @@ class PickActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun scanWithinBounds(bitmap: Bitmap) {
|
||||
val roi = Rect(detectorView.roi)
|
||||
val rectInView = if (roi.width() < 1) {
|
||||
val viewRoi = if (detectorView.roi.width() < 1) {
|
||||
cropImageView.getBoundsRect()
|
||||
} else {
|
||||
roi
|
||||
detectorView.roi
|
||||
}
|
||||
val imageRect = cropImageView.mappedRect
|
||||
val rectInImage = normalizeRoi(imageRect, rectInView)
|
||||
val mappedRect = cropImageView.mappedRect
|
||||
val cropped = bitmap.crop(
|
||||
rectInImage,
|
||||
cropImageView.imageRotation
|
||||
getNormalizedRoi(mappedRect, viewRoi),
|
||||
cropImageView.imageRotation,
|
||||
cropImageView.pivotX,
|
||||
cropImageView.pivotY
|
||||
) ?: return
|
||||
val croppedInView = Rect(
|
||||
max(viewRoi.left, mappedRect.left.roundToInt()),
|
||||
max(viewRoi.top, mappedRect.top.roundToInt()),
|
||||
min(viewRoi.right, mappedRect.right.roundToInt()),
|
||||
min(viewRoi.bottom, mappedRect.bottom.roundToInt())
|
||||
)
|
||||
matrix.apply {
|
||||
setScale(
|
||||
croppedInView.width().toFloat() / cropped.width,
|
||||
croppedInView.height().toFloat() / cropped.height
|
||||
)
|
||||
postTranslate(
|
||||
croppedInView.left.toFloat(),
|
||||
croppedInView.top.toFloat()
|
||||
)
|
||||
}
|
||||
scope.launch {
|
||||
result = zxing.decodePositiveNegative(cropped)
|
||||
result?.let {
|
||||
cropped.decode()?.let {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (isFinishing) {
|
||||
return@withContext
|
||||
}
|
||||
vibrator.vibrate()
|
||||
val rc = Rect()
|
||||
imageRect.round(rc)
|
||||
if (!rectInView.intersect(rc)) {
|
||||
return@withContext
|
||||
}
|
||||
result = it
|
||||
scanFeedback()
|
||||
detectorView.update(
|
||||
mapResultToView(
|
||||
cropped.width,
|
||||
cropped.height,
|
||||
0,
|
||||
rectInView,
|
||||
it.resultPoints,
|
||||
matrix.mapPosition(
|
||||
it.position,
|
||||
detectorView.coordinates
|
||||
)
|
||||
)
|
||||
@@ -156,15 +163,38 @@ class PickActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
// By default, ZXing uses LOCAL_AVERAGE, but this does not work
|
||||
// well with inverted barcodes on low-contrast backgrounds.
|
||||
private fun Bitmap.decode() = ZxingCpp.readBitmap(
|
||||
this,
|
||||
0, 0,
|
||||
width, height,
|
||||
0,
|
||||
decodeHints.apply {
|
||||
binarizer = Binarizer.LOCAL_AVERAGE
|
||||
}
|
||||
) ?: ZxingCpp.readBitmap(
|
||||
this,
|
||||
0, 0,
|
||||
width, height,
|
||||
0,
|
||||
decodeHints.apply {
|
||||
binarizer = Binarizer.GLOBAL_HISTOGRAM
|
||||
}
|
||||
)
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
detectorView.saveCropHandlePos()
|
||||
rs.destroy()
|
||||
parentJob.cancel()
|
||||
releaseToneGenerators()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.activity_pick, menu)
|
||||
freeRotationItem = menu.findItem(R.id.toggle_free).apply {
|
||||
updateFreeRotationIcon()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -174,10 +204,26 @@ class PickActivity : AppCompatActivity() {
|
||||
rotateClockwise()
|
||||
true
|
||||
}
|
||||
R.id.toggle_free -> {
|
||||
prefs.freeRotation = prefs.freeRotation xor true
|
||||
cropImageView.freeRotation = prefs.freeRotation
|
||||
freeRotationItem.updateFreeRotationIcon()
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MenuItem.updateFreeRotationIcon() {
|
||||
setIcon(
|
||||
if (prefs.freeRotation) {
|
||||
R.drawable.ic_action_rotation_unlocked
|
||||
} else {
|
||||
R.drawable.ic_action_rotation_locked
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun rotateClockwise() {
|
||||
cropImageView.imageRotation = cropImageView.imageRotation + 90 % 360
|
||||
}
|
||||
@@ -197,7 +243,7 @@ class PickActivity : AppCompatActivity() {
|
||||
private fun showResult() {
|
||||
val r = result
|
||||
if (r != null) {
|
||||
showResult(this, r, vibrator)
|
||||
showResult(this, r)
|
||||
finish()
|
||||
} else {
|
||||
applicationContext.toast(R.string.no_barcode_found)
|
||||
@@ -205,7 +251,7 @@ class PickActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun normalizeRoi(imageRect: RectF, roi: Rect): RectF {
|
||||
private fun getNormalizedRoi(imageRect: RectF, roi: Rect): RectF {
|
||||
val w = imageRect.width()
|
||||
val h = imageRect.height()
|
||||
return RectF(
|
||||
|
||||
@@ -3,7 +3,6 @@ package de.markusfisch.android.binaryeye.activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import de.markusfisch.android.binaryeye.app.setRestartCount
|
||||
|
||||
class SplashActivity : AppCompatActivity() {
|
||||
override fun onCreate(state: Bundle?) {
|
||||
@@ -13,7 +12,6 @@ class SplashActivity : AppCompatActivity() {
|
||||
// because that would happen after the app is fully
|
||||
// initialized what is too late.
|
||||
|
||||
intent?.setRestartCount()
|
||||
startActivity(Intent(applicationContext, CameraActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package de.markusfisch.android.binaryeye.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -10,41 +11,71 @@ import android.widget.TextView
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.database.Database
|
||||
import java.text.DateFormat
|
||||
import java.text.ParseException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class ScansAdapter(context: Context, cursor: Cursor) :
|
||||
CursorAdapter(context, cursor, false) {
|
||||
var selectedScanId = 0L
|
||||
var selectedScanPosition = -1
|
||||
|
||||
private val idIndex = cursor.getColumnIndex(Database.SCANS_ID)
|
||||
private val timeIndex = cursor.getColumnIndex(Database.SCANS_DATETIME)
|
||||
private val nameIndex = cursor.getColumnIndex(Database.SCANS_NAME)
|
||||
private val contentIndex = cursor.getColumnIndex(Database.SCANS_CONTENT)
|
||||
private val formatIndex = cursor.getColumnIndex(Database.SCANS_FORMAT)
|
||||
private val selections = mutableMapOf<Long, Int>()
|
||||
private val selectedColor = ContextCompat.getColor(
|
||||
context, R.color.selected_row
|
||||
)
|
||||
|
||||
fun select(id: Long, position: Int) {
|
||||
selectedScanId = id
|
||||
selectedScanPosition = position
|
||||
fun select(view: View, id: Long, position: Int) {
|
||||
view.select(
|
||||
if (selections[id] == null) {
|
||||
selections[id] = position
|
||||
true
|
||||
} else {
|
||||
selections.remove(id)
|
||||
false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun clearSelection() {
|
||||
selectedScanId = 0L
|
||||
selectedScanPosition = -1
|
||||
selections.clear()
|
||||
}
|
||||
|
||||
fun getSelectedContent() = if (selectedScanPosition < 0) {
|
||||
null
|
||||
} else {
|
||||
val cursor = getItem(selectedScanPosition)
|
||||
if (cursor is Cursor) {
|
||||
cursor.getString(contentIndex)
|
||||
} else {
|
||||
null
|
||||
fun forSelection(callback: (Long, Int) -> Unit) {
|
||||
selections.forEach {
|
||||
callback.invoke(it.key, it.value)
|
||||
}
|
||||
}
|
||||
|
||||
fun getSelectedIds(): List<Long> = mutableListOf<Long>().apply {
|
||||
forSelection { id, _ ->
|
||||
add(id)
|
||||
}
|
||||
}
|
||||
|
||||
fun getSelectedContent(separator: String): String {
|
||||
val sb = StringBuilder()
|
||||
forSelection { _, position ->
|
||||
getContent(position)?.let {
|
||||
if (sb.isNotEmpty()) {
|
||||
sb.append(separator)
|
||||
}
|
||||
sb.append(it)
|
||||
}
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
fun getName(
|
||||
position: Int
|
||||
) = (getItem(position) as Cursor?)?.getString(nameIndex)
|
||||
|
||||
fun getContent(
|
||||
position: Int
|
||||
) = (getItem(position) as Cursor?)?.getString(contentIndex)
|
||||
|
||||
override fun newView(
|
||||
context: Context,
|
||||
cursor: Cursor,
|
||||
@@ -78,13 +109,17 @@ class ScansAdapter(context: Context, cursor: Cursor) :
|
||||
)
|
||||
formatView.text = prettifyFormatName(cursor.getString(formatIndex))
|
||||
}
|
||||
// view.isSelected needs to be put on the queue to work.
|
||||
val selected = cursor.getLong(idIndex) == selectedScanId
|
||||
val selected = selections[cursor.getLong(idIndex)] != null
|
||||
view.post {
|
||||
view.isSelected = selected
|
||||
// Needs to be put on the queue to work.
|
||||
view.select(selected)
|
||||
}
|
||||
}
|
||||
|
||||
private fun View.select(selected: Boolean) {
|
||||
setBackgroundColor(if (selected) selectedColor else 0)
|
||||
}
|
||||
|
||||
private fun getViewHolder(
|
||||
view: View
|
||||
): ViewHolder = view.tag as ViewHolder? ?: ViewHolder(
|
||||
@@ -105,11 +140,15 @@ class ScansAdapter(context: Context, cursor: Cursor) :
|
||||
fun prettifyFormatName(format: String) = format.replace("_", " ")
|
||||
|
||||
private fun formatDateTime(rfc: String): String {
|
||||
SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).parse(rfc)?.let {
|
||||
return DateFormat.getDateTimeInstance(
|
||||
DateFormat.LONG,
|
||||
DateFormat.SHORT
|
||||
).format(it)
|
||||
try {
|
||||
SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).parse(rfc)?.let {
|
||||
return DateFormat.getDateTimeInstance(
|
||||
DateFormat.LONG,
|
||||
DateFormat.SHORT
|
||||
).format(it)
|
||||
}
|
||||
} catch (e: ParseException) {
|
||||
// Ignore and fall through.
|
||||
}
|
||||
return rfc
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package de.markusfisch.android.binaryeye.app
|
||||
|
||||
import android.content.Context
|
||||
import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
package de.markusfisch.android.binaryeye.app
|
||||
|
||||
import android.support.multidex.MultiDexApplication;
|
||||
import android.support.v8.renderscript.RenderScript
|
||||
import android.app.Application
|
||||
import de.markusfisch.android.binaryeye.database.Database
|
||||
import de.markusfisch.android.binaryeye.preference.Preferences
|
||||
|
||||
val db = Database()
|
||||
val prefs = Preferences()
|
||||
|
||||
class BinaryEyeApp : MultiDexApplication() {
|
||||
class BinaryEyeApp : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
db.open(this)
|
||||
prefs.init(this)
|
||||
|
||||
if (prefs.forceCompat) {
|
||||
RenderScript.forceCompat()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
package de.markusfisch.android.binaryeye.app
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import java.io.UnsupportedEncodingException
|
||||
import java.net.URLEncoder
|
||||
|
||||
private val nonPrintable = "[\\x00-\\x08\\x0e-\\x1f]".toRegex()
|
||||
fun String.hasNonPrintableCharacters() = nonPrintable.containsMatchIn(this)
|
||||
|
||||
private val nonAlNum = "[^a-zA-Z0-9]".toRegex()
|
||||
private val multipleDots = "[…]+".toRegex()
|
||||
fun String.foldNonAlNum() = replace(nonAlNum, "…")
|
||||
.replace(multipleDots, "…")
|
||||
|
||||
fun String.urlEncode(): String = try {
|
||||
URLEncoder.encode(this, "UTF-8")
|
||||
} catch (e: UnsupportedEncodingException) {
|
||||
this
|
||||
}
|
||||
|
||||
fun String.parseAndNormalizeUri(): Uri = Uri.parse(this).let {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
it.normalizeScheme()
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
fun ByteArray.toHexString() = joinToString("") { "%02X".format(it) }
|
||||
@@ -1,24 +0,0 @@
|
||||
package de.markusfisch.android.binaryeye.app
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import de.markusfisch.android.binaryeye.activity.SplashActivity
|
||||
|
||||
private const val RESTART_COUNT = "restart_count"
|
||||
|
||||
private var restartCount = 0
|
||||
|
||||
fun Intent.setRestartCount() {
|
||||
restartCount = getIntExtra(RESTART_COUNT, restartCount)
|
||||
}
|
||||
|
||||
fun Activity.restartApp() {
|
||||
if (restartCount < 3) {
|
||||
startActivity(Intent(this, SplashActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
putExtra(RESTART_COUNT, ++restartCount)
|
||||
})
|
||||
finish()
|
||||
}
|
||||
Runtime.getRuntime().exit(0)
|
||||
}
|
||||
@@ -1,17 +1,37 @@
|
||||
package de.markusfisch.android.binaryeye.content
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipDescription
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.PersistableBundle
|
||||
|
||||
fun Context.copyToClipboard(text: String) {
|
||||
fun Context.copyToClipboard(text: String, isSensitive: Boolean = false) {
|
||||
val service = getSystemService(Context.CLIPBOARD_SERVICE)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
|
||||
@Suppress("DEPRECATION")
|
||||
(service as android.text.ClipboardManager).text = text
|
||||
} else {
|
||||
(service as android.content.ClipboardManager).setPrimaryClip(
|
||||
ClipData.newPlainText("plain text", text)
|
||||
ClipData.newPlainText("plain text", text).apply {
|
||||
setSensitive(isSensitive)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClipData.setSensitive(isSensitive: Boolean) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
description.extras = PersistableBundle().apply {
|
||||
putBoolean(EXTRA_IS_SENSITIVE, isSensitive)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val EXTRA_IS_SENSITIVE = if (
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
|
||||
) {
|
||||
ClipDescription.EXTRA_IS_SENSITIVE
|
||||
} else {
|
||||
"android.content.extra.IS_SENSITIVE"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
package de.markusfisch.android.binaryeye.content
|
||||
|
||||
fun ByteArray.toHexString() = joinToString("") { "%02X".format(it) }
|
||||
@@ -8,7 +8,6 @@ import android.os.Build
|
||||
import android.support.v4.content.FileProvider
|
||||
import de.markusfisch.android.binaryeye.BuildConfig
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.app.parseAndNormalizeUri
|
||||
import de.markusfisch.android.binaryeye.widget.toast
|
||||
import java.io.File
|
||||
|
||||
@@ -36,11 +35,22 @@ fun Context.startIntent(intent: Intent): Boolean = try {
|
||||
false
|
||||
}
|
||||
|
||||
fun Context.openUrl(url: String): Boolean = openUri(url.parseAndNormalizeUri())
|
||||
fun Context.openUrl(url: String, silent: Boolean = false): Boolean {
|
||||
val intent = Intent(Intent.ACTION_VIEW, url.parseAndNormalizeUri())
|
||||
return if (silent) {
|
||||
startIntent(intent)
|
||||
} else {
|
||||
execShareIntent(intent)
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.openUri(uri: Uri): Boolean = execShareIntent(
|
||||
Intent(Intent.ACTION_VIEW, uri)
|
||||
)
|
||||
fun String.parseAndNormalizeUri(): Uri = Uri.parse(this).let {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
it.normalizeScheme()
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.shareText(text: String, mimeType: String = "text/plain") {
|
||||
execShareIntent(Intent(Intent.ACTION_SEND).apply {
|
||||
|
||||
@@ -2,7 +2,7 @@ package de.markusfisch.android.binaryeye.database
|
||||
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import de.markusfisch.android.binaryeye.app.toHexString
|
||||
import de.markusfisch.android.binaryeye.content.toHexString
|
||||
import de.markusfisch.android.binaryeye.io.writeExternalFile
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.OutputStream
|
||||
@@ -34,13 +34,14 @@ private fun exportCsv(
|
||||
Database.SCANS_FORMAT,
|
||||
Database.SCANS_CONTENT,
|
||||
Database.SCANS_ERROR_CORRECTION_LEVEL,
|
||||
Database.SCANS_ISSUE_NUMBER,
|
||||
Database.SCANS_ORIENTATION,
|
||||
Database.SCANS_OTHER_META_DATA,
|
||||
Database.SCANS_PDF417_EXTRA_METADATA,
|
||||
Database.SCANS_POSSIBLE_COUNTRY,
|
||||
Database.SCANS_SUGGESTED_PRICE,
|
||||
Database.SCANS_UPC_EAN_EXTENSION
|
||||
Database.SCANS_VERSION,
|
||||
Database.SCANS_SEQUENCE_SIZE,
|
||||
Database.SCANS_SEQUENCE_INDEX,
|
||||
Database.SCANS_SEQUENCE_ID,
|
||||
Database.SCANS_GTIN_COUNTRY,
|
||||
Database.SCANS_GTIN_ADD_ON,
|
||||
Database.SCANS_GTIN_PRICE,
|
||||
Database.SCANS_GTIN_ISSUE_NUMBER
|
||||
)
|
||||
val indices = columns.map {
|
||||
cursor.getColumnIndex(it)
|
||||
|
||||
@@ -2,6 +2,25 @@ package de.markusfisch.android.binaryeye.database
|
||||
|
||||
import android.database.Cursor
|
||||
|
||||
// Overwrite Kotlin's ".use" function for Cursor because Cursor cannot
|
||||
// be cast to Closeable below API level 16. This should be removed when
|
||||
// the minSDK is increased to at least JELLY_BEAN (16).
|
||||
inline fun <R> Cursor.use(block: (Cursor) -> R): R = try {
|
||||
block.invoke(this)
|
||||
} finally {
|
||||
close()
|
||||
}
|
||||
|
||||
fun Cursor.getInt(name: String): Int {
|
||||
val idx = getColumnIndex(name)
|
||||
return if (idx < 0) 0 else getInt(idx)
|
||||
}
|
||||
|
||||
fun Cursor.getLong(name: String): Long {
|
||||
val idx = getColumnIndex(name)
|
||||
return if (idx < 0) 0L else getLong(idx)
|
||||
}
|
||||
|
||||
fun Cursor.getString(name: String): String {
|
||||
val idx = getColumnIndex(name)
|
||||
return if (idx < 0) "" else getString(idx) ?: ""
|
||||
@@ -11,8 +30,3 @@ fun Cursor.getBlob(name: String): ByteArray? {
|
||||
val idx = getColumnIndex(name)
|
||||
return if (idx < 0) null else getBlob(idx)
|
||||
}
|
||||
|
||||
fun Cursor.getLong(name: String): Long {
|
||||
val idx = getColumnIndex(name)
|
||||
return if (idx < 0) 0L else getLong(idx)
|
||||
}
|
||||
|
||||
@@ -36,13 +36,14 @@ class Database {
|
||||
$SCANS_RAW,
|
||||
$SCANS_FORMAT,
|
||||
$SCANS_ERROR_CORRECTION_LEVEL,
|
||||
$SCANS_ISSUE_NUMBER,
|
||||
$SCANS_ORIENTATION,
|
||||
$SCANS_OTHER_META_DATA,
|
||||
$SCANS_PDF417_EXTRA_METADATA,
|
||||
$SCANS_POSSIBLE_COUNTRY,
|
||||
$SCANS_SUGGESTED_PRICE,
|
||||
$SCANS_UPC_EAN_EXTENSION
|
||||
$SCANS_VERSION,
|
||||
$SCANS_SEQUENCE_SIZE,
|
||||
$SCANS_SEQUENCE_INDEX,
|
||||
$SCANS_SEQUENCE_ID,
|
||||
$SCANS_GTIN_COUNTRY,
|
||||
$SCANS_GTIN_ADD_ON,
|
||||
$SCANS_GTIN_PRICE,
|
||||
$SCANS_GTIN_ISSUE_NUMBER
|
||||
FROM $SCANS
|
||||
${getWhereClause(query)}
|
||||
ORDER BY $SCANS_DATETIME DESC
|
||||
@@ -77,13 +78,14 @@ class Database {
|
||||
$SCANS_RAW,
|
||||
$SCANS_FORMAT,
|
||||
$SCANS_ERROR_CORRECTION_LEVEL,
|
||||
$SCANS_ISSUE_NUMBER,
|
||||
$SCANS_ORIENTATION,
|
||||
$SCANS_OTHER_META_DATA,
|
||||
$SCANS_PDF417_EXTRA_METADATA,
|
||||
$SCANS_POSSIBLE_COUNTRY,
|
||||
$SCANS_SUGGESTED_PRICE,
|
||||
$SCANS_UPC_EAN_EXTENSION
|
||||
$SCANS_VERSION,
|
||||
$SCANS_SEQUENCE_SIZE,
|
||||
$SCANS_SEQUENCE_INDEX,
|
||||
$SCANS_SEQUENCE_ID,
|
||||
$SCANS_GTIN_COUNTRY,
|
||||
$SCANS_GTIN_ADD_ON,
|
||||
$SCANS_GTIN_PRICE,
|
||||
$SCANS_GTIN_ISSUE_NUMBER
|
||||
FROM $SCANS
|
||||
WHERE $SCANS_ID = ?
|
||||
""".trimMargin(), arrayOf("$id")
|
||||
@@ -94,13 +96,14 @@ class Database {
|
||||
it.getBlob(SCANS_RAW),
|
||||
it.getString(SCANS_FORMAT),
|
||||
it.getString(SCANS_ERROR_CORRECTION_LEVEL),
|
||||
it.getString(SCANS_ISSUE_NUMBER),
|
||||
it.getString(SCANS_ORIENTATION),
|
||||
it.getString(SCANS_OTHER_META_DATA),
|
||||
it.getString(SCANS_PDF417_EXTRA_METADATA),
|
||||
it.getString(SCANS_POSSIBLE_COUNTRY),
|
||||
it.getString(SCANS_SUGGESTED_PRICE),
|
||||
it.getString(SCANS_UPC_EAN_EXTENSION),
|
||||
it.getString(SCANS_VERSION),
|
||||
it.getInt(SCANS_SEQUENCE_SIZE),
|
||||
it.getInt(SCANS_SEQUENCE_INDEX),
|
||||
it.getString(SCANS_SEQUENCE_ID),
|
||||
it.getString(SCANS_GTIN_COUNTRY),
|
||||
it.getString(SCANS_GTIN_ADD_ON),
|
||||
it.getString(SCANS_GTIN_PRICE),
|
||||
it.getString(SCANS_GTIN_ISSUE_NUMBER),
|
||||
it.getString(SCANS_DATETIME),
|
||||
it.getLong(SCANS_ID)
|
||||
)
|
||||
@@ -125,13 +128,14 @@ class Database {
|
||||
scan.errorCorrectionLevel?.let {
|
||||
put(SCANS_ERROR_CORRECTION_LEVEL, it)
|
||||
}
|
||||
scan.issueNumber?.let { put(SCANS_ISSUE_NUMBER, it) }
|
||||
scan.orientation?.let { put(SCANS_ORIENTATION, it) }
|
||||
scan.otherMetaData?.let { put(SCANS_OTHER_META_DATA, it) }
|
||||
scan.pdf417ExtraMetaData?.let { put(SCANS_PDF417_EXTRA_METADATA, it) }
|
||||
scan.possibleCountry?.let { put(SCANS_POSSIBLE_COUNTRY, it) }
|
||||
scan.suggestedPrice?.let { put(SCANS_SUGGESTED_PRICE, it) }
|
||||
scan.upcEanExtension?.let { put(SCANS_UPC_EAN_EXTENSION, it) }
|
||||
put(SCANS_VERSION, scan.version)
|
||||
put(SCANS_SEQUENCE_SIZE, scan.sequenceSize)
|
||||
put(SCANS_SEQUENCE_INDEX, scan.sequenceIndex)
|
||||
put(SCANS_SEQUENCE_ID, scan.sequenceId)
|
||||
scan.country?.let { put(SCANS_GTIN_COUNTRY, it) }
|
||||
scan.addOn?.let { put(SCANS_GTIN_ADD_ON, it) }
|
||||
scan.price?.let { put(SCANS_GTIN_PRICE, it) }
|
||||
scan.issueNumber?.let { put(SCANS_GTIN_ISSUE_NUMBER, it) }
|
||||
if (prefs.ignoreConsecutiveDuplicates) {
|
||||
val id = getIdOfLastScan(
|
||||
get(SCANS_CONTENT) as String,
|
||||
@@ -188,9 +192,9 @@ class Database {
|
||||
}
|
||||
|
||||
private class OpenHelper(context: Context) :
|
||||
SQLiteOpenHelper(context, FILE_NAME, null, 4) {
|
||||
SQLiteOpenHelper(context, FILE_NAME, null, 6) {
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
createScans(db)
|
||||
db.createScans()
|
||||
}
|
||||
|
||||
override fun onUpgrade(
|
||||
@@ -199,13 +203,19 @@ class Database {
|
||||
newVersion: Int
|
||||
) {
|
||||
if (oldVersion < 2) {
|
||||
addRawColumn(db)
|
||||
db.addRawColumn()
|
||||
}
|
||||
if (oldVersion < 3) {
|
||||
addMetaDataColumns(db)
|
||||
db.addMetaDataColumns()
|
||||
}
|
||||
if (oldVersion < 4) {
|
||||
addNameColumn(db)
|
||||
db.addNameColumn()
|
||||
}
|
||||
if (oldVersion < 5) {
|
||||
db.migrateToZxingCpp()
|
||||
}
|
||||
if (oldVersion < 6) {
|
||||
db.migrateToVersionString()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,6 +230,8 @@ class Database {
|
||||
const val SCANS_RAW = "raw"
|
||||
const val SCANS_FORMAT = "format"
|
||||
const val SCANS_ERROR_CORRECTION_LEVEL = "error_correction_level"
|
||||
const val SCANS_VERSION_NUMBER = "version_number"
|
||||
const val SCANS_VERSION = "version"
|
||||
const val SCANS_ISSUE_NUMBER = "issue_number"
|
||||
const val SCANS_ORIENTATION = "orientation"
|
||||
const val SCANS_OTHER_META_DATA = "other_meta_data"
|
||||
@@ -227,10 +239,17 @@ class Database {
|
||||
const val SCANS_POSSIBLE_COUNTRY = "possible_country"
|
||||
const val SCANS_SUGGESTED_PRICE = "suggested_price"
|
||||
const val SCANS_UPC_EAN_EXTENSION = "upc_ean_extension"
|
||||
const val SCANS_SEQUENCE_SIZE = "sequence_size"
|
||||
const val SCANS_SEQUENCE_INDEX = "sequence_index"
|
||||
const val SCANS_SEQUENCE_ID = "sequence_id"
|
||||
const val SCANS_GTIN_COUNTRY = "gtin_country"
|
||||
const val SCANS_GTIN_ADD_ON = "gtin_add_on"
|
||||
const val SCANS_GTIN_PRICE = "gtin_price"
|
||||
const val SCANS_GTIN_ISSUE_NUMBER = "gtin_issue_number"
|
||||
|
||||
private fun createScans(db: SQLiteDatabase) {
|
||||
db.execSQL("DROP TABLE IF EXISTS $SCANS".trimMargin())
|
||||
db.execSQL(
|
||||
private fun SQLiteDatabase.createScans() {
|
||||
execSQL("DROP TABLE IF EXISTS $SCANS".trimMargin())
|
||||
execSQL(
|
||||
"""CREATE TABLE $SCANS (
|
||||
$SCANS_ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
$SCANS_DATETIME DATETIME NOT NULL,
|
||||
@@ -239,36 +258,57 @@ class Database {
|
||||
$SCANS_RAW BLOB,
|
||||
$SCANS_FORMAT TEXT NOT NULL,
|
||||
$SCANS_ERROR_CORRECTION_LEVEL TEXT,
|
||||
$SCANS_ISSUE_NUMBER INT,
|
||||
$SCANS_ORIENTATION INT,
|
||||
$SCANS_OTHER_META_DATA TEXT,
|
||||
$SCANS_PDF417_EXTRA_METADATA TEXT,
|
||||
$SCANS_POSSIBLE_COUNTRY TEXT,
|
||||
$SCANS_SUGGESTED_PRICE TEXT,
|
||||
$SCANS_UPC_EAN_EXTENSION TEXT
|
||||
$SCANS_VERSION TEXT,
|
||||
$SCANS_SEQUENCE_SIZE INTEGER,
|
||||
$SCANS_SEQUENCE_INDEX INTEGER,
|
||||
$SCANS_SEQUENCE_ID TEXT,
|
||||
$SCANS_GTIN_COUNTRY TEXT,
|
||||
$SCANS_GTIN_ADD_ON TEXT,
|
||||
$SCANS_GTIN_PRICE TEXT,
|
||||
$SCANS_GTIN_ISSUE_NUMBER TEXT
|
||||
)""".trimMargin()
|
||||
)
|
||||
}
|
||||
|
||||
private fun addRawColumn(db: SQLiteDatabase) {
|
||||
db.execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_RAW BLOB".trimMargin())
|
||||
private fun SQLiteDatabase.addRawColumn() {
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_RAW BLOB".trimMargin())
|
||||
}
|
||||
|
||||
private fun addMetaDataColumns(db: SQLiteDatabase) {
|
||||
db.apply {
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_ERROR_CORRECTION_LEVEL TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_ISSUE_NUMBER INT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_ORIENTATION INT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_OTHER_META_DATA TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_PDF417_EXTRA_METADATA TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_POSSIBLE_COUNTRY TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_SUGGESTED_PRICE TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_UPC_EAN_EXTENSION TEXT".trimMargin())
|
||||
}
|
||||
private fun SQLiteDatabase.addMetaDataColumns() {
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_ERROR_CORRECTION_LEVEL TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_ISSUE_NUMBER INT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_ORIENTATION INT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_OTHER_META_DATA TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_PDF417_EXTRA_METADATA TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_POSSIBLE_COUNTRY TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_SUGGESTED_PRICE TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_UPC_EAN_EXTENSION TEXT".trimMargin())
|
||||
}
|
||||
|
||||
private fun addNameColumn(db: SQLiteDatabase) {
|
||||
db.execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_NAME TEXT".trimMargin())
|
||||
private fun SQLiteDatabase.addNameColumn() {
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_NAME TEXT".trimMargin())
|
||||
}
|
||||
|
||||
private fun SQLiteDatabase.migrateToZxingCpp() {
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_VERSION_NUMBER INTEGER".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_SEQUENCE_SIZE INTEGER".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_SEQUENCE_INDEX INTEGER".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_SEQUENCE_ID TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_GTIN_COUNTRY TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_GTIN_ADD_ON TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_GTIN_PRICE TEXT".trimMargin())
|
||||
execSQL("ALTER TABLE $SCANS ADD COLUMN $SCANS_GTIN_ISSUE_NUMBER TEXT".trimMargin())
|
||||
execSQL("UPDATE $SCANS SET $SCANS_SEQUENCE_SIZE = -1")
|
||||
execSQL("UPDATE $SCANS SET $SCANS_SEQUENCE_INDEX = -1")
|
||||
execSQL("UPDATE $SCANS SET $SCANS_GTIN_COUNTRY = $SCANS_POSSIBLE_COUNTRY")
|
||||
execSQL("UPDATE $SCANS SET $SCANS_GTIN_ADD_ON = $SCANS_UPC_EAN_EXTENSION")
|
||||
execSQL("UPDATE $SCANS SET $SCANS_GTIN_PRICE = $SCANS_SUGGESTED_PRICE")
|
||||
execSQL("UPDATE $SCANS SET $SCANS_GTIN_ISSUE_NUMBER = $SCANS_ISSUE_NUMBER")
|
||||
}
|
||||
|
||||
private fun SQLiteDatabase.migrateToVersionString() {
|
||||
execSQL("ALTER TABLE $SCANS ADD $SCANS_VERSION TEXT")
|
||||
execSQL("UPDATE $SCANS SET $SCANS_VERSION = $SCANS_VERSION_NUMBER")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package de.markusfisch.android.binaryeye.database
|
||||
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import de.markusfisch.android.binaryeye.app.toHexString
|
||||
import de.markusfisch.android.binaryeye.content.toHexString
|
||||
import de.markusfisch.android.binaryeye.io.writeExternalFile
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
@@ -26,13 +26,14 @@ fun Cursor.exportJson(): String? {
|
||||
Database.SCANS_FORMAT,
|
||||
Database.SCANS_CONTENT,
|
||||
Database.SCANS_ERROR_CORRECTION_LEVEL,
|
||||
Database.SCANS_ISSUE_NUMBER,
|
||||
Database.SCANS_ORIENTATION,
|
||||
Database.SCANS_OTHER_META_DATA,
|
||||
Database.SCANS_PDF417_EXTRA_METADATA,
|
||||
Database.SCANS_POSSIBLE_COUNTRY,
|
||||
Database.SCANS_SUGGESTED_PRICE,
|
||||
Database.SCANS_UPC_EAN_EXTENSION
|
||||
Database.SCANS_VERSION,
|
||||
Database.SCANS_SEQUENCE_SIZE,
|
||||
Database.SCANS_SEQUENCE_INDEX,
|
||||
Database.SCANS_SEQUENCE_ID,
|
||||
Database.SCANS_GTIN_COUNTRY,
|
||||
Database.SCANS_GTIN_ADD_ON,
|
||||
Database.SCANS_GTIN_PRICE,
|
||||
Database.SCANS_GTIN_ISSUE_NUMBER
|
||||
)
|
||||
val indices = columns.map {
|
||||
Pair(getColumnIndex(it), it)
|
||||
|
||||
@@ -1,29 +1,33 @@
|
||||
package de.markusfisch.android.binaryeye.database
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import android.text.format.DateFormat
|
||||
import com.google.zxing.Result
|
||||
import com.google.zxing.ResultMetadataType
|
||||
import de.markusfisch.android.binaryeye.app.hasNonPrintableCharacters
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.ContentType
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Format
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Result
|
||||
|
||||
data class Scan(
|
||||
val content: String,
|
||||
val raw: ByteArray?,
|
||||
val format: String,
|
||||
val errorCorrectionLevel: String?,
|
||||
val issueNumber: String?,
|
||||
val orientation: String?,
|
||||
val otherMetaData: String?,
|
||||
val pdf417ExtraMetaData: String?,
|
||||
val possibleCountry: String?,
|
||||
val suggestedPrice: String?,
|
||||
val upcEanExtension: String?,
|
||||
val errorCorrectionLevel: String? = null,
|
||||
val version: String? = null,
|
||||
val sequenceSize: Int = -1,
|
||||
val sequenceIndex: Int = -1,
|
||||
val sequenceId: String = "",
|
||||
val country: String? = null,
|
||||
val addOn: String? = null,
|
||||
val price: String? = null,
|
||||
val issueNumber: String? = null,
|
||||
val dateTime: String = getDateTime(),
|
||||
var id: Long = 0L
|
||||
) : Parcelable {
|
||||
// Needs to be overwritten manually, as ByteArray is an array and
|
||||
// this isn't handled well by Kotlin
|
||||
// this isn't handled well by Kotlin.
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) {
|
||||
return true
|
||||
@@ -41,17 +45,18 @@ data class Scan(
|
||||
(raw != null && other.raw != null && raw.contentEquals(other.raw))) &&
|
||||
format == other.format &&
|
||||
errorCorrectionLevel == other.errorCorrectionLevel &&
|
||||
issueNumber == other.issueNumber &&
|
||||
orientation == other.orientation &&
|
||||
otherMetaData == other.otherMetaData &&
|
||||
pdf417ExtraMetaData == other.pdf417ExtraMetaData &&
|
||||
possibleCountry == other.possibleCountry &&
|
||||
suggestedPrice == other.suggestedPrice &&
|
||||
upcEanExtension == other.upcEanExtension
|
||||
version == other.version &&
|
||||
sequenceSize == other.sequenceSize &&
|
||||
sequenceIndex == other.sequenceIndex &&
|
||||
sequenceId == other.sequenceId &&
|
||||
country == other.country &&
|
||||
addOn == other.addOn &&
|
||||
price == other.price &&
|
||||
issueNumber == other.issueNumber
|
||||
}
|
||||
|
||||
// Needs to be overwritten manually, as ByteArray is an array and
|
||||
// this isn't handled well by Kotlin
|
||||
// this isn't handled well by Kotlin.
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + dateTime.hashCode()
|
||||
@@ -59,13 +64,14 @@ data class Scan(
|
||||
result = 31 * result + (raw?.contentHashCode() ?: 0)
|
||||
result = 31 * result + format.hashCode()
|
||||
result = 31 * result + (errorCorrectionLevel?.hashCode() ?: 0)
|
||||
result = 31 * result + version.hashCode()
|
||||
result = 31 * result + sequenceSize
|
||||
result = 31 * result + sequenceIndex
|
||||
result = 31 * result + sequenceId.hashCode()
|
||||
result = 31 * result + (country?.hashCode() ?: 0)
|
||||
result = 31 * result + (addOn?.hashCode() ?: 0)
|
||||
result = 31 * result + (price?.hashCode() ?: 0)
|
||||
result = 31 * result + (issueNumber?.hashCode() ?: 0)
|
||||
result = 31 * result + (orientation?.hashCode() ?: 0)
|
||||
result = 31 * result + (otherMetaData?.hashCode() ?: 0)
|
||||
result = 31 * result + (pdf417ExtraMetaData?.hashCode() ?: 0)
|
||||
result = 31 * result + (possibleCountry?.hashCode() ?: 0)
|
||||
result = 31 * result + (suggestedPrice?.hashCode() ?: 0)
|
||||
result = 31 * result + (upcEanExtension?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -74,13 +80,14 @@ data class Scan(
|
||||
raw = parcel.readSizedByteArray(),
|
||||
format = parcel.readString() ?: "",
|
||||
errorCorrectionLevel = parcel.readString(),
|
||||
version = parcel.readString(),
|
||||
sequenceSize = parcel.readInt(),
|
||||
sequenceIndex = parcel.readInt(),
|
||||
sequenceId = parcel.readString() ?: "",
|
||||
country = parcel.readString(),
|
||||
addOn = parcel.readString(),
|
||||
price = parcel.readString(),
|
||||
issueNumber = parcel.readString(),
|
||||
orientation = parcel.readString(),
|
||||
otherMetaData = parcel.readString(),
|
||||
pdf417ExtraMetaData = parcel.readString(),
|
||||
possibleCountry = parcel.readString(),
|
||||
suggestedPrice = parcel.readString(),
|
||||
upcEanExtension = parcel.readString(),
|
||||
dateTime = parcel.readString() ?: "",
|
||||
id = parcel.readLong()
|
||||
)
|
||||
@@ -91,13 +98,14 @@ data class Scan(
|
||||
writeSizedByteArray(raw)
|
||||
writeString(format)
|
||||
writeString(errorCorrectionLevel)
|
||||
writeString(version)
|
||||
writeInt(sequenceSize)
|
||||
writeInt(sequenceIndex)
|
||||
writeString(sequenceId)
|
||||
writeString(country)
|
||||
writeString(addOn)
|
||||
writeString(price)
|
||||
writeString(issueNumber)
|
||||
writeString(orientation)
|
||||
writeString(otherMetaData)
|
||||
writeString(pdf417ExtraMetaData)
|
||||
writeString(possibleCountry)
|
||||
writeString(suggestedPrice)
|
||||
writeString(upcEanExtension)
|
||||
writeString(dateTime)
|
||||
writeLong(id)
|
||||
}
|
||||
@@ -114,8 +122,82 @@ data class Scan(
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDateTime(time: Long = System.currentTimeMillis()) = DateFormat.format(
|
||||
"yyyy-MM-dd HH:mm:ss",
|
||||
fun Result.toScan(): Scan {
|
||||
val content: String
|
||||
val raw: ByteArray?
|
||||
when (contentType) {
|
||||
ContentType.GS1,
|
||||
ContentType.ISO15434,
|
||||
ContentType.TEXT -> {
|
||||
content = text
|
||||
raw = null
|
||||
}
|
||||
else -> {
|
||||
content = ""
|
||||
raw = rawBytes
|
||||
}
|
||||
}
|
||||
return Scan(
|
||||
content,
|
||||
raw,
|
||||
format,
|
||||
ecLevel,
|
||||
version,
|
||||
sequenceSize,
|
||||
sequenceIndex,
|
||||
sequenceId,
|
||||
gtin?.country,
|
||||
gtin?.addOn,
|
||||
gtin?.price,
|
||||
gtin?.issueNumber
|
||||
)
|
||||
}
|
||||
|
||||
data class Recreation(
|
||||
val format: Format,
|
||||
val ecLevel: Int,
|
||||
val size: Int,
|
||||
val margin: Int
|
||||
) {
|
||||
fun encode(content: String): Bitmap? = try {
|
||||
ZxingCpp.encodeAsBitmap(
|
||||
content, format, size, size, margin, ecLevel
|
||||
)
|
||||
} catch (_: RuntimeException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun Scan.toRecreation(
|
||||
size: Int = 128,
|
||||
margin: Int = -1
|
||||
) = if (content.isEmpty()) {
|
||||
null
|
||||
} else {
|
||||
Recreation(
|
||||
Format.valueOf(format),
|
||||
when (errorCorrectionLevel) {
|
||||
"L" -> 0
|
||||
"M" -> 1
|
||||
"Q" -> 2
|
||||
"H" -> 3
|
||||
else -> -1
|
||||
},
|
||||
size,
|
||||
margin
|
||||
)
|
||||
}
|
||||
|
||||
private fun getDateTime(
|
||||
time: Long = System.currentTimeMillis()
|
||||
) = DateFormat.format(
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
// Up to API level 17, 'k' was interpreted as 'H', which wasn't
|
||||
// implemented until API level 18.
|
||||
"yyyy-MM-dd kk:mm:ss"
|
||||
} else {
|
||||
"yyyy-MM-dd HH:mm:ss"
|
||||
},
|
||||
time
|
||||
).toString()
|
||||
|
||||
@@ -137,51 +219,3 @@ private fun Parcel.readSizedByteArray(): ByteArray? {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun Result.toScan(): Scan {
|
||||
val content: String
|
||||
val raw: ByteArray?
|
||||
if (text.hasNonPrintableCharacters()) {
|
||||
content = ""
|
||||
raw = getRawData() ?: text.toByteArray()
|
||||
} else {
|
||||
content = text
|
||||
raw = null
|
||||
}
|
||||
return Scan(
|
||||
content,
|
||||
raw,
|
||||
barcodeFormat.toString(),
|
||||
getMetaString(ResultMetadataType.ERROR_CORRECTION_LEVEL),
|
||||
getMetaString(ResultMetadataType.ISSUE_NUMBER),
|
||||
getMetaString(ResultMetadataType.ORIENTATION),
|
||||
getMetaString(ResultMetadataType.OTHER),
|
||||
getMetaString(ResultMetadataType.PDF417_EXTRA_METADATA),
|
||||
getMetaString(ResultMetadataType.POSSIBLE_COUNTRY),
|
||||
getMetaString(ResultMetadataType.SUGGESTED_PRICE),
|
||||
getMetaString(ResultMetadataType.UPC_EAN_EXTENSION)
|
||||
)
|
||||
}
|
||||
|
||||
private fun Result.getRawData(): ByteArray? {
|
||||
val metadata = resultMetadata ?: return null
|
||||
val segments = metadata[ResultMetadataType.BYTE_SEGMENTS] ?: return null
|
||||
var bytes = ByteArray(0)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
for (seg in segments as Iterable<ByteArray>) {
|
||||
bytes += seg
|
||||
}
|
||||
// If the byte segments are shorter than the converted string, the
|
||||
// content of the QR Code has been encoded with different encoding
|
||||
// modes (e.g. some parts in alphanumeric, some in byte encoding).
|
||||
// This is because Zxing only records byte segments for byte encoded
|
||||
// parts. Please note the byte segments can actually be longer than
|
||||
// the string because Zxing cuts off prefixes like "WIFI:".
|
||||
return if (bytes.size >= text.length) bytes else null
|
||||
}
|
||||
|
||||
private fun Result.getMetaString(
|
||||
key: ResultMetadataType
|
||||
): String? = this.resultMetadata?.let {
|
||||
it[key]?.toString()
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@ import android.os.Bundle
|
||||
import android.support.v4.app.Fragment
|
||||
import android.view.*
|
||||
import android.widget.EditText
|
||||
import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.EncodeHintType
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.app.hasWritePermission
|
||||
import de.markusfisch.android.binaryeye.content.copyToClipboard
|
||||
import de.markusfisch.android.binaryeye.content.shareFile
|
||||
import de.markusfisch.android.binaryeye.content.shareText
|
||||
import de.markusfisch.android.binaryeye.graphics.COLOR_BLACK
|
||||
import de.markusfisch.android.binaryeye.graphics.COLOR_WHITE
|
||||
import de.markusfisch.android.binaryeye.io.addSuffixIfNotGiven
|
||||
import de.markusfisch.android.binaryeye.io.toSaveResult
|
||||
import de.markusfisch.android.binaryeye.io.writeExternalFile
|
||||
@@ -23,15 +23,15 @@ import de.markusfisch.android.binaryeye.view.doOnApplyWindowInsets
|
||||
import de.markusfisch.android.binaryeye.view.setPaddingFromWindowInsets
|
||||
import de.markusfisch.android.binaryeye.widget.ConfinedScalingImageView
|
||||
import de.markusfisch.android.binaryeye.widget.toast
|
||||
import de.markusfisch.android.binaryeye.zxing.encodeAsBitmap
|
||||
import de.markusfisch.android.binaryeye.zxing.encodeAsSvg
|
||||
import de.markusfisch.android.binaryeye.zxing.encodeAsText
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Format
|
||||
import kotlinx.coroutines.*
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.OutputStream
|
||||
import java.util.*
|
||||
import kotlin.math.min
|
||||
|
||||
class BarcodeFragment : Fragment() {
|
||||
private enum class FileType {
|
||||
@@ -41,11 +41,7 @@ class BarcodeFragment : Fragment() {
|
||||
private val parentJob = Job()
|
||||
private val scope = CoroutineScope(Dispatchers.IO + parentJob)
|
||||
|
||||
private var barcodeBitmap: Bitmap? = null
|
||||
private var barcodeSvg: String? = null
|
||||
private var barcodeTxt: String? = null
|
||||
private var content: String = ""
|
||||
private var format: BarcodeFormat? = null
|
||||
private lateinit var barcode: Barcode
|
||||
|
||||
override fun onCreate(state: Bundle?) {
|
||||
super.onCreate(state)
|
||||
@@ -66,15 +62,13 @@ class BarcodeFragment : Fragment() {
|
||||
false
|
||||
)
|
||||
|
||||
val args = arguments ?: return view
|
||||
val content = args.getString(CONTENT) ?: return view
|
||||
val format = args.getSerializable(FORMAT) as BarcodeFormat? ?: return view
|
||||
val hints = args.getSerializable(HINTS) as EnumMap<EncodeHintType, Any>?
|
||||
val size = args.getInt(SIZE)
|
||||
val bitmap: Bitmap
|
||||
try {
|
||||
barcodeBitmap = encodeAsBitmap(content, format, size, size, hints)
|
||||
barcodeSvg = encodeAsSvg(content, format, hints)
|
||||
barcodeTxt = encodeAsText(content, format, hints)
|
||||
barcode = arguments?.toBarcode() ?: throw IllegalArgumentException(
|
||||
"Illegal arguments"
|
||||
)
|
||||
// Catch exceptions from encoding.
|
||||
bitmap = barcode.bitmap()
|
||||
} catch (e: Exception) {
|
||||
var message = e.message
|
||||
if (message == null || message.isEmpty()) {
|
||||
@@ -86,16 +80,17 @@ class BarcodeFragment : Fragment() {
|
||||
fragmentManager.popBackStack()
|
||||
return null
|
||||
}
|
||||
this.content = content
|
||||
this.format = format
|
||||
|
||||
val imageView = view.findViewById<ConfinedScalingImageView>(
|
||||
R.id.barcode
|
||||
)
|
||||
imageView.setImageBitmap(barcodeBitmap)
|
||||
imageView.setImageBitmap(bitmap)
|
||||
imageView.post {
|
||||
// Make sure to invoke this after ScalingImageView.onLayout().
|
||||
imageView.minWidth /= 2f
|
||||
imageView.minWidth = min(
|
||||
imageView.minWidth / 2f,
|
||||
barcode.size.toFloat()
|
||||
)
|
||||
}
|
||||
|
||||
view.findViewById<View>(R.id.share).setOnClickListener {
|
||||
@@ -114,6 +109,20 @@ class BarcodeFragment : Fragment() {
|
||||
return view
|
||||
}
|
||||
|
||||
private fun Bundle.toBarcode() = Barcode(
|
||||
getString(CONTENT) ?: throw IllegalArgumentException(
|
||||
"content cannot be null"
|
||||
),
|
||||
Format.valueOf(
|
||||
getString(FORMAT) ?: throw IllegalArgumentException(
|
||||
"format cannot be null"
|
||||
)
|
||||
),
|
||||
getInt(SIZE),
|
||||
getInt(EC_LEVEL),
|
||||
Colors.values()[getInt(COLORS)]
|
||||
)
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
parentJob.cancel()
|
||||
@@ -126,9 +135,9 @@ class BarcodeFragment : Fragment() {
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.copy_to_clipboard -> {
|
||||
barcodeTxt?.let {
|
||||
context.copyToClipboard(it)
|
||||
context.toast(R.string.copied_to_clipboard)
|
||||
context.apply {
|
||||
copyToClipboard(barcode.text())
|
||||
toast(R.string.copied_to_clipboard)
|
||||
}
|
||||
true
|
||||
}
|
||||
@@ -167,7 +176,9 @@ class BarcodeFragment : Fragment() {
|
||||
}
|
||||
val view = ac.layoutInflater.inflate(R.layout.dialog_save_file, null)
|
||||
val editText = view.findViewById<EditText>(R.id.file_name)
|
||||
editText.setText(encodeFileName("${format.toString()}_$content"))
|
||||
editText.setText(
|
||||
encodeFileName("${barcode.format}_${barcode.content}")
|
||||
)
|
||||
AlertDialog.Builder(ac)
|
||||
.setView(view)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
@@ -177,23 +188,19 @@ class BarcodeFragment : Fragment() {
|
||||
addSuffixIfNotGiven(fileName, ".png"),
|
||||
MIME_PNG
|
||||
) {
|
||||
barcodeBitmap?.saveAsPng(it)
|
||||
barcode.bitmap().saveAsPng(it)
|
||||
}
|
||||
FileType.SVG -> saveAs(
|
||||
addSuffixIfNotGiven(fileName, ".svg"),
|
||||
MIME_SVG
|
||||
) { outputStream ->
|
||||
barcodeSvg?.let {
|
||||
outputStream.write(it.toByteArray())
|
||||
}
|
||||
outputStream.write(barcode.svg().toByteArray())
|
||||
}
|
||||
FileType.TXT -> saveAs(
|
||||
addSuffixIfNotGiven(fileName, ".txt"),
|
||||
MIME_TXT
|
||||
) { outputStream ->
|
||||
barcodeTxt?.let {
|
||||
outputStream.write(it.toByteArray())
|
||||
}
|
||||
outputStream.write(barcode.text().toByteArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,9 +225,9 @@ class BarcodeFragment : Fragment() {
|
||||
|
||||
private fun Context.shareAs(fileType: FileType) {
|
||||
when (fileType) {
|
||||
FileType.PNG -> barcodeBitmap?.let { share(it) }
|
||||
FileType.SVG -> barcodeSvg?.let { shareText(it, MIME_SVG) }
|
||||
FileType.TXT -> barcodeTxt?.let { shareText(it) }
|
||||
FileType.PNG -> share(barcode.bitmap())
|
||||
FileType.SVG -> shareText(barcode.svg(), MIME_SVG)
|
||||
FileType.TXT -> shareText(barcode.text())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,25 +258,26 @@ class BarcodeFragment : Fragment() {
|
||||
companion object {
|
||||
private const val CONTENT = "content"
|
||||
private const val FORMAT = "format"
|
||||
private const val HINTS = "hints"
|
||||
private const val SIZE = "size"
|
||||
private const val EC_LEVEL = "ec_level"
|
||||
private const val COLORS = "colors"
|
||||
private const val MIME_PNG = "image/png"
|
||||
private const val MIME_SVG = "image/svg+xmg"
|
||||
private const val MIME_TXT = "text/plain"
|
||||
|
||||
fun newInstance(
|
||||
content: String,
|
||||
format: BarcodeFormat,
|
||||
format: Format,
|
||||
size: Int,
|
||||
hints: EnumMap<EncodeHintType, Any>? = null
|
||||
ecLevel: Int = -1,
|
||||
colors: Int = 0
|
||||
): Fragment {
|
||||
val args = Bundle()
|
||||
args.putString(CONTENT, content)
|
||||
args.putSerializable(FORMAT, format)
|
||||
hints?.let {
|
||||
args.putSerializable(HINTS, it)
|
||||
}
|
||||
args.putString(FORMAT, format.name)
|
||||
args.putInt(SIZE, size)
|
||||
args.putInt(EC_LEVEL, ecLevel)
|
||||
args.putInt(COLORS, colors)
|
||||
val fragment = BarcodeFragment()
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
@@ -277,6 +285,65 @@ class BarcodeFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private data class Barcode(
|
||||
val content: String,
|
||||
val format: Format,
|
||||
val size: Int,
|
||||
val ecLevel: Int,
|
||||
val colors: Colors
|
||||
) {
|
||||
private var _bitmap: Bitmap? = null
|
||||
fun bitmap(): Bitmap {
|
||||
val b = _bitmap ?: ZxingCpp.encodeAsBitmap(
|
||||
content, format, size, size, -1, ecLevel,
|
||||
setColor = colors.foregroundColor(),
|
||||
unsetColor = colors.backgroundColor()
|
||||
)
|
||||
_bitmap = b
|
||||
return b
|
||||
}
|
||||
|
||||
private var _svg: String? = null
|
||||
fun svg(): String {
|
||||
val s = _svg ?: ZxingCpp.encodeAsSvg(
|
||||
content, format, -1, ecLevel
|
||||
)
|
||||
_svg = s
|
||||
return s
|
||||
}
|
||||
|
||||
private var _text: String? = null
|
||||
fun text(): String {
|
||||
val t = _text ?: ZxingCpp.encodeAsText(
|
||||
content, format, -1, ecLevel,
|
||||
inverted = colors == Colors.BLACK_ON_WHITE
|
||||
)
|
||||
_text = t
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
private enum class Colors {
|
||||
BLACK_ON_WHITE,
|
||||
WHITE_ON_BLACK,
|
||||
BLACK_ON_TRANSPARENT,
|
||||
WHITE_ON_TRANSPARENT;
|
||||
|
||||
fun foregroundColor(): Int = when (this) {
|
||||
BLACK_ON_WHITE,
|
||||
BLACK_ON_TRANSPARENT -> COLOR_BLACK
|
||||
WHITE_ON_BLACK,
|
||||
WHITE_ON_TRANSPARENT -> COLOR_WHITE
|
||||
}
|
||||
|
||||
fun backgroundColor(): Int = when (this) {
|
||||
BLACK_ON_WHITE -> COLOR_WHITE
|
||||
WHITE_ON_BLACK -> COLOR_BLACK
|
||||
BLACK_ON_TRANSPARENT,
|
||||
WHITE_ON_TRANSPARENT -> 0
|
||||
}
|
||||
}
|
||||
|
||||
private fun Bitmap.saveAsPng(outputStream: OutputStream, quality: Int = 90) =
|
||||
compress(Bitmap.CompressFormat.PNG, quality, outputStream)
|
||||
|
||||
|
||||
@@ -5,16 +5,14 @@ import android.os.Bundle
|
||||
import android.support.design.widget.FloatingActionButton
|
||||
import android.support.v4.app.Fragment
|
||||
import android.text.Editable
|
||||
import android.text.Html
|
||||
import android.text.TextWatcher
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.*
|
||||
import android.widget.EditText
|
||||
import android.widget.TableLayout
|
||||
import android.widget.TableRow
|
||||
import android.widget.TextView
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
||||
import com.google.zxing.qrcode.encoder.Encoder
|
||||
import android.widget.*
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.actions.ActionRegistry
|
||||
import de.markusfisch.android.binaryeye.actions.IAction
|
||||
import de.markusfisch.android.binaryeye.actions.wifi.WifiAction
|
||||
import de.markusfisch.android.binaryeye.actions.wifi.WifiConnector
|
||||
import de.markusfisch.android.binaryeye.activity.MainActivity
|
||||
@@ -22,16 +20,17 @@ import de.markusfisch.android.binaryeye.adapter.prettifyFormatName
|
||||
import de.markusfisch.android.binaryeye.app.*
|
||||
import de.markusfisch.android.binaryeye.content.copyToClipboard
|
||||
import de.markusfisch.android.binaryeye.content.shareText
|
||||
import de.markusfisch.android.binaryeye.content.toHexString
|
||||
import de.markusfisch.android.binaryeye.database.Recreation
|
||||
import de.markusfisch.android.binaryeye.database.Scan
|
||||
import de.markusfisch.android.binaryeye.database.toRecreation
|
||||
import de.markusfisch.android.binaryeye.io.askForFileName
|
||||
import de.markusfisch.android.binaryeye.io.toSaveResult
|
||||
import de.markusfisch.android.binaryeye.io.writeExternalFile
|
||||
import de.markusfisch.android.binaryeye.view.setPaddingFromWindowInsets
|
||||
import de.markusfisch.android.binaryeye.widget.toast
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.*
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class DecodeFragment : Fragment() {
|
||||
private lateinit var contentView: EditText
|
||||
@@ -39,19 +38,24 @@ class DecodeFragment : Fragment() {
|
||||
private lateinit var dataView: TableLayout
|
||||
private lateinit var metaView: TableLayout
|
||||
private lateinit var hexView: TextView
|
||||
private lateinit var format: String
|
||||
private lateinit var stampView: TextView
|
||||
private lateinit var recreationView: ImageView
|
||||
private lateinit var fab: FloatingActionButton
|
||||
private lateinit var format: String
|
||||
|
||||
private val parentJob = Job()
|
||||
private val scope: CoroutineScope = CoroutineScope(Dispatchers.Main + parentJob)
|
||||
private val dp: Float
|
||||
get() = resources.displayMetrics.density
|
||||
private val content: String
|
||||
get() = contentView.text.toString()
|
||||
|
||||
private var closeAutomatically = false
|
||||
private var action = ActionRegistry.DEFAULT_ACTION
|
||||
private var isBinary = false
|
||||
private var raw: ByteArray = ByteArray(0)
|
||||
private var originalBytes: ByteArray = ByteArray(0)
|
||||
private var id = 0L
|
||||
private var recreation: Recreation? = null
|
||||
|
||||
override fun onCreate(state: Bundle?) {
|
||||
super.onCreate(state)
|
||||
@@ -74,70 +78,42 @@ class DecodeFragment : Fragment() {
|
||||
closeAutomatically = prefs.closeAutomatically &&
|
||||
activity?.intent?.hasExtra(MainActivity.DECODED) == true
|
||||
|
||||
val scan = arguments?.getParcelable(SCAN) as Scan?
|
||||
?: throw IllegalArgumentException("DecodeFragment needs a Scan")
|
||||
val scan = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
arguments?.getParcelable(SCAN, Scan::class.java)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
arguments?.getParcelable(SCAN) as Scan?
|
||||
} ?: throw IllegalArgumentException("DecodeFragment needs a Scan")
|
||||
|
||||
val originalContent = scan.content
|
||||
isBinary = scan.raw != null
|
||||
originalBytes = scan.raw ?: originalContent.toByteArray()
|
||||
format = scan.format
|
||||
id = scan.id
|
||||
|
||||
val inputContent = scan.content
|
||||
isBinary = scan.raw != null
|
||||
raw = scan.raw ?: inputContent.toByteArray()
|
||||
format = scan.format
|
||||
|
||||
contentView = view.findViewById(R.id.content)
|
||||
fab = view.findViewById(R.id.open)
|
||||
|
||||
if (!isBinary) {
|
||||
contentView.setText(inputContent)
|
||||
contentView.addTextChangedListener(object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
updateViewsAndAction(content.toByteArray())
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence?,
|
||||
start: Int,
|
||||
count: Int,
|
||||
after: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(
|
||||
s: CharSequence?,
|
||||
start: Int,
|
||||
before: Int,
|
||||
count: Int
|
||||
) {
|
||||
}
|
||||
})
|
||||
fab.setOnClickListener {
|
||||
executeAction(content.toByteArray())
|
||||
}
|
||||
if (prefs.openImmediately) {
|
||||
executeAction(content.toByteArray())
|
||||
}
|
||||
} else {
|
||||
contentView.setText(String(raw).foldNonAlNum())
|
||||
contentView.isEnabled = false
|
||||
fab.setImageResource(R.drawable.ic_action_save)
|
||||
fab.setOnClickListener {
|
||||
askForFileNameAndSave(raw)
|
||||
}
|
||||
}
|
||||
|
||||
formatView = view.findViewById(R.id.format)
|
||||
dataView = view.findViewById(R.id.data)
|
||||
metaView = view.findViewById(R.id.meta)
|
||||
hexView = view.findViewById(R.id.hex)
|
||||
stampView = view.findViewById(R.id.stamp)
|
||||
recreationView = view.findViewById(R.id.recreation)
|
||||
fab = view.findViewById(R.id.open)
|
||||
|
||||
updateViewsAndAction(raw)
|
||||
|
||||
if (!isBinary) {
|
||||
fillDataView(dataView, inputContent)
|
||||
}
|
||||
initContentAndFab(originalContent)
|
||||
|
||||
if (prefs.showMetaData) {
|
||||
fillMetaView(metaView, scan)
|
||||
metaView.fillMetaView(scan)
|
||||
} else {
|
||||
metaView.visibility = View.GONE
|
||||
}
|
||||
if (prefs.showRecreation) {
|
||||
recreation = scan.toRecreation(
|
||||
(200f * dp).roundToInt()
|
||||
)
|
||||
}
|
||||
|
||||
updateViewsAndFab(originalContent, originalBytes)
|
||||
|
||||
(view.findViewById(R.id.inset_layout) as View).setPaddingFromWindowInsets()
|
||||
(view.findViewById(R.id.scroll_view) as View).setPaddingFromWindowInsets()
|
||||
@@ -150,35 +126,104 @@ class DecodeFragment : Fragment() {
|
||||
parentJob.cancel()
|
||||
}
|
||||
|
||||
private fun updateViewsAndAction(bytes: ByteArray) {
|
||||
private fun initContentAndFab(originalContent: String) {
|
||||
if (isBinary) {
|
||||
contentView.setText(String(originalBytes).foldNonAlNum())
|
||||
contentView.isEnabled = false
|
||||
fab.setImageResource(R.drawable.ic_action_save)
|
||||
fab.setOnClickListener {
|
||||
askForFileNameAndSave(originalBytes)
|
||||
}
|
||||
} else {
|
||||
contentView.setText(originalContent)
|
||||
contentView.addTextChangedListener(object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
updateViewsAndFab(s?.toString() ?: "")
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence?,
|
||||
start: Int,
|
||||
count: Int,
|
||||
after: Int
|
||||
) = Unit
|
||||
|
||||
override fun onTextChanged(
|
||||
s: CharSequence?,
|
||||
start: Int,
|
||||
before: Int,
|
||||
count: Int
|
||||
) = Unit
|
||||
})
|
||||
fab.setOnClickListener {
|
||||
executeAction(content)
|
||||
}
|
||||
if (prefs.openImmediately) {
|
||||
executeAction(content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateViewsAndFab(text: String, bytes: ByteArray? = null) {
|
||||
val b = bytes ?: text.toByteArray()
|
||||
resolveActionAndUpdateFab(b)
|
||||
updateViews(text, b)
|
||||
}
|
||||
|
||||
private fun resolveActionAndUpdateFab(bytes: ByteArray) {
|
||||
val prevAction = action
|
||||
if (!prevAction.canExecuteOn(bytes)) {
|
||||
action = ActionRegistry.getAction(bytes)
|
||||
}
|
||||
if (prevAction !== action) {
|
||||
updateFab(action)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateFab(action: IAction) {
|
||||
fab.setImageResource(action.iconResId)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
fab.setOnLongClickListener { v ->
|
||||
v.context.toast(action.titleResId)
|
||||
true
|
||||
}
|
||||
} else {
|
||||
fab.tooltipText = getString(action.titleResId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateViews(text: String, bytes: ByteArray) {
|
||||
formatView.text = resources.getQuantityString(
|
||||
R.plurals.barcode_info,
|
||||
bytes.size,
|
||||
prettifyFormatName(format),
|
||||
bytes.size
|
||||
)
|
||||
hexView.text = if (prefs.showHexDump) hexDump(bytes) else ""
|
||||
if (prevAction !== action) {
|
||||
fab.setImageResource(action.iconResId)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
fab.setOnLongClickListener { v ->
|
||||
v.context.toast(action.titleResId)
|
||||
true
|
||||
}
|
||||
} else {
|
||||
fab.tooltipText = getString(action.titleResId)
|
||||
hexView.showIf(prefs.showHexDump) { v ->
|
||||
v.text = hexDump(bytes)
|
||||
}
|
||||
recreationView.showIf(prefs.showRecreation) { v ->
|
||||
val r = recreation ?: return@showIf
|
||||
v.setImageBitmap(r.encode(text))
|
||||
v.setOnClickListener {
|
||||
fragmentManager?.addFragment(
|
||||
BarcodeFragment.newInstance(
|
||||
text,
|
||||
r.format,
|
||||
r.size,
|
||||
r.ecLevel
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
dataView.fillDataView(text)
|
||||
stampView.setTrackingLink(bytes, format)
|
||||
}
|
||||
|
||||
private fun fillDataView(tableLayout: TableLayout, content: String) {
|
||||
private fun TableLayout.fillDataView(text: String) {
|
||||
val items = LinkedHashMap<Int, String?>()
|
||||
if (action is WifiAction) {
|
||||
WifiConnector.parseMap(content)?.let { wifiData ->
|
||||
WifiConnector.parseMap(text)?.let { wifiData ->
|
||||
items.putAll(
|
||||
linkedMapOf(
|
||||
R.string.entry_type to getString(R.string.wifi_network),
|
||||
@@ -194,52 +239,61 @@ class DecodeFragment : Fragment() {
|
||||
)
|
||||
}
|
||||
}
|
||||
fillDataTable(tableLayout, items)
|
||||
fill(items)
|
||||
}
|
||||
|
||||
private fun fillMetaView(tableLayout: TableLayout, scan: Scan) {
|
||||
private fun TableLayout.fillMetaView(scan: Scan) {
|
||||
val items = linkedMapOf(
|
||||
R.string.error_correction_level to scan.errorCorrectionLevel,
|
||||
R.string.issue_number to scan.issueNumber,
|
||||
R.string.orientation to scan.orientation,
|
||||
R.string.other_meta_data to scan.otherMetaData,
|
||||
R.string.pdf417_extra_metadata to scan.pdf417ExtraMetaData,
|
||||
R.string.possible_country to scan.possibleCountry,
|
||||
R.string.suggested_price to scan.suggestedPrice,
|
||||
R.string.upc_ean_extension to scan.upcEanExtension
|
||||
R.string.sequence_size to scan.sequenceSize.positiveToString(),
|
||||
R.string.sequence_index to scan.sequenceIndex.positiveToString(),
|
||||
R.string.sequence_id to scan.sequenceId,
|
||||
R.string.gtin_country to scan.country,
|
||||
R.string.gtin_add_on to scan.addOn,
|
||||
R.string.gtin_price to scan.price,
|
||||
R.string.gtin_issue_number to scan.issueNumber,
|
||||
)
|
||||
if (prefs.showQrVersion && scan.format == "QR_CODE") {
|
||||
if (!scan.version.isNullOrBlank()) {
|
||||
val versionString = if (scan.format == "QR_CODE") {
|
||||
getString(
|
||||
R.string.qr_version_and_modules,
|
||||
scan.version,
|
||||
(scan.version.toIntOrNull() ?: 0) * 4 + 17
|
||||
)
|
||||
} else {
|
||||
scan.version
|
||||
}
|
||||
items.putAll(
|
||||
linkedMapOf(
|
||||
R.string.qr_version to "${scan.version()}"
|
||||
R.string.barcode_version_number to versionString
|
||||
)
|
||||
)
|
||||
}
|
||||
fillDataTable(tableLayout, items)
|
||||
fill(items)
|
||||
}
|
||||
|
||||
private fun fillDataTable(
|
||||
tableLayout: TableLayout,
|
||||
private fun TableLayout.fill(
|
||||
items: LinkedHashMap<Int, String?>
|
||||
) {
|
||||
val ctx = tableLayout.context
|
||||
val spaceBetween = (16f * ctx.resources.displayMetrics.density).toInt()
|
||||
items.forEach { item ->
|
||||
val text = item.value
|
||||
if (!text.isNullOrBlank()) {
|
||||
val tr = TableRow(ctx)
|
||||
val keyView = TextView(ctx)
|
||||
keyView.setText(item.key)
|
||||
val valueView = TextView(ctx)
|
||||
valueView.setPadding(spaceBetween, 0, 0, 0)
|
||||
valueView.text = text
|
||||
tr.addView(keyView)
|
||||
tr.addView(valueView)
|
||||
tableLayout.addView(tr)
|
||||
removeAllViews()
|
||||
visibility = if (items.isEmpty()) View.GONE else {
|
||||
val ctx = context
|
||||
val spaceBetween = (16f * dp).roundToInt()
|
||||
items.forEach { item ->
|
||||
val text = item.value
|
||||
if (!text.isNullOrBlank()) {
|
||||
val tr = TableRow(ctx)
|
||||
val keyView = TextView(ctx)
|
||||
keyView.setText(item.key)
|
||||
val valueView = TextView(ctx)
|
||||
valueView.setPadding(spaceBetween, 0, 0, 0)
|
||||
valueView.text = text
|
||||
tr.addView(keyView)
|
||||
tr.addView(valueView)
|
||||
addView(tr)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tableLayout.childCount > 0) {
|
||||
tableLayout.setPadding(0, 0, 0, spaceBetween)
|
||||
View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +346,7 @@ class DecodeFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun textOrHex() = if (isBinary) {
|
||||
raw.toHexString()
|
||||
originalBytes.toHexString()
|
||||
} else {
|
||||
content
|
||||
}
|
||||
@@ -302,16 +356,16 @@ class DecodeFragment : Fragment() {
|
||||
if (ac is WifiAction) {
|
||||
ac.password?.let { password ->
|
||||
activity?.apply {
|
||||
copyToClipboard(password)
|
||||
copyToClipboard(password, isSensitive = true)
|
||||
toast(R.string.copied_password_to_clipboard)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun copyToClipboard(text: String) {
|
||||
private fun copyToClipboard(text: String, isSensitive: Boolean = false) {
|
||||
activity?.apply {
|
||||
copyToClipboard(text)
|
||||
copyToClipboard(text, isSensitive)
|
||||
toast(R.string.copied_to_clipboard)
|
||||
}
|
||||
}
|
||||
@@ -331,7 +385,7 @@ class DecodeFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun executeAction(content: ByteArray) {
|
||||
private fun executeAction(content: String) {
|
||||
val ac = activity ?: return
|
||||
if (content.isNotEmpty()) {
|
||||
if (action is WifiAction &&
|
||||
@@ -341,7 +395,7 @@ class DecodeFragment : Fragment() {
|
||||
return
|
||||
}
|
||||
scope.launch {
|
||||
action.execute(ac, content)
|
||||
action.execute(ac, content.toByteArray())
|
||||
maybeBackOrFinish()
|
||||
}
|
||||
}
|
||||
@@ -357,13 +411,17 @@ class DecodeFragment : Fragment() {
|
||||
}
|
||||
scope.launch(Dispatchers.Main) {
|
||||
val name = ac.askForFileName() ?: return@launch
|
||||
val message = ac.writeExternalFile(
|
||||
name,
|
||||
"application/octet-stream"
|
||||
) {
|
||||
it.write(raw)
|
||||
}.toSaveResult()
|
||||
ac.toast(message)
|
||||
withContext(Dispatchers.IO) {
|
||||
val message = ac.writeExternalFile(
|
||||
name,
|
||||
"application/octet-stream"
|
||||
) {
|
||||
it.write(raw)
|
||||
}.toSaveResult()
|
||||
withContext(Dispatchers.Main) {
|
||||
ac.toast(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,6 +438,23 @@ class DecodeFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <T : View> T.showIf(
|
||||
visible: Boolean,
|
||||
block: (T) -> Unit
|
||||
) {
|
||||
visibility = if (visible) {
|
||||
block.invoke(this)
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private val nonAlNum = "[^a-zA-Z0-9]".toRegex()
|
||||
private val multipleDots = "[…]+".toRegex()
|
||||
private fun String.foldNonAlNum() = replace(nonAlNum, "…")
|
||||
.replace(multipleDots, "…")
|
||||
|
||||
private fun hexDump(bytes: ByteArray, charsPerLine: Int = 33): String {
|
||||
if (charsPerLine < 4 || bytes.isEmpty()) {
|
||||
return ""
|
||||
@@ -419,7 +494,91 @@ private fun hexDump(bytes: ByteArray, charsPerLine: Int = 33): String {
|
||||
return dump.toString()
|
||||
}
|
||||
|
||||
private fun Scan.version(): Int = Encoder.encode(
|
||||
content,
|
||||
ErrorCorrectionLevel.valueOf(errorCorrectionLevel ?: "L")
|
||||
).version.versionNumber
|
||||
private fun Int.positiveToString() = if (this > -1) this.toString() else ""
|
||||
|
||||
private fun TextView.setTrackingLink(bytes: ByteArray, format: String) {
|
||||
val trackingLink = generateDpTrackingLink(bytes, format)
|
||||
if (trackingLink != null) {
|
||||
text = trackingLink.fromHtml()
|
||||
isClickable = true
|
||||
movementMethod = LinkMovementMethod.getInstance()
|
||||
} else {
|
||||
visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateDpTrackingLink(bytes: ByteArray, format: String): String? {
|
||||
// Check for Deutsche Post Matrixcode stamp.
|
||||
var isStamp = false
|
||||
var rawData = bytes
|
||||
if (format == "DATA_MATRIX" &&
|
||||
bytes.toString(Charsets.ISO_8859_1).startsWith("DEA5")
|
||||
) {
|
||||
if (bytes.size == 47) {
|
||||
isStamp = true
|
||||
} else if (bytes.size > 47) {
|
||||
// Transform back to original data.
|
||||
rawData = bytes.toString(Charsets.UTF_8).toByteArray(
|
||||
Charsets.ISO_8859_1
|
||||
)
|
||||
if (rawData.size == 47) {
|
||||
isStamp = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isStamp) {
|
||||
return null
|
||||
}
|
||||
|
||||
val hex = StringBuilder()
|
||||
hex.append(String.format("%02X", rawData[9]))
|
||||
hex.append(String.format("%02X", rawData[10]))
|
||||
hex.append(String.format("%02X", rawData[11]))
|
||||
hex.append(String.format("%02X", rawData[12]))
|
||||
hex.append(String.format("%02X", rawData[13]))
|
||||
hex.append(String.format("%X", (rawData[4].toInt() and 0x0f).toByte()))
|
||||
hex.append(String.format("%02X", rawData[5]))
|
||||
hex.append(String.format("%02X", rawData[6]))
|
||||
hex.append(String.format("%02X", rawData[7]))
|
||||
hex.append(String.format("%02X", rawData[8]))
|
||||
val hexString = hex.toString()
|
||||
val trackingNumber = hexString + String.format(
|
||||
"%X",
|
||||
crc4(hexString.toByteArray(Charsets.ISO_8859_1))
|
||||
)
|
||||
return "<a href=\"https://www.deutschepost.de/de/s/sendungsverfolgung/verfolgen.html?piececode=$trackingNumber\">Deutsche Post: $trackingNumber</a>"
|
||||
}
|
||||
|
||||
// CRC-4 with polynomial x^4 + x + 1.
|
||||
private fun crc4(input: ByteArray): Int {
|
||||
var crc = 0
|
||||
var i = 0
|
||||
while (i < input.size) {
|
||||
val c = input[i].toInt()
|
||||
var j = 0x80
|
||||
while (j != 0) {
|
||||
var bit = crc and 0x8
|
||||
crc = crc shl 1
|
||||
if (c and j != 0) {
|
||||
bit = bit xor 0x8
|
||||
}
|
||||
if (bit != 0) {
|
||||
crc = crc xor 0x3
|
||||
}
|
||||
j = j ushr 1
|
||||
}
|
||||
++i
|
||||
}
|
||||
crc = crc and 0xF
|
||||
return crc
|
||||
}
|
||||
|
||||
private fun String.fromHtml() = if (
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
||||
) {
|
||||
Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
Html.fromHtml(this)
|
||||
}
|
||||
|
||||
@@ -1,42 +1,43 @@
|
||||
package de.markusfisch.android.binaryeye.fragment
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.EncodeHintType
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.adapter.prettifyFormatName
|
||||
import de.markusfisch.android.binaryeye.app.addFragment
|
||||
import de.markusfisch.android.binaryeye.app.prefs
|
||||
import de.markusfisch.android.binaryeye.view.hideSoftKeyboard
|
||||
import de.markusfisch.android.binaryeye.view.setPaddingFromWindowInsets
|
||||
import java.util.*
|
||||
import de.markusfisch.android.binaryeye.widget.toast
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Format
|
||||
|
||||
class EncodeFragment : Fragment() {
|
||||
private lateinit var formatView: Spinner
|
||||
private lateinit var errorCorrectionLabel: TextView
|
||||
private lateinit var errorCorrectionLevel: Spinner
|
||||
private lateinit var ecLabel: TextView
|
||||
private lateinit var ecSpinner: Spinner
|
||||
private lateinit var colorsLabel: TextView
|
||||
private lateinit var colorsSpinner: Spinner
|
||||
private lateinit var sizeView: TextView
|
||||
private lateinit var sizeBarView: SeekBar
|
||||
private lateinit var contentView: EditText
|
||||
|
||||
private val writers = arrayListOf(
|
||||
BarcodeFormat.AZTEC,
|
||||
BarcodeFormat.CODABAR,
|
||||
BarcodeFormat.CODE_39,
|
||||
BarcodeFormat.CODE_128,
|
||||
BarcodeFormat.DATA_MATRIX,
|
||||
BarcodeFormat.EAN_8,
|
||||
BarcodeFormat.EAN_13,
|
||||
BarcodeFormat.ITF,
|
||||
BarcodeFormat.PDF_417,
|
||||
BarcodeFormat.QR_CODE,
|
||||
BarcodeFormat.UPC_A
|
||||
Format.AZTEC,
|
||||
Format.CODABAR,
|
||||
Format.CODE_39,
|
||||
Format.CODE_128,
|
||||
Format.DATA_MATRIX,
|
||||
Format.EAN_8,
|
||||
Format.EAN_13,
|
||||
Format.ITF,
|
||||
Format.PDF_417,
|
||||
Format.QR_CODE,
|
||||
Format.UPC_A
|
||||
)
|
||||
|
||||
override fun onCreateView(
|
||||
@@ -70,22 +71,26 @@ class EncodeFragment : Fragment() {
|
||||
position: Int,
|
||||
id: Long
|
||||
) {
|
||||
val visibility = if (
|
||||
writers[position] == BarcodeFormat.QR_CODE
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
errorCorrectionLabel.visibility = visibility
|
||||
errorCorrectionLevel.visibility = visibility
|
||||
val ecVisibility = if (
|
||||
writers[position] == Format.QR_CODE
|
||||
) View.VISIBLE else View.GONE
|
||||
ecLabel.visibility = ecVisibility
|
||||
ecSpinner.visibility = ecVisibility
|
||||
val colorsVisibility = if (
|
||||
writers[position].canBeInverted()
|
||||
) View.VISIBLE else View.GONE
|
||||
colorsLabel.visibility = colorsVisibility
|
||||
colorsSpinner.visibility = colorsVisibility
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parentView: AdapterView<*>?) {}
|
||||
}
|
||||
|
||||
errorCorrectionLabel = view.findViewById(R.id.error_correction_label)
|
||||
errorCorrectionLevel = view.findViewById(R.id.error_correction_level)
|
||||
ecLabel = view.findViewById(R.id.error_correction_label)
|
||||
ecSpinner = view.findViewById(R.id.error_correction_level)
|
||||
|
||||
colorsLabel = view.findViewById(R.id.colors_label)
|
||||
colorsSpinner = view.findViewById(R.id.colors)
|
||||
|
||||
sizeView = view.findViewById(R.id.size_display)
|
||||
sizeBarView = view.findViewById(R.id.size_bar)
|
||||
@@ -94,14 +99,14 @@ class EncodeFragment : Fragment() {
|
||||
contentView = view.findViewById(R.id.content)
|
||||
|
||||
val args = arguments
|
||||
args?.also {
|
||||
contentView.setText(it.getString(CONTENT))
|
||||
args?.getString(CONTENT)?.let {
|
||||
contentView.setText(it)
|
||||
}
|
||||
|
||||
val barcodeFormat = args?.getString(FORMAT)
|
||||
if (barcodeFormat != null) {
|
||||
formatView.setSelection(
|
||||
writers.indexOf(resolveFormat(barcodeFormat))
|
||||
writers.indexOf(barcodeFormat.toFormat())
|
||||
)
|
||||
} else if (state == null) {
|
||||
formatView.post {
|
||||
@@ -110,7 +115,7 @@ class EncodeFragment : Fragment() {
|
||||
}
|
||||
|
||||
view.findViewById<View>(R.id.encode).setOnClickListener {
|
||||
encode()
|
||||
it.context.encode()
|
||||
}
|
||||
|
||||
(view.findViewById(R.id.inset_layout) as View).setPaddingFromWindowInsets()
|
||||
@@ -124,31 +129,25 @@ class EncodeFragment : Fragment() {
|
||||
prefs.indexOfLastSelectedFormat = formatView.selectedItemPosition
|
||||
}
|
||||
|
||||
private fun encode() {
|
||||
val hints = EnumMap<EncodeHintType, Any>(EncodeHintType::class.java)
|
||||
val format = writers[formatView.selectedItemPosition]
|
||||
if (format == BarcodeFormat.QR_CODE) {
|
||||
hints[EncodeHintType.ERROR_CORRECTION] = arrayListOf(
|
||||
ErrorCorrectionLevel.L,
|
||||
ErrorCorrectionLevel.M,
|
||||
ErrorCorrectionLevel.Q,
|
||||
ErrorCorrectionLevel.H
|
||||
)[errorCorrectionLevel.selectedItemPosition]
|
||||
}
|
||||
val size = getSize(sizeBarView.progress)
|
||||
private fun Context.encode() {
|
||||
val content = contentView.text.toString()
|
||||
if (content.isEmpty()) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.error_no_content,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
} else {
|
||||
activity?.hideSoftKeyboard(contentView)
|
||||
fragmentManager?.addFragment(
|
||||
BarcodeFragment.newInstance(content, format, size, hints)
|
||||
)
|
||||
toast(R.string.error_no_content)
|
||||
return
|
||||
}
|
||||
hideSoftKeyboard(contentView)
|
||||
val writer = writers[formatView.selectedItemPosition]
|
||||
fragmentManager?.addFragment(
|
||||
BarcodeFragment.newInstance(
|
||||
content,
|
||||
writer,
|
||||
getSize(sizeBarView.progress),
|
||||
ecSpinner.selectedItemPosition,
|
||||
if (writer.canBeInverted()) {
|
||||
colorsSpinner.selectedItemPosition
|
||||
} else 0
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun initSizeBar() {
|
||||
@@ -181,11 +180,11 @@ class EncodeFragment : Fragment() {
|
||||
private const val FORMAT = "format"
|
||||
|
||||
fun newInstance(
|
||||
content: String,
|
||||
content: String? = null,
|
||||
format: String? = null
|
||||
): Fragment {
|
||||
val args = Bundle()
|
||||
args.putString(CONTENT, content)
|
||||
content?.let { args.putString(CONTENT, content) }
|
||||
format?.let { args.putString(FORMAT, it) }
|
||||
val fragment = EncodeFragment()
|
||||
fragment.arguments = args
|
||||
@@ -194,8 +193,15 @@ class EncodeFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveFormat(name: String): BarcodeFormat = try {
|
||||
BarcodeFormat.valueOf(name)
|
||||
} catch (_: IllegalArgumentException) {
|
||||
BarcodeFormat.QR_CODE
|
||||
private fun Format.canBeInverted() = when (this) {
|
||||
Format.AZTEC,
|
||||
Format.DATA_MATRIX,
|
||||
Format.QR_CODE -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
private fun String.toFormat(default: Format = Format.QR_CODE): Format = try {
|
||||
Format.valueOf(this)
|
||||
} catch (_: IllegalArgumentException) {
|
||||
default
|
||||
}
|
||||
|
||||
@@ -23,11 +23,7 @@ import de.markusfisch.android.binaryeye.adapter.ScansAdapter
|
||||
import de.markusfisch.android.binaryeye.app.*
|
||||
import de.markusfisch.android.binaryeye.content.copyToClipboard
|
||||
import de.markusfisch.android.binaryeye.content.shareText
|
||||
import de.markusfisch.android.binaryeye.database.Database
|
||||
import de.markusfisch.android.binaryeye.database.getString
|
||||
import de.markusfisch.android.binaryeye.database.exportCsv
|
||||
import de.markusfisch.android.binaryeye.database.exportDatabase
|
||||
import de.markusfisch.android.binaryeye.database.exportJson
|
||||
import de.markusfisch.android.binaryeye.database.*
|
||||
import de.markusfisch.android.binaryeye.io.askForFileName
|
||||
import de.markusfisch.android.binaryeye.io.toSaveResult
|
||||
import de.markusfisch.android.binaryeye.view.*
|
||||
@@ -76,7 +72,7 @@ class HistoryFragment : Fragment() {
|
||||
val ac = activity ?: return false
|
||||
return when (item.itemId) {
|
||||
R.id.copy_scan -> {
|
||||
scansAdapter?.getSelectedContent()?.let {
|
||||
scansAdapter?.getSelectedContent("\n")?.let {
|
||||
ac.copyToClipboard(it)
|
||||
ac.toast(R.string.copied_to_clipboard)
|
||||
}
|
||||
@@ -84,19 +80,21 @@ class HistoryFragment : Fragment() {
|
||||
true
|
||||
}
|
||||
R.id.edit_scan -> {
|
||||
scansAdapter?.let {
|
||||
askForName(
|
||||
ac,
|
||||
it.selectedScanId,
|
||||
getScanName(it.selectedScanPosition)
|
||||
scansAdapter?.forSelection { id, position ->
|
||||
ac.askForName(
|
||||
id,
|
||||
scansAdapter?.getName(position),
|
||||
scansAdapter?.getContent(position)
|
||||
)
|
||||
}
|
||||
closeActionMode()
|
||||
true
|
||||
}
|
||||
R.id.remove_scan -> {
|
||||
scansAdapter?.let {
|
||||
askToRemoveScan(ac, it.selectedScanId)
|
||||
scansAdapter?.getSelectedIds()?.let {
|
||||
if (it.isNotEmpty()) {
|
||||
ac.askToRemoveScans(it)
|
||||
}
|
||||
}
|
||||
closeActionMode()
|
||||
true
|
||||
@@ -146,8 +144,7 @@ class HistoryFragment : Fragment() {
|
||||
showScan(id)
|
||||
}
|
||||
listView.setOnItemLongClickListener { _, v, position, id ->
|
||||
v.isSelected = true
|
||||
scansAdapter?.select(id, position)
|
||||
scansAdapter?.select(v, id, position)
|
||||
if (actionMode == null && ac is AppCompatActivity) {
|
||||
actionMode = ac.delegate.startSupportActionMode(
|
||||
actionModeCallback
|
||||
@@ -159,7 +156,7 @@ class HistoryFragment : Fragment() {
|
||||
|
||||
fab = view.findViewById(R.id.share)
|
||||
fab.setOnClickListener { v ->
|
||||
pickListSeparatorAndShare(v.context)
|
||||
v.context.pickListSeparatorAndShare()
|
||||
}
|
||||
|
||||
progressView = view.findViewById(R.id.progress_view)
|
||||
@@ -221,7 +218,7 @@ class HistoryFragment : Fragment() {
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.clear -> {
|
||||
askToRemoveScans(context)
|
||||
context.askToRemoveScans()
|
||||
true
|
||||
}
|
||||
R.id.export_history -> {
|
||||
@@ -300,20 +297,22 @@ class HistoryFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getScanName(position: Int): String? {
|
||||
val cursor = scansAdapter?.getItem(position) as Cursor?
|
||||
return cursor?.getString(Database.SCANS_NAME)
|
||||
}
|
||||
|
||||
// Dialogs don't have a parent layout.
|
||||
@SuppressLint("InflateParams")
|
||||
private fun askForName(context: Context, id: Long, text: String?) {
|
||||
val view = LayoutInflater.from(context).inflate(
|
||||
private fun Context.askForName(id: Long, text: String?, content: String?) {
|
||||
val view = LayoutInflater.from(this).inflate(
|
||||
R.layout.dialog_enter_name, null
|
||||
)
|
||||
val nameView = view.findViewById<EditText>(R.id.name)
|
||||
nameView.setText(text)
|
||||
AlertDialog.Builder(context)
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(
|
||||
if (content.isNullOrEmpty()) {
|
||||
getString(R.string.binary_data)
|
||||
} else {
|
||||
content
|
||||
}
|
||||
)
|
||||
.setView(view)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
val name = nameView.text.toString()
|
||||
@@ -324,11 +323,17 @@ class HistoryFragment : Fragment() {
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun askToRemoveScan(context: Context, id: Long) {
|
||||
AlertDialog.Builder(context)
|
||||
.setMessage(R.string.really_remove_scan)
|
||||
private fun Context.askToRemoveScans(ids: List<Long>) {
|
||||
AlertDialog.Builder(this)
|
||||
.setMessage(
|
||||
if (ids.size > 1) {
|
||||
R.string.really_remove_selected_scans
|
||||
} else {
|
||||
R.string.really_remove_scan
|
||||
}
|
||||
)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
db.removeScan(id)
|
||||
ids.forEach { db.removeScan(it) }
|
||||
if (scansAdapter?.count == 1) {
|
||||
updateAndClearFilter()
|
||||
} else {
|
||||
@@ -340,8 +345,8 @@ class HistoryFragment : Fragment() {
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun askToRemoveScans(context: Context) {
|
||||
AlertDialog.Builder(context)
|
||||
private fun Context.askToRemoveScans() {
|
||||
AlertDialog.Builder(this)
|
||||
.setMessage(
|
||||
if (filter == null) {
|
||||
R.string.really_remove_all_scans
|
||||
@@ -402,11 +407,11 @@ class HistoryFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun pickListSeparatorAndShare(context: Context) {
|
||||
val separators = context.resources.getStringArray(
|
||||
private fun Context.pickListSeparatorAndShare() {
|
||||
val separators = resources.getStringArray(
|
||||
R.array.list_separators_values
|
||||
)
|
||||
AlertDialog.Builder(context)
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(R.string.pick_list_separator)
|
||||
.setItems(R.array.list_separators_names) { _, which ->
|
||||
shareScans(separators[which])
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package de.markusfisch.android.binaryeye.fragment
|
||||
|
||||
import android.content.Context
|
||||
import android.net.wifi.WifiManager
|
||||
import android.net.wifi.WifiNetworkSuggestion
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.support.annotation.RequiresApi
|
||||
import android.support.v4.app.Fragment
|
||||
import android.view.*
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ListView
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.view.setPaddingFromWindowInsets
|
||||
import de.markusfisch.android.binaryeye.view.systemBarListViewScrollListener
|
||||
import de.markusfisch.android.binaryeye.widget.toast
|
||||
|
||||
class NetworkSuggestionsFragment : Fragment() {
|
||||
@RequiresApi(Build.VERSION_CODES.R)
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
state: Bundle?
|
||||
): View? {
|
||||
val ac = activity ?: return null
|
||||
ac.setTitle(R.string.network_suggestions)
|
||||
|
||||
val view = inflater.inflate(
|
||||
R.layout.fragment_network_suggestions,
|
||||
container,
|
||||
false
|
||||
)
|
||||
|
||||
val wm = ac.applicationContext.getSystemService(
|
||||
Context.WIFI_SERVICE
|
||||
) as WifiManager
|
||||
val suggestionArrayAdapter = ArrayAdapter(
|
||||
ac,
|
||||
android.R.layout.simple_list_item_checked,
|
||||
wm.networkSuggestions.map {
|
||||
Suggestion(
|
||||
it.ssid ?: it.toString(),
|
||||
it
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
val listView = view.findViewById<ListView>(R.id.suggestions)
|
||||
listView.emptyView = view.findViewById(R.id.no_suggestions)
|
||||
listView.adapter = suggestionArrayAdapter
|
||||
listView.setOnScrollListener(systemBarListViewScrollListener)
|
||||
(view.findViewById(R.id.inset_layout) as View).setPaddingFromWindowInsets()
|
||||
listView.setPaddingFromWindowInsets()
|
||||
|
||||
view.findViewById<View>(R.id.remove).setOnClickListener {
|
||||
val removeList = ArrayList<WifiNetworkSuggestion>()
|
||||
val removeFromAdapter = ArrayList<Suggestion>()
|
||||
val checked = listView.checkedItemPositions
|
||||
val size = checked.size()
|
||||
for (i in 0 until size) {
|
||||
if (checked.valueAt(i)) {
|
||||
val pos = checked.keyAt(i)
|
||||
listView.setItemChecked(pos, false)
|
||||
val suggestion = listView.getItemAtPosition(
|
||||
pos
|
||||
) as Suggestion
|
||||
removeList.add(suggestion.suggestion)
|
||||
removeFromAdapter.add(suggestion)
|
||||
}
|
||||
}
|
||||
if (removeList.isNotEmpty()) {
|
||||
removeFromAdapter.forEach {
|
||||
suggestionArrayAdapter.remove(it)
|
||||
}
|
||||
wm.removeNetworkSuggestions(removeList)
|
||||
} else {
|
||||
ac.toast(
|
||||
R.string.clear_network_suggestions_nothing_to_remove
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
}
|
||||
|
||||
private data class Suggestion(
|
||||
val label: String,
|
||||
val suggestion: WifiNetworkSuggestion
|
||||
) {
|
||||
override fun toString() = label
|
||||
}
|
||||
+43
-20
@@ -16,9 +16,10 @@ import android.support.v7.preference.Preference
|
||||
import android.support.v7.preference.PreferenceFragmentCompat
|
||||
import android.support.v7.preference.PreferenceGroup
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.actions.wifi.removeNetworkSuggestions
|
||||
import de.markusfisch.android.binaryeye.activity.SplashActivity
|
||||
import de.markusfisch.android.binaryeye.app.addFragment
|
||||
import de.markusfisch.android.binaryeye.app.prefs
|
||||
import de.markusfisch.android.binaryeye.media.beepConfirm
|
||||
import de.markusfisch.android.binaryeye.preference.UrlPreference
|
||||
import de.markusfisch.android.binaryeye.view.setPaddingFromWindowInsets
|
||||
import de.markusfisch.android.binaryeye.view.systemBarRecyclerViewScrollListener
|
||||
@@ -32,48 +33,63 @@ class PreferencesFragment : PreferenceFragmentCompat() {
|
||||
) {
|
||||
val preference = findPreference(key) ?: return
|
||||
prefs.update()
|
||||
if (preference.key == "custom_locale") {
|
||||
activity?.restartApp()
|
||||
} else {
|
||||
setSummary(preference)
|
||||
when (preference.key) {
|
||||
"custom_locale" -> activity?.restartApp()
|
||||
"beep_tone_name" -> {
|
||||
beepConfirm()
|
||||
setSummary(preference)
|
||||
}
|
||||
else -> setSummary(preference)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(state: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.preferences)
|
||||
activity?.setTitle(R.string.preferences)
|
||||
wireClearNetworkPreferences()
|
||||
}
|
||||
|
||||
private fun wireClearNetworkPreferences() {
|
||||
val pref = findPreference("clear_network_suggestions") ?: return
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
pref.isVisible = false
|
||||
} else {
|
||||
pref.setOnPreferenceClickListener {
|
||||
askToClearNetworkSuggestions(context)
|
||||
true
|
||||
findPreference("clear_network_suggestions").apply {
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
|
||||
// From R+ we can query past network suggestions and
|
||||
// make them editable.
|
||||
setOnPreferenceClickListener {
|
||||
fragmentManager.addFragment(NetworkSuggestionsFragment())
|
||||
true
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
|
||||
// On Q, we can only clear *all* suggestions.
|
||||
// Note that previous versions of this app allowed
|
||||
// adding network suggestions on Q as well, so we
|
||||
// need to keep this option.
|
||||
setOnPreferenceClickListener {
|
||||
context.askToClearNetworkSuggestions()
|
||||
true
|
||||
}
|
||||
} else {
|
||||
// There are no network suggestions below Q.
|
||||
isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.Q)
|
||||
private fun askToClearNetworkSuggestions(context: Context) {
|
||||
AlertDialog.Builder(context)
|
||||
private fun Context.askToClearNetworkSuggestions() {
|
||||
AlertDialog.Builder(this)
|
||||
.setMessage(R.string.really_remove_all_networks)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
clearNetworkSuggestions(context)
|
||||
clearNetworkSuggestions()
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||
.show()
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.Q)
|
||||
private fun clearNetworkSuggestions(context: Context) {
|
||||
context.toast(
|
||||
if (
|
||||
removeNetworkSuggestions(context) == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS
|
||||
private fun Context.clearNetworkSuggestions() {
|
||||
toast(
|
||||
if (removeAllNetworkSuggestions() ==
|
||||
WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS
|
||||
) {
|
||||
R.string.clear_network_suggestions_success
|
||||
} else {
|
||||
@@ -84,6 +100,7 @@ class PreferencesFragment : PreferenceFragmentCompat() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
activity?.setTitle(R.string.preferences)
|
||||
listView.setPaddingFromWindowInsets()
|
||||
listView.removeOnScrollListener(systemBarRecyclerViewScrollListener)
|
||||
listView.addOnScrollListener(systemBarRecyclerViewScrollListener)
|
||||
@@ -152,3 +169,9 @@ private fun Activity.restartApp() {
|
||||
// Restart to begin with an unmodified Locale to follow system settings.
|
||||
Runtime.getRuntime().exit(0)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.Q)
|
||||
private fun Context.removeAllNetworkSuggestions(): Int =
|
||||
(applicationContext.getSystemService(
|
||||
Context.WIFI_SERVICE
|
||||
) as WifiManager).removeNetworkSuggestions(listOf())
|
||||
|
||||
@@ -50,15 +50,7 @@ class UrlDialogFragment : PreferenceDialogFragmentCompat() {
|
||||
Scan(
|
||||
"test",
|
||||
null,
|
||||
"none",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
"none"
|
||||
).sendAsync(url, prefs.sendScanType) { code, body ->
|
||||
textView.text = when {
|
||||
code != null -> "$code"
|
||||
|
||||
@@ -49,8 +49,13 @@ private fun calculateInSampleSize(
|
||||
return inSampleSize
|
||||
}
|
||||
|
||||
fun Bitmap.crop(rect: RectF, rotation: Float) = try {
|
||||
val erected = erect(rotation)
|
||||
fun Bitmap.crop(
|
||||
rect: RectF,
|
||||
rotation: Float,
|
||||
pivotX: Float,
|
||||
pivotY: Float
|
||||
) = try {
|
||||
val erected = erect(rotation, pivotX, pivotY)
|
||||
val w = erected.width
|
||||
val h = erected.height
|
||||
val x = max(0, (rect.left * w).roundToInt())
|
||||
@@ -68,7 +73,11 @@ fun Bitmap.crop(rect: RectF, rotation: Float) = try {
|
||||
null
|
||||
}
|
||||
|
||||
private fun Bitmap.erect(rotation: Float): Bitmap = if (
|
||||
private fun Bitmap.erect(
|
||||
rotation: Float,
|
||||
pivotX: Float,
|
||||
pivotY: Float
|
||||
): Bitmap = if (
|
||||
rotation % 360f != 0f
|
||||
) {
|
||||
Bitmap.createBitmap(
|
||||
@@ -78,7 +87,7 @@ private fun Bitmap.erect(rotation: Float): Bitmap = if (
|
||||
width,
|
||||
height,
|
||||
Matrix().apply {
|
||||
setRotate(rotation)
|
||||
setRotate(rotation, pivotX, pivotY)
|
||||
},
|
||||
true
|
||||
)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package de.markusfisch.android.binaryeye.graphics
|
||||
|
||||
const val COLOR_BLACK = 0xff000000.toInt()
|
||||
const val COLOR_WHITE = 0xffffffff.toInt()
|
||||
@@ -2,61 +2,86 @@ package de.markusfisch.android.binaryeye.graphics
|
||||
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.Rect
|
||||
import com.google.zxing.ResultPoint
|
||||
import android.graphics.RectF
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Position
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
fun mapResultToView(
|
||||
frameWidth: Int,
|
||||
frameHeight: Int,
|
||||
frameOrientation: Int,
|
||||
viewRect: Rect,
|
||||
resultPoints: Array<ResultPoint?>,
|
||||
targetArray: FloatArray
|
||||
): Int = getFrameToViewMatrix(
|
||||
frameWidth,
|
||||
frameHeight,
|
||||
frameOrientation,
|
||||
viewRect
|
||||
).map(
|
||||
resultPoints,
|
||||
targetArray
|
||||
data class FrameMetrics(
|
||||
var width: Int = 0,
|
||||
var height: Int = 0,
|
||||
var orientation: Int = 0
|
||||
)
|
||||
|
||||
fun getFrameToViewMatrix(
|
||||
frameWidth: Int,
|
||||
frameHeight: Int,
|
||||
frameOrientation: Int,
|
||||
viewRect: Rect
|
||||
) = Matrix().apply {
|
||||
// Normalize to frame dimensions for rotation.
|
||||
postScale(
|
||||
1f / frameWidth,
|
||||
1f / frameHeight
|
||||
)
|
||||
// Rotate around center.
|
||||
postRotate(frameOrientation.toFloat(), 0.5f, 0.5f)
|
||||
// Scale up to view size.
|
||||
postScale(viewRect.width().toFloat(), viewRect.height().toFloat())
|
||||
// Apply view displacement.
|
||||
postTranslate(viewRect.left.toFloat(), viewRect.top.toFloat())
|
||||
fun Rect.setFrameRoi(
|
||||
frameMetrics: FrameMetrics,
|
||||
viewRect: Rect,
|
||||
viewRoi: Rect
|
||||
) {
|
||||
Matrix().apply {
|
||||
// Map ROI from view coordinates to frame coordinates.
|
||||
setTranslate(-viewRect.left.toFloat(), -viewRect.top.toFloat())
|
||||
postScale(1f / viewRect.width(), 1f / viewRect.height())
|
||||
postRotate(-frameMetrics.orientation.toFloat(), .5f, .5f)
|
||||
postScale(frameMetrics.width.toFloat(), frameMetrics.height.toFloat())
|
||||
val frameRoiF = RectF()
|
||||
val viewRoiF = RectF(
|
||||
viewRoi.left.toFloat(),
|
||||
viewRoi.top.toFloat(),
|
||||
viewRoi.right.toFloat(),
|
||||
viewRoi.bottom.toFloat()
|
||||
)
|
||||
mapRect(frameRoiF, viewRoiF)
|
||||
set(
|
||||
frameRoiF.left.roundToInt(),
|
||||
frameRoiF.top.roundToInt(),
|
||||
frameRoiF.right.roundToInt(),
|
||||
frameRoiF.bottom.roundToInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun Matrix.map(
|
||||
resultPoints: Array<ResultPoint?>,
|
||||
targetArray: FloatArray
|
||||
): Int {
|
||||
val max = targetArray.size
|
||||
var i = 0
|
||||
for (resultPoint in resultPoints) {
|
||||
// Because ZXing apparently returns null in this array sometimes.
|
||||
if (resultPoint == null) {
|
||||
continue
|
||||
fun Matrix.setFrameToView(
|
||||
frameMetrics: FrameMetrics,
|
||||
viewRect: Rect,
|
||||
viewRoi: Rect? = null
|
||||
) {
|
||||
// Configure this matrix to map points in frame coordinates to
|
||||
// view coordinates.
|
||||
val uprightWidth: Int
|
||||
val uprightHeight: Int
|
||||
when (frameMetrics.orientation) {
|
||||
90, 270 -> {
|
||||
uprightWidth = frameMetrics.height
|
||||
uprightHeight = frameMetrics.width
|
||||
}
|
||||
targetArray[i++] = resultPoint.x
|
||||
targetArray[i++] = resultPoint.y
|
||||
if (i >= max) {
|
||||
break
|
||||
else -> {
|
||||
uprightWidth = frameMetrics.width
|
||||
uprightHeight = frameMetrics.height
|
||||
}
|
||||
}
|
||||
mapPoints(targetArray, 0, targetArray, 0, i)
|
||||
setScale(
|
||||
viewRect.width().toFloat() / uprightWidth,
|
||||
viewRect.height().toFloat() / uprightHeight
|
||||
)
|
||||
viewRoi?.let {
|
||||
postTranslate(viewRoi.left.toFloat(), viewRoi.top.toFloat())
|
||||
}
|
||||
}
|
||||
|
||||
fun Matrix.mapPosition(
|
||||
position: Position,
|
||||
coords: FloatArray
|
||||
): Int {
|
||||
var i = 0
|
||||
setOf(
|
||||
position.topLeft,
|
||||
position.topRight,
|
||||
position.bottomRight,
|
||||
position.bottomLeft
|
||||
).forEach {
|
||||
coords[i++] = it.x.toFloat()
|
||||
coords[i++] = it.y.toFloat()
|
||||
}
|
||||
mapPoints(coords)
|
||||
return i
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package de.markusfisch.android.binaryeye.graphics
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
|
||||
fun Bitmap.fixTransparency(): Bitmap {
|
||||
val result = analyzeTransparency()
|
||||
return if (result.hasTransparentPixels) {
|
||||
val copy = Bitmap.createBitmap(
|
||||
width,
|
||||
height,
|
||||
config
|
||||
)
|
||||
Canvas(copy).apply {
|
||||
drawColor(result.backgroundColor)
|
||||
drawBitmap(this@fixTransparency, 0f, 0f, null)
|
||||
}
|
||||
copy
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
private fun Bitmap.analyzeTransparency(): Result {
|
||||
val pixels = IntArray(width * height)
|
||||
getPixels(pixels, 0, width, 0, 0, width, height)
|
||||
var transparent = 0
|
||||
var visible = 0
|
||||
var bright = 0
|
||||
for (pixel in pixels) {
|
||||
val alpha = (pixel shr 24) and 0xff
|
||||
if (alpha < 0xff) {
|
||||
++transparent
|
||||
}
|
||||
if (alpha > 0) {
|
||||
++visible
|
||||
if (
|
||||
((pixel shr 16) and 0xff) +
|
||||
((pixel shr 8) and 0xff) +
|
||||
(pixel and 0xff) > 128
|
||||
) ++bright
|
||||
}
|
||||
}
|
||||
return Result(
|
||||
transparent > 0,
|
||||
if (bright > 0 && visible / bright < 2) {
|
||||
COLOR_BLACK
|
||||
} else {
|
||||
COLOR_WHITE
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private data class Result(
|
||||
val hasTransparentPixels: Boolean,
|
||||
val backgroundColor: Int
|
||||
)
|
||||
@@ -0,0 +1,33 @@
|
||||
package de.markusfisch.android.binaryeye.media
|
||||
|
||||
import android.media.AudioManager
|
||||
import android.media.ToneGenerator
|
||||
import de.markusfisch.android.binaryeye.app.prefs
|
||||
|
||||
private var confirmToneGenerator: ToneGenerator? = null
|
||||
private var errorToneGenerator: ToneGenerator? = null
|
||||
|
||||
fun beepConfirm() {
|
||||
val tg = confirmToneGenerator ?: ToneGenerator(
|
||||
AudioManager.STREAM_NOTIFICATION,
|
||||
ToneGenerator.MAX_VOLUME
|
||||
)
|
||||
confirmToneGenerator = tg
|
||||
tg.startTone(prefs.beepTone())
|
||||
}
|
||||
|
||||
fun beepError() {
|
||||
val tg = errorToneGenerator ?: ToneGenerator(
|
||||
AudioManager.STREAM_ALARM,
|
||||
ToneGenerator.MAX_VOLUME
|
||||
)
|
||||
errorToneGenerator = tg
|
||||
tg.startTone(ToneGenerator.TONE_SUP_ERROR)
|
||||
}
|
||||
|
||||
fun releaseToneGenerators() {
|
||||
confirmToneGenerator?.release()
|
||||
confirmToneGenerator = null
|
||||
errorToneGenerator?.release()
|
||||
errorToneGenerator = null
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package de.markusfisch.android.binaryeye.net
|
||||
|
||||
import de.markusfisch.android.binaryeye.app.toHexString
|
||||
import de.markusfisch.android.binaryeye.app.urlEncode
|
||||
import de.markusfisch.android.binaryeye.content.toHexString
|
||||
import de.markusfisch.android.binaryeye.database.Scan
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -69,13 +68,14 @@ private fun Scan.getMap(): Map<String, String> = mapOf(
|
||||
"raw" to raw?.toHexString(),
|
||||
"format" to format,
|
||||
"errorCorrectionLevel" to errorCorrectionLevel,
|
||||
"version" to version,
|
||||
"sequenceSize" to sequenceSize.toString(),
|
||||
"sequenceIndex" to sequenceIndex.toString(),
|
||||
"sequenceId" to sequenceId,
|
||||
"country" to country,
|
||||
"addOn" to addOn,
|
||||
"price" to price,
|
||||
"issueNumber" to issueNumber,
|
||||
"orientation" to orientation,
|
||||
"otherMetaData" to otherMetaData,
|
||||
"pdf417ExtraMetaData" to pdf417ExtraMetaData,
|
||||
"possibleCountry" to possibleCountry,
|
||||
"suggestedPrice" to suggestedPrice,
|
||||
"upcEanExtension" to upcEanExtension,
|
||||
"timestamp" to dateTime
|
||||
).filterNullValues()
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.markusfisch.android.binaryeye.net
|
||||
|
||||
import java.io.UnsupportedEncodingException
|
||||
import java.net.URLEncoder
|
||||
|
||||
fun String.urlEncode(): String = try {
|
||||
URLEncoder.encode(this, "UTF-8")
|
||||
} catch (e: UnsupportedEncodingException) {
|
||||
this
|
||||
}
|
||||
@@ -4,10 +4,8 @@ import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
import android.os.VibratorManager
|
||||
import de.markusfisch.android.binaryeye.app.prefs
|
||||
|
||||
private const val DURATION_IN_MS = 100L
|
||||
private const val DURATION_IN_MS = 250L
|
||||
|
||||
private val beforeO = Build.VERSION.SDK_INT < Build.VERSION_CODES.O
|
||||
private val errorPatternTimings = longArrayOf(
|
||||
@@ -17,7 +15,9 @@ private val errorPatternAmplitudes = intArrayOf(
|
||||
255, 0, 255, 0, 255
|
||||
)
|
||||
|
||||
fun Context.getVibrator(): Vibrator = if (
|
||||
// On SDK 31 and better, we should ask the `VIBRATOR_MANAGER_SERVICE`
|
||||
// for the default vibrator. This was implemented here before:
|
||||
/*fun Context.getVibrator(): Vibrator = if (
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.S
|
||||
) {
|
||||
@Suppress("DEPRECATION")
|
||||
@@ -26,12 +26,18 @@ fun Context.getVibrator(): Vibrator = if (
|
||||
(getSystemService(
|
||||
Context.VIBRATOR_MANAGER_SERVICE
|
||||
) as VibratorManager).defaultVibrator
|
||||
}
|
||||
}*/
|
||||
// But for reasons beyond my interests, using `VIBRATOR_MANAGER_SERVICE`
|
||||
// leads to a very cryptic `java.lang.VerifyError: r0/b` on Android 4.
|
||||
// This is probably a Proguard/R8 issue, but I don't want to waste more
|
||||
// time just to get rid of the deprecation warning. So let's use the old
|
||||
// `VIBRATOR_SERVICE` and wait for Google to fix their stuff.
|
||||
fun Context.getVibrator(): Vibrator = getSystemService(
|
||||
Context.VIBRATOR_SERVICE
|
||||
) as Vibrator
|
||||
|
||||
fun Vibrator.vibrate() {
|
||||
if (!prefs.vibrate) {
|
||||
return
|
||||
} else if (beforeO) {
|
||||
if (beforeO) {
|
||||
@Suppress("DEPRECATION")
|
||||
vibrate(DURATION_IN_MS)
|
||||
} else {
|
||||
@@ -45,9 +51,7 @@ fun Vibrator.vibrate() {
|
||||
}
|
||||
|
||||
fun Vibrator.error() {
|
||||
if (!prefs.vibrate) {
|
||||
return
|
||||
} else if (beforeO) {
|
||||
if (beforeO) {
|
||||
@Suppress("DEPRECATION")
|
||||
vibrate(errorPatternTimings, -1)
|
||||
} else {
|
||||
|
||||
@@ -2,31 +2,33 @@ package de.markusfisch.android.binaryeye.preference
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.media.ToneGenerator
|
||||
import android.os.Build
|
||||
import android.preference.PreferenceManager
|
||||
import android.support.annotation.RequiresApi
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Format
|
||||
|
||||
class Preferences {
|
||||
lateinit var preferences: SharedPreferences
|
||||
|
||||
var barcodeFormats = setOf(
|
||||
"AZTEC",
|
||||
"CODABAR",
|
||||
"CODE_39",
|
||||
"CODE_93",
|
||||
"CODE_128",
|
||||
"DATA_MATRIX",
|
||||
"EAN_8",
|
||||
"EAN_13",
|
||||
"ITF",
|
||||
"MAXICODE",
|
||||
"PDF_417",
|
||||
"QR_CODE",
|
||||
"RSS_14",
|
||||
"RSS_EXPANDED",
|
||||
"UPC_A",
|
||||
"UPC_E",
|
||||
"UPC_EAN_EXTENSION"
|
||||
Format.AZTEC.name,
|
||||
Format.CODABAR.name,
|
||||
Format.CODE_39.name,
|
||||
Format.CODE_93.name,
|
||||
Format.CODE_128.name,
|
||||
Format.DATA_BAR.name,
|
||||
Format.DATA_BAR_EXPANDED.name,
|
||||
Format.DATA_MATRIX.name,
|
||||
Format.EAN_8.name,
|
||||
Format.EAN_13.name,
|
||||
Format.ITF.name,
|
||||
Format.MAXICODE.name,
|
||||
Format.PDF_417.name,
|
||||
Format.QR_CODE.name,
|
||||
Format.MICRO_QR_CODE.name,
|
||||
Format.UPC_A.name,
|
||||
Format.UPC_E.name,
|
||||
)
|
||||
@RequiresApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
set(value) {
|
||||
@@ -58,39 +60,29 @@ class Preferences {
|
||||
apply(ZOOM_BY_SWIPING, value)
|
||||
field = value
|
||||
}
|
||||
var autoRotate = false
|
||||
var autoRotate = true
|
||||
set(value) {
|
||||
// Immediately save this setting before it shouldn't change
|
||||
// on the fly while scanning.
|
||||
commit(AUTO_ROTATE, value)
|
||||
apply(AUTO_ROTATE, value)
|
||||
field = value
|
||||
}
|
||||
var tryHarder = false
|
||||
set(value) {
|
||||
// Immediately save this setting because it's only ever read
|
||||
// before the camera is opened.
|
||||
commit(TRY_HARDER, value)
|
||||
apply(TRY_HARDER, value)
|
||||
field = value
|
||||
}
|
||||
var bulkMode = false
|
||||
set(value) {
|
||||
// Immediately save this setting because it's only ever read
|
||||
// before the camera is opened.
|
||||
commit(BULK_MODE, value)
|
||||
apply(BULK_MODE, value)
|
||||
field = value
|
||||
}
|
||||
var bulkModeDelay = "500"
|
||||
set(value) {
|
||||
// Immediately save this setting because it's only ever read
|
||||
// before the camera is opened.
|
||||
commit(BULK_MODE_DELAY, value)
|
||||
apply(BULK_MODE_DELAY, value)
|
||||
field = value
|
||||
}
|
||||
var showToastInBulkMode = true
|
||||
set(value) {
|
||||
// Immediately save this setting because it's only ever read
|
||||
// before the camera is opened.
|
||||
commit(SHOW_TOAST_IN_BULK_MODE, value)
|
||||
apply(SHOW_TOAST_IN_BULK_MODE, value)
|
||||
field = value
|
||||
}
|
||||
var vibrate = true
|
||||
@@ -98,6 +90,16 @@ class Preferences {
|
||||
apply(VIBRATE, value)
|
||||
field = value
|
||||
}
|
||||
var beep = false
|
||||
set(value) {
|
||||
apply(BEEP, value)
|
||||
field = value
|
||||
}
|
||||
var beepToneName = "tone_prop_beep"
|
||||
set(value) {
|
||||
apply(BEEP_TONE_NAME, value)
|
||||
field = value
|
||||
}
|
||||
var useHistory = false
|
||||
set(value) {
|
||||
apply(USE_HISTORY, value)
|
||||
@@ -123,16 +125,16 @@ class Preferences {
|
||||
apply(SHOW_META_DATA, value)
|
||||
field = value
|
||||
}
|
||||
var showQrVersion = false
|
||||
set(value) {
|
||||
apply(SHOW_QR_VERSION, value)
|
||||
field = value
|
||||
}
|
||||
var showHexDump = true
|
||||
set(value) {
|
||||
apply(SHOW_HEX_DUMP, value)
|
||||
field = value
|
||||
}
|
||||
var showRecreation = true
|
||||
set(value) {
|
||||
apply(SHOW_RECREATION, value)
|
||||
field = value
|
||||
}
|
||||
var closeAutomatically = false
|
||||
set(value) {
|
||||
apply(CLOSE_AUTOMATICALLY, value)
|
||||
@@ -173,11 +175,9 @@ class Preferences {
|
||||
apply(INDEX_OF_LAST_SELECTED_FORMAT, value)
|
||||
field = value
|
||||
}
|
||||
var forceCompat = false
|
||||
var freeRotation = true
|
||||
set(value) {
|
||||
// Since the app may be about to crash when forceCompat is set,
|
||||
// it's necessary to `commit()` this synchronously.
|
||||
commit(FORCE_COMPAT, value)
|
||||
apply(FREE_ROTATION, value)
|
||||
field = value
|
||||
}
|
||||
|
||||
@@ -215,6 +215,10 @@ class Preferences {
|
||||
showToastInBulkMode
|
||||
)
|
||||
vibrate = preferences.getBoolean(VIBRATE, vibrate)
|
||||
beep = preferences.getBoolean(BEEP, beep)
|
||||
preferences.getString(BEEP_TONE_NAME, beepToneName)?.also {
|
||||
beepToneName = it
|
||||
}
|
||||
useHistory = preferences.getBoolean(USE_HISTORY, useHistory)
|
||||
ignoreConsecutiveDuplicates = preferences.getBoolean(
|
||||
IGNORE_CONSECUTIVE_DUPLICATES,
|
||||
@@ -229,8 +233,8 @@ class Preferences {
|
||||
openImmediately
|
||||
)
|
||||
showMetaData = preferences.getBoolean(SHOW_META_DATA, showMetaData)
|
||||
showQrVersion = preferences.getBoolean(SHOW_QR_VERSION, showQrVersion)
|
||||
showHexDump = preferences.getBoolean(SHOW_HEX_DUMP, showHexDump)
|
||||
showRecreation = preferences.getBoolean(SHOW_RECREATION, showRecreation)
|
||||
closeAutomatically = preferences.getBoolean(
|
||||
CLOSE_AUTOMATICALLY,
|
||||
closeAutomatically
|
||||
@@ -258,7 +262,16 @@ class Preferences {
|
||||
INDEX_OF_LAST_SELECTED_FORMAT,
|
||||
indexOfLastSelectedFormat
|
||||
)
|
||||
forceCompat = preferences.getBoolean(FORCE_COMPAT, forceCompat)
|
||||
freeRotation = preferences.getBoolean(FREE_ROTATION, freeRotation)
|
||||
}
|
||||
|
||||
fun beepTone() = when (beepToneName) {
|
||||
"tone_cdma_confirm" -> ToneGenerator.TONE_CDMA_CONFIRM
|
||||
"tone_sup_radio_ack" -> ToneGenerator.TONE_SUP_RADIO_ACK
|
||||
"tone_prop_ack" -> ToneGenerator.TONE_PROP_ACK
|
||||
"tone_prop_beep" -> ToneGenerator.TONE_PROP_BEEP
|
||||
"tone_prop_beep2" -> ToneGenerator.TONE_PROP_BEEP2
|
||||
else -> ToneGenerator.TONE_PROP_BEEP
|
||||
}
|
||||
|
||||
private fun put(label: String, value: Boolean) =
|
||||
@@ -267,14 +280,6 @@ class Preferences {
|
||||
private fun put(label: String, value: String) =
|
||||
preferences.edit().putString(label, value)
|
||||
|
||||
private fun commit(label: String, value: Boolean) {
|
||||
put(label, value).commit()
|
||||
}
|
||||
|
||||
private fun commit(label: String, value: String) {
|
||||
put(label, value).commit()
|
||||
}
|
||||
|
||||
private fun apply(label: String, value: Boolean) {
|
||||
put(label, value).apply()
|
||||
}
|
||||
@@ -293,7 +298,7 @@ class Preferences {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val BARCODE_FORMATS = "barcode_formats"
|
||||
private const val BARCODE_FORMATS = "formats"
|
||||
private const val CROP_HANDLE_X = "crop_handle_x"
|
||||
private const val CROP_HANDLE_Y = "crop_handle_y"
|
||||
private const val CROP_HANDLE_ORIENTATION = "crop_handle_orientation"
|
||||
@@ -305,13 +310,15 @@ class Preferences {
|
||||
private const val BULK_MODE_DELAY = "bulk_mode_delay"
|
||||
private const val SHOW_TOAST_IN_BULK_MODE = "show_toast_in_bulk_mode"
|
||||
private const val VIBRATE = "vibrate"
|
||||
private const val BEEP = "beep"
|
||||
private const val BEEP_TONE_NAME = "beep_tone_name"
|
||||
private const val USE_HISTORY = "use_history"
|
||||
private const val IGNORE_CONSECUTIVE_DUPLICATES = "ignore_consecutive_duplicates"
|
||||
private const val OPEN_IMMEDIATELY = "open_immediately"
|
||||
private const val COPY_IMMEDIATELY = "copy_immediately"
|
||||
private const val SHOW_META_DATA = "show_meta_data"
|
||||
private const val SHOW_QR_VERSION = "show_qr_version"
|
||||
private const val SHOW_HEX_DUMP = "show_hex_dump"
|
||||
private const val SHOW_RECREATION = "show_recreation"
|
||||
private const val CLOSE_AUTOMATICALLY = "close_automatically"
|
||||
private const val DEFAULT_SEARCH_URL = "default_search_url"
|
||||
private const val OPEN_WITH_URL = "open_with_url"
|
||||
@@ -320,6 +327,6 @@ class Preferences {
|
||||
private const val SEND_SCAN_TYPE = "send_scan_type"
|
||||
private const val CUSTOM_LOCALE = "custom_locale"
|
||||
private const val INDEX_OF_LAST_SELECTED_FORMAT = "index_of_last_selected_format"
|
||||
private const val FORCE_COMPAT = "force_compat"
|
||||
private const val FREE_ROTATION = "free_rotation"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package de.markusfisch.android.binaryeye.rs
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.support.v8.renderscript.Allocation
|
||||
import android.support.v8.renderscript.RenderScript
|
||||
|
||||
fun fixTransparency(rs: RenderScript, bitmap: Bitmap?): Bitmap? {
|
||||
bitmap ?: return null
|
||||
val result = analyze(rs, bitmap)
|
||||
return if (result.hasTransparentPixels) {
|
||||
val copy = Bitmap.createBitmap(
|
||||
bitmap.width,
|
||||
bitmap.height,
|
||||
bitmap.config
|
||||
)
|
||||
Canvas(copy).apply {
|
||||
drawColor(result.backgroundColor)
|
||||
drawBitmap(bitmap, 0f, 0f, null)
|
||||
}
|
||||
copy
|
||||
} else {
|
||||
bitmap
|
||||
}
|
||||
}
|
||||
|
||||
private fun analyze(rs: RenderScript, bitmap: Bitmap): Result {
|
||||
val analyzeScript = ScriptC_analyze(rs)
|
||||
val bitmapAllocation = Allocation.createFromBitmap(rs, bitmap)
|
||||
val result = analyzeScript.reduce_analyze(bitmapAllocation).get()
|
||||
bitmapAllocation.destroy()
|
||||
analyzeScript.destroy()
|
||||
return Result(
|
||||
result.x > 0,
|
||||
if (result.y > 0) 0xff000000.toInt() else 0xffffffff.toInt()
|
||||
)
|
||||
}
|
||||
|
||||
private data class Result(
|
||||
val hasTransparentPixels: Boolean,
|
||||
val backgroundColor: Int
|
||||
)
|
||||
@@ -1,156 +0,0 @@
|
||||
package de.markusfisch.android.binaryeye.rs
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.support.v8.renderscript.*
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
private const val SCALE_FACTOR = .75f
|
||||
|
||||
class Preprocessor(
|
||||
rs: RenderScript,
|
||||
width: Int,
|
||||
height: Int,
|
||||
private val roi: Rect?
|
||||
) {
|
||||
var outWidth = 0
|
||||
var outHeight = 0
|
||||
|
||||
private val resizeScript = ScriptIntrinsicResize.create(rs)
|
||||
private val rotateScript = ScriptC_rotate(rs)
|
||||
|
||||
private var yuvType: Type? = null
|
||||
private var yuvAlloc: Allocation? = null
|
||||
private var roiType: Type? = null
|
||||
private var roiAlloc: Allocation? = null
|
||||
private var resizedType: Type? = null
|
||||
private var resizedAlloc: Allocation? = null
|
||||
private var rotatedType: Type? = null
|
||||
private var rotatedAlloc: Allocation? = null
|
||||
|
||||
init {
|
||||
yuvType = Type.createXY(
|
||||
rs,
|
||||
Element.U8(rs),
|
||||
width,
|
||||
height // use only grayscale part
|
||||
)
|
||||
yuvAlloc = Allocation.createTyped(
|
||||
rs,
|
||||
yuvType,
|
||||
Allocation.USAGE_SCRIPT
|
||||
)
|
||||
|
||||
if (roi != null) {
|
||||
val roiWidth = roi.width()
|
||||
val roiHeight = roi.height()
|
||||
|
||||
roiType = Type.createXY(
|
||||
rs,
|
||||
Element.U8(rs),
|
||||
roiWidth,
|
||||
roiHeight
|
||||
)
|
||||
roiAlloc = Allocation.createTyped(
|
||||
rs,
|
||||
roiType,
|
||||
Allocation.USAGE_SCRIPT
|
||||
)
|
||||
|
||||
outWidth = (roiWidth * SCALE_FACTOR).roundToInt()
|
||||
outHeight = (roiHeight * SCALE_FACTOR).roundToInt()
|
||||
|
||||
// Make sure the dimensions are always a multiple of 4.
|
||||
outWidth -= outWidth % 4
|
||||
outHeight -= outHeight % 4
|
||||
|
||||
// Make sure the dimensions are always greater than 4.
|
||||
outWidth = max(4, outWidth)
|
||||
outHeight = max(4, outHeight)
|
||||
} else {
|
||||
outWidth = (width * SCALE_FACTOR).roundToInt()
|
||||
outHeight = (height * SCALE_FACTOR).roundToInt()
|
||||
}
|
||||
|
||||
resizedType = Type.createXY(
|
||||
rs,
|
||||
Element.U8(rs),
|
||||
outWidth,
|
||||
outHeight
|
||||
)
|
||||
resizedAlloc = Allocation.createTyped(
|
||||
rs,
|
||||
resizedType,
|
||||
Allocation.USAGE_SCRIPT
|
||||
)
|
||||
|
||||
rotatedType = Type.createXY(
|
||||
rs,
|
||||
Element.U8(rs),
|
||||
outHeight,
|
||||
outWidth
|
||||
)
|
||||
rotatedAlloc = Allocation.createTyped(
|
||||
rs,
|
||||
rotatedType,
|
||||
Allocation.USAGE_SCRIPT
|
||||
)
|
||||
}
|
||||
|
||||
fun destroy() {
|
||||
yuvType?.destroy()
|
||||
yuvType = null
|
||||
yuvAlloc?.destroy()
|
||||
yuvAlloc = null
|
||||
roiType?.destroy()
|
||||
roiType = null
|
||||
roiAlloc?.destroy()
|
||||
roiAlloc = null
|
||||
resizedType?.destroy()
|
||||
resizedType = null
|
||||
resizedAlloc?.destroy()
|
||||
resizedAlloc = null
|
||||
rotatedType?.destroy()
|
||||
rotatedType = null
|
||||
rotatedAlloc?.destroy()
|
||||
rotatedAlloc = null
|
||||
resizeScript.destroy()
|
||||
rotateScript.destroy()
|
||||
}
|
||||
|
||||
fun resizeOnly(frame: ByteArray) {
|
||||
resize(frame)
|
||||
resizedAlloc?.copyTo(frame)
|
||||
}
|
||||
|
||||
fun resizeAndRotate(frame: ByteArray) {
|
||||
resize(frame)
|
||||
val t = resizedType ?: return
|
||||
rotateScript._inImage = resizedAlloc
|
||||
rotateScript._inWidth = t.x
|
||||
rotateScript._inHeight = t.y
|
||||
rotateScript.forEach_rotate90(
|
||||
rotatedAlloc, // Ignored in kernel, just to satisfy forEach.
|
||||
rotatedAlloc
|
||||
)
|
||||
rotatedAlloc?.copyTo(frame)
|
||||
}
|
||||
|
||||
private fun resize(frame: ByteArray) {
|
||||
yuvAlloc?.copyFrom(frame)
|
||||
resizeScript.setInput(
|
||||
if (roi != null) {
|
||||
roiAlloc?.copy2DRangeFrom(
|
||||
0, 0,
|
||||
roi.width(), roi.height(),
|
||||
yuvAlloc,
|
||||
max(0, roi.left), max(0, roi.top)
|
||||
)
|
||||
roiAlloc
|
||||
} else {
|
||||
yuvAlloc
|
||||
}
|
||||
)
|
||||
resizeScript.forEach_bicubic(resizedAlloc)
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,10 @@ import de.markusfisch.android.binaryeye.activity.CameraActivity
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
class ScanTileService : TileService() {
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
override fun onClick() {
|
||||
super.onClick()
|
||||
val intent = Intent(applicationContext, CameraActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
startActivityAndCollapse(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package de.markusfisch.android.binaryeye.view
|
||||
|
||||
import android.content.Context
|
||||
import android.media.AudioManager
|
||||
import de.markusfisch.android.binaryeye.app.prefs
|
||||
import de.markusfisch.android.binaryeye.media.beepConfirm
|
||||
import de.markusfisch.android.binaryeye.media.beepError
|
||||
import de.markusfisch.android.binaryeye.os.error
|
||||
import de.markusfisch.android.binaryeye.os.getVibrator
|
||||
import de.markusfisch.android.binaryeye.os.vibrate
|
||||
|
||||
fun Context.scanFeedback() {
|
||||
if (prefs.vibrate) {
|
||||
getVibrator().vibrate()
|
||||
}
|
||||
if (prefs.beep && !isSilent()) {
|
||||
beepConfirm()
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.errorFeedback() {
|
||||
if (prefs.vibrate) {
|
||||
getVibrator().error()
|
||||
}
|
||||
if (!isSilent()) {
|
||||
beepError()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Context.isSilent(): Boolean {
|
||||
val am = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
return when (am.ringerMode) {
|
||||
AudioManager.RINGER_MODE_SILENT,
|
||||
AudioManager.RINGER_MODE_VIBRATE -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@@ -100,14 +100,15 @@ class DetectorView : View {
|
||||
}
|
||||
|
||||
private fun setCropHandlePos(x: Int, y: Int, orientation: Int) {
|
||||
// Always set handlePos even if it's invalid because
|
||||
// handlePos.x may be -2 which is a signal to set the
|
||||
// default ROI.
|
||||
if (orientation == currentOrientation) {
|
||||
handlePos.set(x, y)
|
||||
} else {
|
||||
handlePos.set(y, x)
|
||||
}
|
||||
if (x > -1) {
|
||||
handleActive = true
|
||||
}
|
||||
handleActive = handlePos.x > -1
|
||||
}
|
||||
|
||||
fun update(numberOfCoordinates: Int) {
|
||||
@@ -164,8 +165,8 @@ class DetectorView : View {
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
if (handleGrabbed) {
|
||||
handlePos.set(x, y)
|
||||
handleActive =
|
||||
handleActive or (distSq(handlePos, touchDown) > minMoveThresholdSq)
|
||||
handleActive = handleActive ||
|
||||
distSq(handlePos, touchDown) > minMoveThresholdSq
|
||||
if (handleActive) {
|
||||
updateClipRect()
|
||||
invalidate()
|
||||
@@ -216,10 +217,10 @@ class DetectorView : View {
|
||||
val cy = clampY(y)
|
||||
val dx = abs(cx - center.x)
|
||||
val dy = abs(cy - center.y)
|
||||
// check if handle is close to the vertical or horizontal center line
|
||||
// Check if handle is close to the vertical or horizontal center line.
|
||||
if (dx < distToFull ||
|
||||
dy < distToFull ||
|
||||
// check if handle is close to a screen corner
|
||||
// Check if handle is close to a screen corner.
|
||||
((abs(cy - minY) < distToFull || abs(maxY - cy) < distToFull) &&
|
||||
abs(dx - center.x) < distToFull)
|
||||
) {
|
||||
@@ -260,23 +261,18 @@ class DetectorView : View {
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
if (handleActive) {
|
||||
drawClip(canvas)
|
||||
canvas.drawClip()
|
||||
}
|
||||
drawDots(canvas)
|
||||
canvas.drawDots()
|
||||
if (prefs.showCropHandle) {
|
||||
canvas.drawBitmap(
|
||||
handleBitmap,
|
||||
(handlePos.x - handleXRadius).toFloat(),
|
||||
(handlePos.y - handleYRadius).toFloat(),
|
||||
null
|
||||
)
|
||||
canvas.drawHandle()
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawDots(canvas: Canvas) {
|
||||
private fun Canvas.drawDots() {
|
||||
var i = 0
|
||||
while (i < coordinatesLast) {
|
||||
canvas.drawCircle(
|
||||
drawCircle(
|
||||
coordinates[i++],
|
||||
coordinates[i++],
|
||||
dotRadius,
|
||||
@@ -285,15 +281,15 @@ class DetectorView : View {
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawClip(canvas: Canvas) {
|
||||
private fun Canvas.drawClip() {
|
||||
if (minDist < 1) {
|
||||
return
|
||||
}
|
||||
// canvas.clipRect() doesn't work reliably below KITKAT.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
val radius = min(minDist / 2, cornerRadius).toFloat()
|
||||
canvas.save()
|
||||
canvas.clipOutPathCompat(
|
||||
save()
|
||||
clipOutPathCompat(
|
||||
calculateRoundedRectPath(
|
||||
roi.left.toFloat(),
|
||||
roi.top.toFloat(),
|
||||
@@ -303,13 +299,22 @@ class DetectorView : View {
|
||||
radius
|
||||
)
|
||||
)
|
||||
canvas.drawColor(shadeColor)
|
||||
canvas.restore()
|
||||
drawColor(shadeColor)
|
||||
restore()
|
||||
} else {
|
||||
canvas.drawRect(roi, roiPaint)
|
||||
drawRect(roi, roiPaint)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Canvas.drawHandle() {
|
||||
drawBitmap(
|
||||
handleBitmap,
|
||||
(handlePos.x - handleXRadius).toFloat(),
|
||||
(handlePos.y - handleYRadius).toFloat(),
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateClipRect() {
|
||||
clampHandlePos()
|
||||
val dx = abs(handlePos.x - center.x)
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
package de.markusfisch.android.binaryeye.zxing
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import com.google.zxing.*
|
||||
import com.google.zxing.common.BitMatrix
|
||||
import com.google.zxing.common.HybridBinarizer
|
||||
import java.util.*
|
||||
|
||||
class Zxing(possibleResultPoint: ResultPointCallback? = null) {
|
||||
private val hints = EnumMap<DecodeHintType, Any>(DecodeHintType::class.java)
|
||||
private val multiFormatReader = MultiFormatReader()
|
||||
|
||||
init {
|
||||
possibleResultPoint?.let {
|
||||
hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK] = it
|
||||
}
|
||||
}
|
||||
|
||||
fun updateHints(tryHarder: Boolean, formats: Set<String>) {
|
||||
if (tryHarder) {
|
||||
hints[DecodeHintType.TRY_HARDER] = java.lang.Boolean.TRUE
|
||||
} else {
|
||||
hints.remove(DecodeHintType.TRY_HARDER)
|
||||
}
|
||||
setDecodeFormats(formats)
|
||||
}
|
||||
|
||||
private fun setDecodeFormats(formats: Set<String>) {
|
||||
hints[DecodeHintType.POSSIBLE_FORMATS] = EnumSet.noneOf(
|
||||
BarcodeFormat::class.java
|
||||
).apply {
|
||||
addAll(
|
||||
EnumSet.copyOf(
|
||||
formats.map { BarcodeFormat.valueOf(it) }
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun decode(
|
||||
yuvData: ByteArray,
|
||||
width: Int,
|
||||
height: Int,
|
||||
invert: Boolean = false
|
||||
): Result? = decodeLuminanceSource(
|
||||
PlanarYUVLuminanceSource(
|
||||
yuvData,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
false
|
||||
),
|
||||
invert
|
||||
)
|
||||
|
||||
fun decodePositiveNegative(bitmap: Bitmap): Result? =
|
||||
decode(bitmap, false) ?: decode(bitmap, true)
|
||||
|
||||
private fun decode(
|
||||
bitmap: Bitmap,
|
||||
invert: Boolean = false
|
||||
): Result? {
|
||||
val width = bitmap.width
|
||||
val height = bitmap.height
|
||||
val pixels = IntArray(width * height)
|
||||
if (bitmap.config != Bitmap.Config.ARGB_8888) {
|
||||
bitmap.copy(Bitmap.Config.ARGB_8888, true)
|
||||
} else {
|
||||
bitmap
|
||||
}.getPixels(pixels, 0, width, 0, 0, width, height)
|
||||
return decodeLuminanceSource(
|
||||
RGBLuminanceSource(width, height, pixels),
|
||||
invert
|
||||
)
|
||||
}
|
||||
|
||||
private fun decodeLuminanceSource(
|
||||
source: LuminanceSource,
|
||||
invert: Boolean
|
||||
): Result? = decodeLuminanceSource(
|
||||
if (invert) {
|
||||
source.invert()
|
||||
} else {
|
||||
source
|
||||
}
|
||||
)
|
||||
|
||||
private fun decodeLuminanceSource(source: LuminanceSource): Result? = try {
|
||||
multiFormatReader.decode(
|
||||
BinaryBitmap(HybridBinarizer(source)),
|
||||
hints
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
// Usually it's bad practice to blindly catch *all* exceptions
|
||||
// because this can hide problems we want to know about. But
|
||||
// since ZXing has some errors (like all software) and I don't
|
||||
// want this app to break in the hands of my users, which won't
|
||||
// see the stack trace anyway, it's better to just catch all
|
||||
// exceptions here and live on.
|
||||
null
|
||||
} finally {
|
||||
multiFormatReader.reset()
|
||||
}
|
||||
}
|
||||
|
||||
private const val BLACK = 0xff000000.toInt()
|
||||
private const val WHITE = 0xffffffff.toInt()
|
||||
|
||||
fun encodeAsBitmap(
|
||||
text: String,
|
||||
format: BarcodeFormat,
|
||||
width: Int,
|
||||
height: Int,
|
||||
hints: EnumMap<EncodeHintType, Any>? = null
|
||||
): Bitmap? {
|
||||
val bitMatrix = encode(text, format, hints, width, height)
|
||||
val w = bitMatrix.width
|
||||
val h = bitMatrix.height
|
||||
val pixels = IntArray(w * h)
|
||||
var offset = 0
|
||||
for (y in 0 until h) {
|
||||
for (x in 0 until w) {
|
||||
pixels[offset + x] = if (bitMatrix.get(x, y)) {
|
||||
BLACK
|
||||
} else {
|
||||
WHITE
|
||||
}
|
||||
}
|
||||
offset += w
|
||||
}
|
||||
val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
|
||||
bitmap.setPixels(pixels, 0, w, 0, 0, w, h)
|
||||
return bitmap
|
||||
}
|
||||
|
||||
fun encodeAsSvg(
|
||||
text: String,
|
||||
format: BarcodeFormat,
|
||||
hints: EnumMap<EncodeHintType, Any>? = null
|
||||
): String {
|
||||
val bitMatrix = encode(text, format, hints)
|
||||
val sb = StringBuilder()
|
||||
val w = bitMatrix.width
|
||||
var h = bitMatrix.height
|
||||
val moduleHeight = if (h == 1) w / 2 else 1
|
||||
for (y in 0 until h) {
|
||||
for (x in 0 until w) {
|
||||
if (bitMatrix.get(x, y)) {
|
||||
sb.append(" M${x},${y}h1v${moduleHeight}h-1z")
|
||||
}
|
||||
}
|
||||
}
|
||||
h *= moduleHeight
|
||||
return """<svg width="$w" height="$h"
|
||||
viewBox="0 0 $w $h"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="$sb"/>
|
||||
</svg>
|
||||
"""
|
||||
}
|
||||
|
||||
fun encodeAsText(
|
||||
text: String,
|
||||
format: BarcodeFormat,
|
||||
hints: EnumMap<EncodeHintType, Any>? = null
|
||||
): String {
|
||||
val bitMatrix = encode(text, format, hints)
|
||||
val w = bitMatrix.width
|
||||
val h = bitMatrix.height
|
||||
val sb = StringBuilder()
|
||||
for (y in 0 until h) {
|
||||
for (x in 0 until w) {
|
||||
sb.append(if (bitMatrix.get(x, y)) "█" else " ")
|
||||
}
|
||||
sb.append("\n")
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
private fun encode(
|
||||
text: String,
|
||||
format: BarcodeFormat,
|
||||
encodeHints: EnumMap<EncodeHintType, Any>? = null,
|
||||
width: Int = 0,
|
||||
height: Int = 0
|
||||
): BitMatrix = MultiFormatWriter().encode(
|
||||
text, format, width, height,
|
||||
(encodeHints ?: EnumMap<EncodeHintType, Any>(EncodeHintType::class.java)).apply {
|
||||
if (!contains(EncodeHintType.CHARACTER_SET)) {
|
||||
this[EncodeHintType.CHARACTER_SET] = "utf-8"
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -1,3 +1,3 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M3 11h8V3H3v8zm2-6h4v4H5V5zM3 21h8v-8H3v8zm2-6h4v4H5v-4zm8-12v8h8V3h-8zm6 6h-4V5h4v4zm0 10h2v2h-2zm-6-6h2v2h-2zm2 2h2v2h-2zm-2 2h2v2h-2zm2 2h2v2h-2zm2-2h2v2h-2zm0-4h2v2h-2zm2 2h2v2h-2z"/>
|
||||
<path android:fillColor="#FF000000" android:pathData="M3 11h8V3H3v8zm2-6h4v4H5V5zM3 21h8v-8H3v8zm2-6h4v4H5v-4zm8-12v8h8V3h-8zm6 6h-4V5h4v4zm0 10h2v2h-2zm-6-6h2v2h-2zm2 2h2v2h-2zm-2 2h2v2h-2zm2 2h2v2h-2zm2-2h2v2h-2zm0-4h2v2h-2zm2 2h2v2h-2z"/>
|
||||
</vector>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#ffffff" android:pathData="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 0.9-2 2v10c0 1.1 0.9 2 2 2h12c1.1 0 2-0.9 2-2V10c0-1.1-0.9-2-2-2zm-6 9c-1.1 0-2-0.9-2-2s0.9-2 2-2 2 0.9 2 2-0.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,3 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#ffffff" android:pathData="M12 17c1.1 0 2-0.9 2-2s-0.9-2-2-2-2 0.9-2 2 0.9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 0.9-2 2v10c0 1.1 0.9 2 2 2h12c1.1 0 2-0.9 2-2V10c0-1.1-0.9-2-2-2zm0 12H6V10h12v10z"/>
|
||||
</vector>
|
||||
@@ -1,5 +1,20 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="90dp" android:height="90dp" android:viewportWidth="90" android:viewportHeight="90">
|
||||
<path android:fillColor="#FF000000" android:pathData="M27 45a18 18 0 1 1 36 0 18 18 0 1 1-36 0" android:strokeWidth="4"/>
|
||||
<path android:pathData="M31.738 45a13.262 13.262 0 1 1 26.524 0 13.262 13.262 0 1 1-26.524 0" android:strokeWidth="4" android:fillColor="#ffffff"/>
|
||||
<path android:pathData="M54.41 45c0 2.303-0.827 4.412-2.201 6.048V38.952c1.374 1.636 2.201 3.745 2.201 6.048zM45 54.41c-0.27 0-0.537-0.012-0.801-0.034V35.624C44.463 35.602 44.73 35.59 45 35.59s0.537 0.012 0.801 0.034v18.752C45.537 54.398 45.27 54.41 45 54.41zM35.59 45c0-2.303 0.827-4.412 2.201-6.048v12.096C36.417 49.412 35.59 47.303 35.59 45zm13.415 8.517c-0.511 0.241-1.046 0.437-1.602 0.583V35.9c0.556 0.146 1.091 0.342 1.602 0.583v17.034zM42.597 54.1c-1.173-0.309-2.257-0.839-3.204-1.542V37.442c0.947-0.703 2.031-1.233 3.204-1.542v18.2z" android:strokeWidth="4" android:fillColor="#000000"/>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="90dp"
|
||||
android:height="90dp"
|
||||
android:viewportWidth="90"
|
||||
android:viewportHeight="90">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M58.262,45C58.262,52.324 52.324,58.262 45,58.262C37.676,58.262 31.738,52.324 31.738,45C31.738,37.676 37.676,31.738 45,31.738C52.324,31.738 58.262,37.676 58.262,45ZM45,27C35.059,27 27,35.059 27,45C27,54.941 35.059,63 45,63C54.941,63 63,54.941 63,45C63,35.059 54.941,27 45,27Z"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="4"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeLineCap="butt"/>
|
||||
<path
|
||||
android:pathData="M54.41,45C54.41,47.303 53.583,49.412 52.209,51.048L52.209,38.952C53.583,40.588 54.41,42.697 54.41,45ZM45,54.41C44.73,54.41 44.463,54.398 44.199,54.376L44.199,35.624C44.463,35.602 44.73,35.59 45,35.59C45.27,35.59 45.537,35.602 45.801,35.624L45.801,54.376C45.537,54.398 45.27,54.41 45,54.41ZM35.59,45C35.59,42.697 36.417,40.588 37.791,38.952L37.791,51.048C36.417,49.412 35.59,47.303 35.59,45ZM49.005,53.517C48.494,53.758 47.959,53.954 47.403,54.1L47.403,35.9C47.959,36.046 48.494,36.242 49.005,36.483L49.005,53.517ZM42.597,54.1C41.424,53.791 40.34,53.261 39.393,52.558L39.393,37.442C40.34,36.739 41.424,36.209 42.597,35.9L42.597,54.1Z"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="4"
|
||||
android:fillColor="#000000"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeLineCap="butt"/>
|
||||
</vector>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@color/selected_row"
|
||||
<item android:drawable="@color/pressed_row"
|
||||
android:state_pressed="true"/>
|
||||
<item android:drawable="@color/selected_row"
|
||||
android:state_selected="true"/>
|
||||
<item android:drawable="@android:color/transparent"/>
|
||||
</selector>
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
style="@style/FAB"
|
||||
android:id="@+id/scan"
|
||||
android:contentDescription="@string/scan_code"
|
||||
android:src="@drawable/ic_action_search"/>
|
||||
android:src="@drawable/ic_action_next"/>
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
</merge>
|
||||
|
||||
@@ -8,18 +8,15 @@
|
||||
android:clipToPadding="false"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
<EditText
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:gravity="start|top"
|
||||
android:hint="@string/content"
|
||||
android:imeOptions="flagNoExtractUi"
|
||||
@@ -32,43 +29,42 @@
|
||||
android:id="@+id/format"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="end|top"/>
|
||||
<TableLayout
|
||||
android:id="@+id/data"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/format"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"/>
|
||||
android:layout_marginBottom="16dp"/>
|
||||
<TableLayout
|
||||
android:id="@+id/meta"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/data"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"/>
|
||||
android:layout_marginBottom="16dp"/>
|
||||
<TextView
|
||||
android:id="@+id/hex"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/meta"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:typeface="monospace"
|
||||
android:textSize="12sp"
|
||||
tools:text="54 65 73 74 20 51 52 20 Test QR\n43 6F 64 65 Code"/>
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
android:id="@+id/stamp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textSize="12sp"
|
||||
android:typeface="monospace"/>
|
||||
<ImageView
|
||||
android:id="@+id/recreation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_gravity="center"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@string/view_barcode"/>
|
||||
</LinearLayout>
|
||||
</de.markusfisch.android.binaryeye.widget.ConfinedScrollView>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
android:id="@+id/inset_layout"
|
||||
|
||||
@@ -35,6 +35,18 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:entries="@array/error_correction_levels"/>
|
||||
<TextView
|
||||
android:id="@+id/colors_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/colors"/>
|
||||
<Spinner
|
||||
android:id="@+id/colors"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:entries="@array/colors"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
android:id="@+id/scans"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:choiceMode="singleChoice"
|
||||
android:choiceMode="multipleChoice"
|
||||
android:clipToPadding="false"
|
||||
android:divider="@color/separator"
|
||||
android:dividerHeight="1px"/>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<ListView
|
||||
android:id="@+id/suggestions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:choiceMode="multipleChoice"
|
||||
android:clipToPadding="false"
|
||||
android:divider="@color/separator"
|
||||
android:dividerHeight="1px"/>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
android:id="@+id/inset_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/no_suggestions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:padding="32dp"
|
||||
android:text="@string/clear_network_suggestions_nothing_to_remove"/>
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
style="@style/FAB"
|
||||
android:id="@+id/remove"
|
||||
android:contentDescription="@string/remove_suggestion"
|
||||
android:src="@drawable/ic_action_remove"/>
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
</FrameLayout>
|
||||
@@ -1,6 +1,11 @@
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:material="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/toggle_free"
|
||||
android:title="@string/toggle_free_rotation"
|
||||
android:icon="@drawable/ic_action_rotation_unlocked"
|
||||
material:showAsAction="ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/rotate"
|
||||
android:title="@string/rotate_image_cw"
|
||||
|
||||
@@ -15,14 +15,20 @@
|
||||
<string name="error_correction_level_m" formatted="false">মধ্যম (~১৫% ঠিককরণ)</string>
|
||||
<string name="error_correction_level_q" formatted="false">বেশি (~২৫% ঠিককরণ)</string>
|
||||
<string name="error_correction_level_h" formatted="false">অনেক বেশি (~৩০% ঠিককরণ)</string>
|
||||
<string name="issue_number">সমস্যা ক্রম</string>
|
||||
<string name="orientation">দিক</string>
|
||||
<string name="other_meta_data">মেটাতথ্য</string>
|
||||
<string name="pdf417_extra_metadata">পিডিএফ৪১৭ মেটাতথ্য</string>
|
||||
<string name="possible_country">তৈরির সম্ভাব্য দেশ</string>
|
||||
<string name="suggested_price">প্রস্তসবিত দাম</string>
|
||||
<string name="upc_ean_extension">ইউপিসি ইএএন বর্ধিত</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">সমস্যা ক্রম</string>
|
||||
<string name="gtin_country">তৈরির সম্ভাব্য দেশ</string>
|
||||
<string name="gtin_price">প্রস্তসবিত দাম</string>
|
||||
<string name="gtin_add_on">ইউপিসি ইএএন বর্ধিত</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">আলো</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="share">ভাগ করো</string>
|
||||
@@ -75,6 +81,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">ধারাবাহিকভাবে তথ্য দেখানোর সময় মুহূর্তের জন্য তথ্য দেখাও।</string>
|
||||
<string name="vibrate">চিনলে কাঁপো</string>
|
||||
<string name="vibrate_summary">এটা সক্ষম রাখলে সংকেত চিনার সাথে সাথে কাঁপবে।</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">ইতিহাস সংরক্ষণ করো।</string>
|
||||
<string name="use_history_summary">সনাক্তকৃত সংকেত যন্ত্রে সংরক্ষণ করো।</string>
|
||||
<string name="ignore_consecutive_duplicates">দ্বিত্ব উপেক্ষা করো</string>
|
||||
@@ -85,10 +100,10 @@
|
||||
<string name="copy_immediately_summary">স্বয়ংক্রিয়ভাবে ক্লিপবোর্ডে অনুলিপি করো। বিশেষ দ্রষ্টব্য অন্য অ্যাপ পটভূমিতে এই তথ্য দেখে ফেলতে পারে।</string>
|
||||
<string name="show_meta_data">মেটাতথ্য দেখাও</string>
|
||||
<string name="show_meta_data_summary">সনাক্তকৃত বারকোড নিয়ে অতিরিক্ত তথ্য দেখাও।</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">ষড়(hex) সংকেত দেখাও</string>
|
||||
<string name="show_hex_dump_summary">পড়া তথ্যের ষড় সংকেত দেখাও</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">অনুলিপি/ভাগ করার পরে পিছনে যাও</string>
|
||||
<string name="close_automatically_summary">তথ্য অনুলিপি/ভাগ করার পরে স্বয়ংক্রিয়ভাবে পিছনে যাও।</string>
|
||||
<string name="default_search_engine">Open unknown data in</string>
|
||||
@@ -151,6 +166,7 @@
|
||||
<string name="export_database">এসকিউলাইট তথ্যভিত্তি</string>
|
||||
<string name="saved_in_downloads">ডাউনলোডে সংরক্ষিত</string>
|
||||
<string name="rotate_image_cw">ছবি ঘড়ির দিকে ঘুরাও</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">ছবি নাও</string>
|
||||
<string name="pick_code_to_scan">খুঁজার জন্য কোড নাও</string>
|
||||
<string name="shortcut_decode">বারকোড খুজো</string>
|
||||
@@ -167,4 +183,6 @@
|
||||
<string name="wifi_anonymous_identity">Anonymous identity</string>
|
||||
<string name="wifi_identity">Identity</string>
|
||||
<string name="wifi_phase2">Phase 2 method</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -17,14 +17,20 @@
|
||||
<string name="error_correction_level_m" formatted="false">Střední (~15% korekce)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Čtvrtinový (~25% korekce)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Vysoký (~30% korekce)</string>
|
||||
<string name="issue_number">Číslo edice</string>
|
||||
<string name="orientation">Orientace</string>
|
||||
<string name="other_meta_data">Metadata</string>
|
||||
<string name="pdf417_extra_metadata">PDF417 metadata</string>
|
||||
<string name="possible_country">Možná země původu</string>
|
||||
<string name="suggested_price">Doporučená cena</string>
|
||||
<string name="upc_ean_extension">rozšíření UPC EAN</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">Číslo edice</string>
|
||||
<string name="gtin_country">Možná země původu</string>
|
||||
<string name="gtin_price">Doporučená cena</string>
|
||||
<string name="gtin_add_on">rozšíření UPC EAN</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">Zap/vyp blesk</string>
|
||||
<string name="error_flash">Zapnutí/vypnutí blesku selhalo</string>
|
||||
<string name="share">Sdílet</string>
|
||||
@@ -77,6 +83,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">Krátce zobrazit data v módu nepřetržitého skenování.</string>
|
||||
<string name="vibrate">Zavibrovat při detekování</string>
|
||||
<string name="vibrate_summary">Zařízení zavibruje, když rozpozná čárový kód.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Ukládat historii skenování</string>
|
||||
<string name="use_history_summary">Rozpoznané kódy se uloží do zařízení.</string>
|
||||
<string name="ignore_consecutive_duplicates">Ignorovat duplikáty</string>
|
||||
@@ -87,10 +102,10 @@
|
||||
<string name="copy_immediately_summary">Automaticky zkopírovat naskenovaný obsah do schránky. Pozor, jiné aplikace jej mohou ze schránky přečíst, i když neběží.</string>
|
||||
<string name="show_meta_data">Zobrazit metadata</string>
|
||||
<string name="show_meta_data_summary">Zobrazí další data o naskenovaném čárovém kódu.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">Zobrazit hex dump</string>
|
||||
<string name="show_hex_dump_summary">Zobrazí hex dump naskenovaného obsahu.</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">Vrátit se po zkopírování/sdílení</string>
|
||||
<string name="close_automatically_summary">Po zkopírovaní či sdílení se automaticky vrátí na skenovací obrazovku.</string>
|
||||
<string name="default_search_engine">Nerozpoznaná data otevřít v</string>
|
||||
@@ -153,6 +168,7 @@
|
||||
<string name="export_database">SQLite databáze</string>
|
||||
<string name="saved_in_downloads">Uloženo do složky Stahování</string>
|
||||
<string name="rotate_image_cw">Otočit obrázek po směru hodinových ručiček</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">Vybrat obrázek</string>
|
||||
<string name="pick_code_to_scan">Vyberte kód k naskenování</string>
|
||||
<string name="shortcut_decode">Skenovat čárový kód</string>
|
||||
@@ -169,4 +185,6 @@
|
||||
<string name="wifi_anonymous_identity">Anonymní identita</string>
|
||||
<string name="wifi_identity">Identita</string>
|
||||
<string name="wifi_phase2">Ověření Phase 2</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">Denne app giver ingen mening uden adgang til kameraet. Farvel.</string>
|
||||
<string name="camera_error">Kan ikke få adgang til kamera, prøv igen</string>
|
||||
<string name="scan_code">Scan kode</string>
|
||||
<string name="compose_barcode">Opret stregkode</string>
|
||||
<string name="decode_barcode">Afkod stregkode</string>
|
||||
<string name="content">Indhold</string>
|
||||
<string name="binary_data">(binære data)</string>
|
||||
<plurals name="barcode_info">
|
||||
<item quantity="one">%2$d karakter, %1$s</item>
|
||||
<item quantity="other">%2$d karakterer, %1$s</item>
|
||||
</plurals>
|
||||
<string name="error_correction_level">Fejlkorrektionsniveau</string>
|
||||
<string name="error_correction_level_l" formatted="false">Lav (~7% korrigering)</string>
|
||||
<string name="error_correction_level_m" formatted="false">Medium (~15% korrigering)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Kvartil (~25% korrigering)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Høj (~30% korrigering)</string>
|
||||
<string name="colors">For- og baggrund</string>
|
||||
<string name="colors_black_on_white">Sort på hvidt</string>
|
||||
<string name="colors_white_on_black">Hvid på sort</string>
|
||||
<string name="colors_black_on_transparent">Sort på gennemsigtig</string>
|
||||
<string name="colors_white_on_transparent">Hvid på gennemsigtig</string>
|
||||
<string name="sequence_size">Sekvens størrelse</string>
|
||||
<string name="sequence_index">Sekvens indeks</string>
|
||||
<string name="sequence_id">Sekvens ID</string>
|
||||
<string name="gtin_issue_number">Udstedelsesnummer</string>
|
||||
<string name="gtin_country">Muligt fremstillingsland</string>
|
||||
<string name="gtin_price">Vejledende pris</string>
|
||||
<string name="gtin_add_on">UPC EAN udvidelse</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d moduler)</string>
|
||||
<string name="toggle_flash">Slå blitz til/fra</string>
|
||||
<string name="error_flash">Der opstod en fejl ved at slå blitz til/fra</string>
|
||||
<string name="share">Del</string>
|
||||
<string name="share_as">Del som?</string>
|
||||
<string name="copy_to_clipboard">Kopier til udklipsholder</string>
|
||||
<string name="copied_to_clipboard">Kopieret til udklipsholder</string>
|
||||
<string name="copy_password">Kopier adgangskode til udklipsholderen</string>
|
||||
<string name="copied_password_to_clipboard">Adgangskode kopieret til udklipsholderen</string>
|
||||
<string name="open_url">Åbn URL</string>
|
||||
<string name="cannot_resolve_action">Inge applikation kan åbne det</string>
|
||||
<string name="pick_search_engine">Vælg en søgemaskine</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="size">Størrelse i pixels</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="input_content_here">Indtast indhold her</string>
|
||||
<string name="encode">INDKOD</string>
|
||||
<string name="error_no_content">Manglende indhold</string>
|
||||
<string name="error_encoding_barcode">Stregkode kan ikke genereres</string>
|
||||
<string name="view_barcode">Vis stregkode</string>
|
||||
<string name="info">Info</string>
|
||||
<string name="switch_camera">Skift kamera</string>
|
||||
<string name="bulk_mode">Scan kontinuerligt</string>
|
||||
<string name="bulk_mode_summary">Begynd altid ved at scanne kontinuerligt.</string>
|
||||
<string name="bulk_mode_delay">Forsinkelse mellem kontinuerlige scanninger</string>
|
||||
<string name="restrict_format">Begræns format</string>
|
||||
<string name="remove_restriction">Fjern begrænsningen</string>
|
||||
<string name="scan_format">Scan %s</string>
|
||||
<string name="quarter_second">Et kvart sekund</string>
|
||||
<string name="half_second">Et halvt sekund</string>
|
||||
<string name="a_second">Et sekund</string>
|
||||
<string name="two_seconds">To sekunder</string>
|
||||
<string name="five_seconds">Fem sekunder</string>
|
||||
<string name="history">Historik</string>
|
||||
<string name="preferences">Præferencer</string>
|
||||
<string name="scan_category">Scan</string>
|
||||
<string name="content_category">Indhold</string>
|
||||
<string name="locale_category">Sprog</string>
|
||||
<string name="custom_locale">Brugerdefineret sprog</string>
|
||||
<string name="follow_system_settings">Følg systemindstillingerne</string>
|
||||
<string name="show_crop_handle">Vis beskæringsbegrænser</string>
|
||||
<string name="show_crop_handle_summary">Begræns scanning til et område, der kan tilpasses.</string>
|
||||
<string name="barcode_formats">Stregkode formater</string>
|
||||
<string name="zoom_by_swiping">Stryg op/ned for at zoome</string>
|
||||
<string name="zoom_by_swiping_summary">Stryg op eller ned på kameraskærmen for at styre kameraets zoom.</string>
|
||||
<string name="auto_rotate">Genkend lodrette 1D stregkoder</string>
|
||||
<string name="auto_rotate_summary">Roter automatisk kamerarammen for at genkende lodrette 1D stregkoder. Afhængigt af enheden kan dette påvirke ydeevnen.</string>
|
||||
<string name="try_harder">Optimer læseren for nøjagtighed</string>
|
||||
<string name="try_harder_summary">Aktiver denne mulighed for koder som er meget svære at læse. Vil påvirke ydeevnen.</string>
|
||||
<string name="show_toast_in_bulk_mode">Vis data i kontinuerlig tilstand</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Vis kort de scannede data, når du scanner kontinuerligt.</string>
|
||||
<string name="vibrate">Vibrer ved registrering</string>
|
||||
<string name="vibrate_summary">Aktiver dette, hvis du vil have din enhed til at vibrere, når en kode genkendes.</string>
|
||||
<string name="beep">Bip ved registrering</string>
|
||||
<string name="beep_summary">Aktiver dette, hvis du vil have din enhed til at bippe, når en kode genkendes.</string>
|
||||
<string name="beep_tone">Bip tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA bekræftelse</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positiv anerkendelse</string>
|
||||
<string name="tone_prop_beep">Generelt bip</string>
|
||||
<string name="tone_prop_beep2">Generelt dobbelt bip</string>
|
||||
<string name="use_history">Gem scanningshistorik</string>
|
||||
<string name="use_history_summary">Gem genkendte koder på din enhed.</string>
|
||||
<string name="ignore_consecutive_duplicates">Ignorer dubletter</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">Gem ikke fortløbende dubletter i scanningshistorikken.</string>
|
||||
<string name="open_immediately">Åbn straks</string>
|
||||
<string name="open_immediately_summary">Spring inspektion over og åbn indholdet med det samme. Kan åbne skadeligt indhold, hvis det er aktiveret.</string>
|
||||
<string name="copy_immediately">Læg i udklipsholderen</string>
|
||||
<string name="copy_immediately_summary">Kopier automatisk scannet indhold til udklipsholder. Bemærk at andre apps kan holde øje med din udklipsholder i baggrunden.</string>
|
||||
<string name="show_meta_data">Vis metadata</string>
|
||||
<string name="show_meta_data_summary">Vis yderligere data om den scannede stregkode.</string>
|
||||
<string name="show_hex_dump">Vis hex-dump</string>
|
||||
<string name="show_hex_dump_summary">Vis et hex-dump af det scannede indhold.</string>
|
||||
<string name="show_recreation">Vis genskabt stregkode</string>
|
||||
<string name="show_recreation_summary">Genskab og vis stregkode fra læst indhold, hvis det er muligt.</string>
|
||||
<string name="close_automatically">Gå tilbage efter Kopier/Del</string>
|
||||
<string name="close_automatically_summary">Vend automatisk tilbage til scanningsskærmen efter kopiering eller deling af det læste indhold.</string>
|
||||
<string name="default_search_engine">Åbn ukendte data i</string>
|
||||
<string name="always_ask">Spørg altid</string>
|
||||
<string name="open_with_url">Åbn ukendte data med URL</string>
|
||||
<string name="clear_network_suggestions">Fjern netværksforslag</string>
|
||||
<string name="clear_network_suggestions_summary">Fjern netværksforslag, der tidligere blev tilføjet med denne app.</string>
|
||||
<string name="really_remove_all_networks">Vil du virkelig fjerne alle netværk?</string>
|
||||
<string name="clear_network_suggestions_success">Netværksforslag ryddet</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Der er intet at fjerne</string>
|
||||
<string name="send_category">Videresendelse</string>
|
||||
<string name="send_scan_active">Videresend scanninger</string>
|
||||
<string name="send_scan_active_summary">Aktiver for at videresende scanninger til en given URL.</string>
|
||||
<string name="send_scan_url">URL at videresende til</string>
|
||||
<string name="send_scan_type">Forespørgsels type</string>
|
||||
<string name="send_type_get_add_content">GET og tilføj blot indhold</string>
|
||||
<string name="send_type_get_query_string">GET med komplet forespørgselsstreng</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Åbn i ekstern browser</string>
|
||||
<string name="test_url">Test URL</string>
|
||||
<string name="really_remove_scan">Vil du virkelig fjerne scanningen?</string>
|
||||
<string name="really_remove_all_scans">Vil du virkelig fjerne alle scanninger?</string>
|
||||
<string name="really_remove_selected_scans">Vil du virkelig fjerne valgte scanninger?</string>
|
||||
<string name="clear_history">Ryd historik</string>
|
||||
<string name="copy_scan">Kopier scanning</string>
|
||||
<string name="edit_scan">Rediger etiket</string>
|
||||
<string name="remove_scan">Fjern scanning</string>
|
||||
<string name="enter_name">Indtast et navn for at beskrive scanningen</string>
|
||||
<string name="enter_name_hint">Navn på scanningen</string>
|
||||
<string name="no_barcode_found">Ingen stregkode fundet</string>
|
||||
<string name="pick_list_separator">Hvordan adskiller man listeelementer?</string>
|
||||
<string name="separator_line_break">Linjeskift</string>
|
||||
<string name="separator_ruler">Lineal</string>
|
||||
<string name="save_as_file_name">Vil du gemme som i downloads?</string>
|
||||
<string name="file_name">Filnavn</string>
|
||||
<string name="error_saving_file">Kan ikke gemme filen</string>
|
||||
<string name="error_file_exists">Filen findes allerede</string>
|
||||
<string name="connect_to_wifi">Opret forbindelse til WiFi</string>
|
||||
<string name="wifi_config_failed">Kunne ikke konfigurere WiFi</string>
|
||||
<string name="wifi_added">WiFi tilføjet</string>
|
||||
<string name="sms_send">Send SMS</string>
|
||||
<string name="sms_error">Kunne ikke sende SMS</string>
|
||||
<string name="tel_dial">Ring til nummer</string>
|
||||
<string name="tel_error">Kunne ikke ringe til nummeret</string>
|
||||
<string name="mail_send">Send mail</string>
|
||||
<string name="mail_error">Kunne ikke sende mail</string>
|
||||
<string name="vcard_add">Tilføj til kontakter</string>
|
||||
<string name="vcard_failed">Kunne ikke føje til kontakter</string>
|
||||
<string name="vevent_add">Tilføj til kalender</string>
|
||||
<string name="vevent_failed">Kunne ikke føje til kalenderen</string>
|
||||
<string name="otpauth_add">Tilføj 2FA</string>
|
||||
<string name="search_web">Søg på nettet</string>
|
||||
<string name="search_scan">Søg scanning</string>
|
||||
<string name="export_to_file">Eksporter til fil</string>
|
||||
<string name="export_as">Eksporter som?</string>
|
||||
<string name="export_csv_comma">CSV-fil med kommaer</string>
|
||||
<string name="export_csv_semicolon">CSV-fil med semikoloner</string>
|
||||
<string name="export_json">JSON fil</string>
|
||||
<string name="export_database">SQLite database</string>
|
||||
<string name="saved_in_downloads">Gemt i downloads</string>
|
||||
<string name="rotate_image_cw">Roter billedet med uret</string>
|
||||
<string name="toggle_free_rotation">Slå fri rotation til/fra</string>
|
||||
<string name="pick_file">Vælg billedfil</string>
|
||||
<string name="pick_code_to_scan">Vælg kode til at scanne</string>
|
||||
<string name="shortcut_decode">Scan en stregkode</string>
|
||||
<string name="shortcut_encode">Opret en stregkode</string>
|
||||
<string name="shortcut_preferences">Indstillinger</string>
|
||||
<string name="background_request_failed">Baggrundsanmodning mislykkedes</string>
|
||||
<string name="entry_type">Type</string>
|
||||
<string name="wifi_network">WiFi netværk</string>
|
||||
<string name="wifi_ssid">Navn</string>
|
||||
<string name="wifi_type">Godkendelsestype</string>
|
||||
<string name="wifi_password">Adgangskode</string>
|
||||
<string name="wifi_hidden">Skjult netværk</string>
|
||||
<string name="wifi_eap">EAP metode</string>
|
||||
<string name="wifi_anonymous_identity">Anonym identitet</string>
|
||||
<string name="wifi_identity">Identitet</string>
|
||||
<string name="wifi_phase2">Fase 2 metode</string>
|
||||
<string name="network_suggestions">Netværksforslag</string>
|
||||
<string name="remove_suggestion">Fjern forslag</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,30 @@
|
||||
<resources>
|
||||
<string-array name="search_engines_names">
|
||||
<item>@string/always_ask</item>
|
||||
<item>Google</item>
|
||||
<item>DuckDuckGo</item>
|
||||
<item>Qwant</item>
|
||||
<item>Bing</item>
|
||||
<item>Yandex</item>
|
||||
<item>ebay</item>
|
||||
<item>Amazon</item>
|
||||
<item>OpenFoodFacts.org</item>
|
||||
<item>OpenBeautyFacts.org</item>
|
||||
<item>OpenPetFoodFacts.org</item>
|
||||
<item>Barcode Lookup</item>
|
||||
</string-array>
|
||||
<string-array name="search_engines_values">
|
||||
<item></item>
|
||||
<item>https://www.google.de/search?q=</item>
|
||||
<item>https://duckduckgo.com/?q=</item>
|
||||
<item>https://www.qwant.com/?q=</item>
|
||||
<item>https://bing.com/?q=</item>
|
||||
<item>https://yandex.com/?q=</item>
|
||||
<item>https://www.ebay.de/sch/i.html?_nkw=</item>
|
||||
<item>https://www.amazon.de/s?k=</item>
|
||||
<item>https://world.openfoodfacts.org/cgi/search.pl?search_terms=</item>
|
||||
<item>https://world.openbeautyfacts.org/cgi/search.pl?search_terms=</item>
|
||||
<item>https://world.openpetfoodfacts.org/cgi/search.pl?search_terms=</item>
|
||||
<item>https://www.barcodelookup.com/</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -15,14 +15,20 @@
|
||||
<string name="error_correction_level_m" formatted="false">Medium (~15% wiederherstellbar)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartile (~25% wiederherstellbar)</string>
|
||||
<string name="error_correction_level_h" formatted="false">High (~30% wiederherstellbar)</string>
|
||||
<string name="issue_number">Ausgabe Nummer</string>
|
||||
<string name="orientation">Orientierung</string>
|
||||
<string name="other_meta_data">Metadaten</string>
|
||||
<string name="pdf417_extra_metadata">PDF417 Metadaten</string>
|
||||
<string name="possible_country">Mögliches Ursprungsland</string>
|
||||
<string name="suggested_price">Preisvorschlag</string>
|
||||
<string name="upc_ean_extension">UPC EAN Erweiterung</string>
|
||||
<string name="qr_version">QR Version</string>
|
||||
<string name="colors">Vor und Hintergrund</string>
|
||||
<string name="colors_black_on_white">Schwarz auf Weiß</string>
|
||||
<string name="colors_white_on_black">Weiß auf Schwarz</string>
|
||||
<string name="colors_black_on_transparent">Schwarz auf Transparent</string>
|
||||
<string name="colors_white_on_transparent">Weiß auf Transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">Ausgabe Nummer</string>
|
||||
<string name="gtin_country">Mögliches Ursprungsland</string>
|
||||
<string name="gtin_price">Preisvorschlag</string>
|
||||
<string name="gtin_add_on">UPC EAN Erweiterung</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d Module)</string>
|
||||
<string name="toggle_flash">Licht an/ausschalten</string>
|
||||
<string name="error_flash">Fehler beim ein/ausschalten des Lichts</string>
|
||||
<string name="share">Teilen</string>
|
||||
@@ -73,8 +79,17 @@
|
||||
<string name="try_harder_summary">Aktivieren Sie diese Option für sehr schwer lesbare Codes. Beeinträchtigt die Leistung.</string>
|
||||
<string name="show_toast_in_bulk_mode">Daten einblenden</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Die gescannten Daten werden kurz eingeblendet, wenn fortlaufend gescannt wird.</string>
|
||||
<string name="vibrate">Bei Erkennung vibrieren</string>
|
||||
<string name="vibrate_summary">Das Gerät soll vibrieren wenn ein Code erkannt wird.</string>
|
||||
<string name="vibrate">Vibration bei Erkennung</string>
|
||||
<string name="vibrate_summary">Bei Erkennung eines Codes soll das Gerät vibrieren.</string>
|
||||
<string name="beep">Signalton bei Erkennung</string>
|
||||
<string name="beep_summary">Bei Erkennung eines Codes soll ein Signalton abgespielt werden.</string>
|
||||
<string name="beep_tone">Signalton</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Codes speichern</string>
|
||||
<string name="use_history_summary">Eingelesene Barcodes auf dem Gerät speichern.</string>
|
||||
<string name="ignore_consecutive_duplicates">Duplikate ignorieren</string>
|
||||
@@ -85,17 +100,17 @@
|
||||
<string name="copy_immediately_summary">Eingelesene Inhalte werden automatisch in die Zwischenablage kopiert. Bitte beachten Sie, dass andere Anwendungen die Zwischenablage im Hintergrund auslesen können.</string>
|
||||
<string name="show_meta_data">Meta Daten anzeigen</string>
|
||||
<string name="show_meta_data_summary">Zusätzliche Daten über den eingelesenen Barcode anzeigen.</string>
|
||||
<string name="show_qr_version">QR Version anzeigen</string>
|
||||
<string name="show_qr_version_summary">Versionsnummer für QR Codes anzeigen.</string>
|
||||
<string name="show_hex_dump">Hex Dump anzeigen</string>
|
||||
<string name="show_hex_dump_summary">Zeigt einen Hexdump des eingelesenen Inhalts an.</string>
|
||||
<string name="show_recreation">Wiederhergestellten Barcode anzeigen</string>
|
||||
<string name="show_recreation_summary">Barcode aus dem gelesenen Inhalt wiederherstellen und anzeigen, wenn möglich.</string>
|
||||
<string name="close_automatically">Automatisch zurückkehren</string>
|
||||
<string name="close_automatically_summary">Nach dem Kopieren/Teilen automatisch zum Scanbildschirm zurückkehren.</string>
|
||||
<string name="default_search_engine">Unbekannte Daten öffnen mit</string>
|
||||
<string name="always_ask">Immer fragen</string>
|
||||
<string name="open_with_url">URL zum Öffnen unbekannter Daten</string>
|
||||
<string name="clear_network_suggestions">WiFi Netzwerkvorschläge entfernen</string>
|
||||
<string name="clear_network_suggestions_summary">Betrifft alle WiFi Netzwerke, die zuvor mit dieser App bereitgestellt wurden.</string>
|
||||
<string name="clear_network_suggestions_summary">Betrifft nur Netzwerke, die zuvor mit dieser App bereitgestellt wurden.</string>
|
||||
<string name="really_remove_all_networks">Alle Netzwerkvorschläge entfernen?</string>
|
||||
<string name="clear_network_suggestions_success">Netzwerkvorschläge entfernt</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Nichts zu entfernen</string>
|
||||
@@ -151,6 +166,7 @@
|
||||
<string name="export_database">SQLite Datenbank</string>
|
||||
<string name="saved_in_downloads">In den Downloads gespeichert</string>
|
||||
<string name="rotate_image_cw">Bild im Uhrzeigersinn rotieren</string>
|
||||
<string name="toggle_free_rotation">Freie Rotation ein/ausschalten</string>
|
||||
<string name="pick_file">Bilddatei auswählen</string>
|
||||
<string name="pick_code_to_scan">Code im Bild auswählen</string>
|
||||
<string name="shortcut_decode">Barcode lesen</string>
|
||||
@@ -167,4 +183,6 @@
|
||||
<string name="wifi_anonymous_identity">Anonyme Identität</string>
|
||||
<string name="wifi_identity">Identität</string>
|
||||
<string name="wifi_phase2">Phase 2 Methode</string>
|
||||
<string name="network_suggestions">WiFi Netzwerkvorschläge</string>
|
||||
<string name="remove_suggestion">Vorschlag entfernen</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">Esta aplicación no tiene sentido usar sin acceso a la cámara. Adiós.</string>
|
||||
<string name="no_camera_no_fun">No tiene sentido usar esta aplicación sin acceso a la cámara. Adiós.</string>
|
||||
<string name="camera_error">No se puede acceder a la cámara, por favor, inténtelo de nuevo</string>
|
||||
<string name="scan_code">Escanear código de barras</string>
|
||||
<string name="compose_barcode">Componer código de barras</string>
|
||||
@@ -15,15 +15,21 @@
|
||||
<string name="error_correction_level_m" formatted="false">Medio (~15% de correción)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Cuartil (~25% de correción)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Alto (~30% de correción)</string>
|
||||
<string name="issue_number">Número de emisión</string>
|
||||
<string name="orientation">Orientación</string>
|
||||
<string name="other_meta_data">Metadatos</string>
|
||||
<string name="pdf417_extra_metadata">Metadatos PDF417</string>
|
||||
<string name="possible_country">Posible país de fabricación</string>
|
||||
<string name="suggested_price">Precio sugerido</string>
|
||||
<string name="upc_ean_extension">Extensión UPC EAN</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="toggle_flash">Activar la linterna</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">Número de emisión</string>
|
||||
<string name="gtin_country">Posible país de fabricación</string>
|
||||
<string name="gtin_price">Precio sugerido</string>
|
||||
<string name="gtin_add_on">Extensión UPC EAN</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">Activar el flash</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="share">Compartir</string>
|
||||
<string name="share_as">¿Compartir como?</string>
|
||||
@@ -46,15 +52,15 @@
|
||||
<string name="switch_camera">Cambiar cámara</string>
|
||||
<string name="bulk_mode">Escanear constantemente</string>
|
||||
<string name="bulk_mode_summary">Siempre iniciar escaneando constantemente</string>
|
||||
<string name="bulk_mode_delay">Delay between continuous scans</string>
|
||||
<string name="restrict_format">Restrict format</string>
|
||||
<string name="remove_restriction">Remove restriction</string>
|
||||
<string name="scan_format">Scan %s</string>
|
||||
<string name="quarter_second">A quarter second</string>
|
||||
<string name="half_second">Half a second</string>
|
||||
<string name="a_second">One second</string>
|
||||
<string name="two_seconds">Two seconds</string>
|
||||
<string name="five_seconds">Five seconds</string>
|
||||
<string name="bulk_mode_delay">Demora entre escaneos continuos</string>
|
||||
<string name="restrict_format">Restringir formato</string>
|
||||
<string name="remove_restriction">Eliminar restricción</string>
|
||||
<string name="scan_format">Escanear %s</string>
|
||||
<string name="quarter_second">Un cuarto de segundo</string>
|
||||
<string name="half_second">Medio segundo</string>
|
||||
<string name="a_second">Un segundo</string>
|
||||
<string name="two_seconds">Dos segundos</string>
|
||||
<string name="five_seconds">Cinco segundos</string>
|
||||
<string name="history">Historial</string>
|
||||
<string name="preferences">Configuración</string>
|
||||
<string name="scan_category">Escanear</string>
|
||||
@@ -75,6 +81,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">Mostrar brevemente los datos escaneados al escanear constantemente. </string>
|
||||
<string name="vibrate">Vibrar al detectar</string>
|
||||
<string name="vibrate_summary">Active esta opción si desea que su dispositivo vibre cuando se reconozca un código.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Guardar historial de escaneo</string>
|
||||
<string name="use_history_summary">Guardar códigos reconocidos en su dispositivo.</string>
|
||||
<string name="ignore_consecutive_duplicates">Ignorar duplicados</string>
|
||||
@@ -85,10 +100,10 @@
|
||||
<string name="copy_immediately_summary">Copiar contenido al portapapeles automáticamente. Ten en cuenta que otras aplicaciones pueden husmear en tu portapapeles en segundo plano.</string>
|
||||
<string name="show_meta_data">Mostrar metadatos</string>
|
||||
<string name="show_meta_data_summary">Mostrar datos adicionales del código escaneado.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">Mostrar dump hexadecimal</string>
|
||||
<string name="show_hex_dump_summary">Mostrar un dump hexadecimal del contenido escaneado.</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">Retroceder luego de Copiar/Compartir</string>
|
||||
<string name="close_automatically_summary">Regresar automáticamente a la pantalla de escaneo luego de copiar o compartir el contenido leído.</string>
|
||||
<string name="default_search_engine">Abrir datos desconocidos en</string>
|
||||
@@ -108,7 +123,7 @@
|
||||
<string name="send_type_get_query_string">GET con consulta completa</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Open in external browser</string>
|
||||
<string name="send_type_external_browser">Abrir en el navegador</string>
|
||||
<string name="test_url">URL de prueba</string>
|
||||
<string name="really_remove_scan">¿Realmente desea borrar el escaneo seleccionado?</string>
|
||||
<string name="really_remove_all_scans">¿Realmente desea borrar todo lo escaneado?</string>
|
||||
@@ -151,6 +166,7 @@
|
||||
<string name="export_database">Base de datos SQLite</string>
|
||||
<string name="saved_in_downloads">Guardado en Descargas</string>
|
||||
<string name="rotate_image_cw">Rotar la imagen en sentido horario</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">Seleccionar imagen</string>
|
||||
<string name="pick_code_to_scan">Seleccione el código a escanear</string>
|
||||
<string name="shortcut_decode">Escanear un código</string>
|
||||
@@ -158,13 +174,15 @@
|
||||
<string name="shortcut_preferences">Ajustes</string>
|
||||
<string name="background_request_failed">Solicitud de fondo fallida</string>
|
||||
<string name="entry_type">Type</string>
|
||||
<string name="wifi_network">Wi-Fi network</string>
|
||||
<string name="wifi_ssid">Name</string>
|
||||
<string name="wifi_type">Authentication type</string>
|
||||
<string name="wifi_password">Password</string>
|
||||
<string name="wifi_hidden">Hidden network</string>
|
||||
<string name="wifi_eap">EAP method</string>
|
||||
<string name="wifi_anonymous_identity">Anonymous identity</string>
|
||||
<string name="wifi_identity">Identity</string>
|
||||
<string name="wifi_network">Red wi-fi</string>
|
||||
<string name="wifi_ssid">Nombre</string>
|
||||
<string name="wifi_type">Tipo de autenticación</string>
|
||||
<string name="wifi_password">Contraseña</string>
|
||||
<string name="wifi_hidden">Red oculta</string>
|
||||
<string name="wifi_eap">Método EAP</string>
|
||||
<string name="wifi_anonymous_identity">Identidad anónima</string>
|
||||
<string name="wifi_identity">Identidad</string>
|
||||
<string name="wifi_phase2">Phase 2 method</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<resources>
|
||||
<string-array name="search_engines_names">
|
||||
<item>@string/always_ask</item>
|
||||
<item>گوگل</item>
|
||||
<item>داکداکگو</item>
|
||||
<item>Qwant</item>
|
||||
<item>بینگ</item>
|
||||
<item>یاندکس</item>
|
||||
<item>ebay</item>
|
||||
<item>Amazon</item>
|
||||
<item>OpenFoodFacts.org</item>
|
||||
<item>OpenBeautyFacts.org</item>
|
||||
<item>OpenPetFoodFacts.org</item>
|
||||
<item>Barcode Lookup</item>
|
||||
</string-array>
|
||||
<string-array name="search_engines_values">
|
||||
<item></item>
|
||||
<item>https://www.google.com/search?q=</item>
|
||||
<item>https://duckduckgo.com/?q=</item>
|
||||
<item>https://www.qwant.com/?q=</item>
|
||||
<item>https://bing.com/?q=</item>
|
||||
<item>https://yandex.com/?q=</item>
|
||||
<item>https://www.ebay.com/sch/i.html?_nkw=</item>
|
||||
<item>https://www.amazon.com/s?k=</item>
|
||||
<item>https://world.openfoodfacts.org/cgi/search.pl?search_terms=</item>
|
||||
<item>https://world.openbeautyfacts.org/cgi/search.pl?search_terms=</item>
|
||||
<item>https://world.openpetfoodfacts.org/cgi/search.pl?search_terms=</item>
|
||||
<item>https://www.barcodelookup.com/</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -0,0 +1,188 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">این برنامه بدون دسترسی به دوربین هیچ کارایی ندارد. خدانگهدار.</string>
|
||||
<string name="camera_error">نمیتوان به دوربین دسترسی داشت، لطفاً دوباره تلاش کنید</string>
|
||||
<string name="scan_code">پویش کد</string>
|
||||
<string name="compose_barcode">ایجاد بارکد</string>
|
||||
<string name="decode_barcode">رمزگشایی بارکد</string>
|
||||
<string name="content">محتویات</string>
|
||||
<string name="binary_data">(دادهٔ دودویی)</string>
|
||||
<plurals name="barcode_info">
|
||||
<item quantity="one">%2$d نویسه، %1$s</item>
|
||||
<item quantity="other">%2$d نویسه، %1$s</item>
|
||||
</plurals>
|
||||
<string name="error_correction_level">سطح تصحیح خطا</string>
|
||||
<string name="error_correction_level_l" formatted="false">کم (~۷٪ تصحیح)</string>
|
||||
<string name="error_correction_level_m" formatted="false">متوسط (~۱۵٪ تصحیح)</string>
|
||||
<string name="error_correction_level_q" formatted="false">یکچهارم (~۲۵٪ تصحیح)</string>
|
||||
<string name="error_correction_level_h" formatted="false">زیاد (~۳۰٪ تصحیح)</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">شمارهٔ اشکال</string>
|
||||
<string name="gtin_country">کشور احتمالی سازنده</string>
|
||||
<string name="gtin_price">قیمت پیشنهادی</string>
|
||||
<string name="gtin_add_on">UPC EAN extension</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">روشن/خاموش کردن چراغ</string>
|
||||
<string name="error_flash">خطا هنگام روشن/خاموش کردن چراغ</string>
|
||||
<string name="share">همرسانی</string>
|
||||
<string name="share_as">همرسانی به عنوان؟</string>
|
||||
<string name="copy_to_clipboard">رونوشت به تخهگیره</string>
|
||||
<string name="copied_to_clipboard">به تختهگیره رونوشت شد</string>
|
||||
<string name="copy_password">رونوشت گذرواژه به تختهگیره</string>
|
||||
<string name="copied_password_to_clipboard">گذرواژه به تختهگیره رونوشت شد</string>
|
||||
<string name="open_url">گشودن نشانی</string>
|
||||
<string name="cannot_resolve_action">هیچ برنامهای نمیتواند آن را بگشاید</string>
|
||||
<string name="pick_search_engine">یک موتور جستوجو برگزینید</string>
|
||||
<string name="format">قالب</string>
|
||||
<string name="size">اندازه به پیکسل</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="input_content_here">محتویات ورودی را اینجا بنویسید</string>
|
||||
<string name="encode">رمزگذاری</string>
|
||||
<string name="error_no_content">محتویاتی نیست</string>
|
||||
<string name="error_encoding_barcode">بارکد نمیتواند ایجاد شود</string>
|
||||
<string name="view_barcode">نمایش بارکد</string>
|
||||
<string name="info">اطّلاعات</string>
|
||||
<string name="switch_camera">تغییر دوربین</string>
|
||||
<string name="bulk_mode">به طور مداوم پویش کن</string>
|
||||
<string name="bulk_mode_summary">همیشه پویش را به طور مداوم شروع میکند.</string>
|
||||
<string name="bulk_mode_delay">تأخیر بین پویشهای مداوم</string>
|
||||
<string name="restrict_format">محدود کردن قالب</string>
|
||||
<string name="remove_restriction">برداشتن محدودیت</string>
|
||||
<string name="scan_format">پویش %s</string>
|
||||
<string name="quarter_second">یکچهارم ثانیه</string>
|
||||
<string name="half_second">نیم ثانیه</string>
|
||||
<string name="a_second">یک ثانیه</string>
|
||||
<string name="two_seconds">دو ثانیه</string>
|
||||
<string name="five_seconds">پنج ثانیه</string>
|
||||
<string name="history">تاریخچه</string>
|
||||
<string name="preferences">ترجیحات</string>
|
||||
<string name="scan_category">پویش</string>
|
||||
<string name="content_category">محتویات</string>
|
||||
<string name="locale_category">زبان</string>
|
||||
<string name="custom_locale">زبان سفارشی</string>
|
||||
<string name="follow_system_settings">پیروی از زبان سامانه</string>
|
||||
<string name="show_crop_handle">نمایش محدود کننده برش</string>
|
||||
<string name="show_crop_handle_summary">پویش را به یک منطقه قابل تنظیم محدود میکند.</string>
|
||||
<string name="barcode_formats">قالبهای بارکد</string>
|
||||
<string name="zoom_by_swiping">برای بزرگنمایی به بالا یا پایین بکشید</string>
|
||||
<string name="zoom_by_swiping_summary">برای کنترل بزرگنمایی دوربین، در صفحهٔ دوربین به بالا یا پایین بکشید.</string>
|
||||
<string name="auto_rotate">تشخیص بارکدهای یک بعدی عمودی</string>
|
||||
<string name="auto_rotate_summary">قاب دوربین را به صورت خودکار بچرخانید تا بارکدهای یک بعدی عمودی را تشخیص دهید. بسته به دستگاه، این ممکن است بر عملکرد تأثیر بگذارد.</string>
|
||||
<string name="try_harder">بهینه کردن خواننده برای دقت بیشتر</string>
|
||||
<string name="try_harder_summary">این گزینه را برای کدهایی که بسیار سخت خوانده میشوند، فعال کنید. بر عملکرد تأثیر خواهد گذاشت.</string>
|
||||
<string name="show_toast_in_bulk_mode">نمایش دادهها در حالت پیوسته</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">هنگام پویش مداوم، دادههای پویش شده را به طور خلاصه نشان میدهید.</string>
|
||||
<string name="vibrate">لرزش هنگام تشخیص</string>
|
||||
<string name="vibrate_summary">اگر میخواهید دستگاهتان هنگام شناسایی کد بلرزد، این را فعال کنید.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">ذخیرهٔ تاریخچهٔ پویش</string>
|
||||
<string name="use_history_summary">کدهای شناسایی شده را در همین دستگاه ذخیره میکند.</string>
|
||||
<string name="ignore_consecutive_duplicates">نادیده گرفتن موارد تکراری</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">موارد تکراری متوالی را در تاریخچهٔ پویش ذخیره نمیکند.</string>
|
||||
<string name="open_immediately">گشودن بلافاصله</string>
|
||||
<string name="open_immediately_summary">بازرسی را رها کنید و محتویات را فورا باز کنید. در صورت فعال بودن ممکن است محتوای مضر را باز کند.</string>
|
||||
<string name="copy_immediately">قرار دادن در تختهگیره</string>
|
||||
<string name="copy_immediately_summary">به طور خودکار محتوای پویش شده را در تختهگیره رونوشت میکند. لطفاً توجه داشته باشید که برنامههای دیگر ممکن است در پسزمینه تختهگیرهٔ شما را شنود کنند.</string>
|
||||
<string name="show_meta_data">نمایش فراداده</string>
|
||||
<string name="show_meta_data_summary">نمایش دادههای اضافی در مورد بارکد پویش شده.</string>
|
||||
<string name="show_hex_dump">نمایش کد هگز استخراج شده</string>
|
||||
<string name="show_hex_dump_summary">نمایش کد هگز استخراج شده از محتویات پویش شده.</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">بازگشت پس از رونوشت یا همرسانی</string>
|
||||
<string name="close_automatically_summary">پس از رونوشت یا همرسانی مطالب خوانده شده، به طور خودکار به صفحهٔ پویش بازگردید.</string>
|
||||
<string name="default_search_engine">گشودن دادهٔ نامشخص در</string>
|
||||
<string name="always_ask">همیشه بپرس</string>
|
||||
<string name="open_with_url">دادههای ناشناخته را با URL باز کنید</string>
|
||||
<string name="clear_network_suggestions">پاک کردن پیشنهادات شبکه</string>
|
||||
<string name="clear_network_suggestions_summary">همه پیشنهادات شبکه را که قبلاً توسط این برنامه ارائه شده است حذف کنید.</string>
|
||||
<string name="really_remove_all_networks">واقعاً همه شبکهها را حذف میکنید؟</string>
|
||||
<string name="clear_network_suggestions_success">پیشنهادات شبکه پاک شد</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">چیزی برای حذف نیست</string>
|
||||
<string name="send_category">هدایت کردن</string>
|
||||
<string name="send_scan_active">هدایت پویشها</string>
|
||||
<string name="send_scan_active_summary">برای هدایت پویشها به نشانی مشخص شده، آن را به کار بیاندازید.</string>
|
||||
<string name="send_scan_url">نشانی برای هدایت به آن</string>
|
||||
<string name="send_scan_type">گونهٔ درخواست</string>
|
||||
<string name="send_type_get_add_content">GET و به سادگی محتوا را اضافه کنید</string>
|
||||
<string name="send_type_get_query_string">GET با رشته پرسوجو کامل</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">گشودن در مرورگر خارجی</string>
|
||||
<string name="test_url">آزمودن نشانی</string>
|
||||
<string name="really_remove_scan">برای برداشتن پویش مطمئنید؟</string>
|
||||
<string name="really_remove_all_scans">برای برداشتن همهٔ پویشها مطمئنید؟</string>
|
||||
<string name="really_remove_selected_scans">برای برداشتن پویشهای برگزیده شده مطمئنید؟</string>
|
||||
<string name="clear_history">پاک کردن تاریخچه</string>
|
||||
<string name="copy_scan">رونوشت پویش</string>
|
||||
<string name="edit_scan">ویرایش عنوان</string>
|
||||
<string name="remove_scan">برداشتن پویش</string>
|
||||
<string name="enter_name">یک نام برای توضیح پویش وارد کنید</string>
|
||||
<string name="enter_name_hint">نام پویش</string>
|
||||
<string name="no_barcode_found">بارکدی یافت نشد</string>
|
||||
<string name="pick_list_separator">چگونه موارد فهرست را جدا کنیم؟</string>
|
||||
<string name="separator_line_break">خط بعدی</string>
|
||||
<string name="separator_ruler">خط كش</string>
|
||||
<string name="save_as_file_name">به عنوان پرونده در بارگیریها ذخیره شود؟</string>
|
||||
<string name="file_name">نام پرونده</string>
|
||||
<string name="error_saving_file">نمیتوان پرونده را ذخیره کرد</string>
|
||||
<string name="error_file_exists">پرونده هماکنون وجود دارد</string>
|
||||
<string name="connect_to_wifi">اتّصال به وایفای</string>
|
||||
<string name="wifi_config_failed">نمیتوان وایفای را پیکربندی کرد</string>
|
||||
<string name="wifi_added">وایفای اضافه شد</string>
|
||||
<string name="sms_send">ارسال اساماس</string>
|
||||
<string name="sms_error">نمیتوان اساماس فرستاد</string>
|
||||
<string name="tel_dial">تماس با شماره</string>
|
||||
<string name="tel_error">نمیتوان با شماره تماس گرفت</string>
|
||||
<string name="mail_send">ارسال رایانامه</string>
|
||||
<string name="mail_error">نمیتوان رایانامه فرستاد</string>
|
||||
<string name="vcard_add">افزودن به مخاطبین</string>
|
||||
<string name="vcard_failed">نمیتوان به مخاطبین اضافه کرد</string>
|
||||
<string name="vevent_add">افزودن به تقویم</string>
|
||||
<string name="vevent_failed">نمیتوان به تقویم اضافه کرد</string>
|
||||
<string name="otpauth_add">افزودن احراز هویت چندعاملی(2FA)</string>
|
||||
<string name="search_web">جستوجوی وب</string>
|
||||
<string name="search_scan">جستوجوی پویش</string>
|
||||
<string name="export_to_file">برونریزی به پرونده</string>
|
||||
<string name="export_as">برونریزی به عنوان؟</string>
|
||||
<string name="export_csv_comma">پروندهٔ سیاسوی با ویرگول</string>
|
||||
<string name="export_csv_semicolon">پروندهٔ سیاسوی با نقطهویرگول</string>
|
||||
<string name="export_json">پروندهٔ جیسون</string>
|
||||
<string name="export_database">پایگاهدادهٔ اسکیولایت</string>
|
||||
<string name="saved_in_downloads">در بارگیریها ذخیره شد</string>
|
||||
<string name="rotate_image_cw">تصویر را در جهت ساعتگرد بچرخانید</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">پروندهٔ تصویری را برگزینید</string>
|
||||
<string name="pick_code_to_scan">کدی را برای پویش برگزینید</string>
|
||||
<string name="shortcut_decode">پویش یک بارکد</string>
|
||||
<string name="shortcut_encode">ایجاد یک بارکد</string>
|
||||
<string name="shortcut_preferences">تنظیمات</string>
|
||||
<string name="background_request_failed">درخواست پسزمینه انجام نشد</string>
|
||||
<string name="entry_type">گونه</string>
|
||||
<string name="wifi_network">شبکهٔ وایفای</string>
|
||||
<string name="wifi_ssid">نام</string>
|
||||
<string name="wifi_type">گونهٔ تأیید اعتبار</string>
|
||||
<string name="wifi_password">گذرواژه</string>
|
||||
<string name="wifi_hidden">شبکهٔ پنهان</string>
|
||||
<string name="wifi_eap">روش EAP</string>
|
||||
<string name="wifi_anonymous_identity">هویت ناشناس</string>
|
||||
<string name="wifi_identity">هویت</string>
|
||||
<string name="wifi_phase2">روش دو مرحلهای</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
@@ -16,16 +16,22 @@
|
||||
<string name="error_correction_level_m" formatted="false">Moyen (~15% de correction)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartile (~25% de correction)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Élevé (~30% de correction)</string>
|
||||
<string name="issue_number">Issue number</string>
|
||||
<string name="orientation">Orientation</string>
|
||||
<string name="other_meta_data">Métadonnées</string>
|
||||
<string name="pdf417_extra_metadata">Métadonnées PDF417</string>
|
||||
<string name="possible_country">Pays de fabrication possible</string>
|
||||
<string name="suggested_price">Prix suggéré</string>
|
||||
<string name="upc_ean_extension">Extension UPC EAN</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">Premier plan et arrière-plan</string>
|
||||
<string name="colors_black_on_white">Noir sur blanc</string>
|
||||
<string name="colors_white_on_black">Blanc sur noir</string>
|
||||
<string name="colors_black_on_transparent">Noir sur transparent</string>
|
||||
<string name="colors_white_on_transparent">Blanc sur transparent</string>
|
||||
<string name="sequence_size">Taille de la séquence</string>
|
||||
<string name="sequence_index">Index de la séquence</string>
|
||||
<string name="sequence_id">ID de la séquence</string>
|
||||
<string name="gtin_issue_number">Numéro du problème</string>
|
||||
<string name="gtin_country">Pays de fabrication possible</string>
|
||||
<string name="gtin_price">Prix suggéré</string>
|
||||
<string name="gtin_add_on">Extension UPC EAN</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">Activer le flash</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="error_flash">Erreur de basculement du flash</string>
|
||||
<string name="share">Partager</string>
|
||||
<string name="share_as">Partager comme ?</string>
|
||||
<string name="copy_to_clipboard">Copier dans le presse-papiers</string>
|
||||
@@ -46,10 +52,10 @@
|
||||
<string name="info">Info</string>
|
||||
<string name="switch_camera">Changer de camera</string>
|
||||
<string name="bulk_mode">Scan continu</string>
|
||||
<string name="bulk_mode_summary">Toujours démarrer en scannant en continu.</string>
|
||||
<string name="bulk_mode_summary">Démarre toujours en scan continu.</string>
|
||||
<string name="bulk_mode_delay">Délai entre les scans continus</string>
|
||||
<string name="restrict_format">Restrict format</string>
|
||||
<string name="remove_restriction">Remove restriction</string>
|
||||
<string name="restrict_format">Restreindre le format</string>
|
||||
<string name="remove_restriction">Supprimer la restriction</string>
|
||||
<string name="scan_format">Scan %s</string>
|
||||
<string name="quarter_second">Un quart de seconde</string>
|
||||
<string name="half_second">Une demi-seconde</string>
|
||||
@@ -64,47 +70,56 @@
|
||||
<string name="custom_locale">Langue personnalisée</string>
|
||||
<string name="follow_system_settings">Suivre les réglages du système</string>
|
||||
<string name="show_crop_handle">Afficher le bouton de rognage</string>
|
||||
<string name="show_crop_handle_summary">Restreindre le scan à une région personnalisée.</string>
|
||||
<string name="show_crop_handle_summary">Restreint le scan à une région personnalisée.</string>
|
||||
<string name="barcode_formats">Formats de codes-barres</string>
|
||||
<string name="zoom_by_swiping">Balayage haut/bas pour zoomer</string>
|
||||
<string name="zoom_by_swiping_summary">Balayez vers le haut ou vers le bas dans l’écran de la caméra pour contrôler le zoom de la caméra.</string>
|
||||
<string name="auto_rotate">Reconnaître les codes-barres 1D verticaux</string>
|
||||
<string name="auto_rotate_summary">Tourner automatiquement le cadre de la caméra pour reconnaître les codes-barres 1D verticaux. En fonction de l\'appareil, cela peut affecter les performances.</string>
|
||||
<string name="auto_rotate_summary">Tourne automatiquement le cadre de la caméra pour reconnaître les codes-barres 1D verticaux. En fonction de l\'appareil, cela peut affecter les performances.</string>
|
||||
<string name="try_harder">Optimiser la précision du lecteur</string>
|
||||
<string name="try_harder_summary">Activez cette option pour les codes très difficiles à lire. Affectera les performances.</string>
|
||||
<string name="show_toast_in_bulk_mode">Afficher les données en mode continu</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Afficher brièvement les données lors d\'un scan en continu.</string>
|
||||
<string name="vibrate">Vibrer à la détection</string>
|
||||
<string name="vibrate_summary">Activez ceci si vous voulez que votre appareil vibre lorsqu’un code est reconnu.</string>
|
||||
<string name="vibrate_summary">Fait vibrer l\'appareil lorsqu\'un code est reconnu.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Sauvegarder l\'historique des scans</string>
|
||||
<string name="use_history_summary">Sauvegarder les codes reconnus sur votre appareil.</string>
|
||||
<string name="use_history_summary">Sauvegarde les codes reconnus sur votre appareil.</string>
|
||||
<string name="ignore_consecutive_duplicates">Ignorer les doublons</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">Ne pas sauvegarder les doublons dans l\'historique des scans.</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">Ne sauvegarde pas les doublons dans l\'historique des scans.</string>
|
||||
<string name="open_immediately">Ouvrir immédiatement</string>
|
||||
<string name="open_immediately_summary">Sauter l\'inspection et ouvrir le contenu immédiatement. Si activé, cela peut ouvrir un contenu nocif.</string>
|
||||
<string name="open_immediately_summary">Saute l\'inspection et ouvre le contenu immédiatement. Si activé, cela peut ouvrir un contenu nocif.</string>
|
||||
<string name="copy_immediately">Mettre dans le presse-papiers</string>
|
||||
<string name="copy_immediately_summary">Copier automatiquement les contenus scannés dans le presse-papiers. Veuillez noter que les autres applications peuvent fouiner dans votre presse-papiers en arrière-plan.</string>
|
||||
<string name="copy_immediately_summary">Copie automatiquement les contenus scannés dans le presse-papiers. Veuillez noter que les autres applications peuvent fouiner dans votre presse-papiers en arrière-plan.</string>
|
||||
<string name="show_meta_data">Afficher les méta-données</string>
|
||||
<string name="show_meta_data_summary">Afficher les données supplémentaires sur le code-barres scanné.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_meta_data_summary">Affiche les données supplémentaires sur le code-barres scanné.</string>
|
||||
<string name="show_hex_dump">Afficher le dump hexa</string>
|
||||
<string name="show_hex_dump_summary">Affiche un dump hexadécimal du contenu scanné.</string>
|
||||
<string name="show_hex_dump_summary">Affiche le dump hexadécimal du contenu scanné.</string>
|
||||
<string name="show_recreation">Afficher le code-barres recréé</string>
|
||||
<string name="show_recreation_summary">Recrée et affiche, si possible, le code-barres à partir du contenu lu.</string>
|
||||
<string name="close_automatically">Revenir après une copie/partage</string>
|
||||
<string name="close_automatically_summary">Revient automatiquement sur l\'écran de scan après avoir copié ou partagé le contenu lu.</string>
|
||||
<string name="default_search_engine">Ouvrir les données inconnues dans</string>
|
||||
<string name="always_ask">Toujours demander</string>
|
||||
<string name="open_with_url">Ouvrir des données inconnues avec l’URL</string>
|
||||
<string name="clear_network_suggestions">Supprimer les suggestions de réseau</string>
|
||||
<string name="clear_network_suggestions_summary">Supprimez toutes les suggestions de réseau précédemment fournies par cette application.</string>
|
||||
<string name="clear_network_suggestions_summary">Supprime toutes les suggestions de réseau précédemment fournies par cette application.</string>
|
||||
<string name="really_remove_all_networks">Supprimer vraiment tous les réseaux ?</string>
|
||||
<string name="clear_network_suggestions_success">Suggestions de réseau supprimées</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Rien à supprimer</string>
|
||||
<string name="send_category">Transfert</string>
|
||||
<string name="send_scan_active">Forward scans</string>
|
||||
<string name="send_scan_active_summary">Enable to forward scans to a the given URL</string>
|
||||
<string name="send_scan_url">Envoyer chaque scan vers une URL</string>
|
||||
<string name="send_scan_type">Type de requête pour chaque scan</string>
|
||||
<string name="send_scan_active">Transférer les scans</string>
|
||||
<string name="send_scan_active_summary">Transfère les scans vers une URL donnée.</string>
|
||||
<string name="send_scan_url">URL de transfert</string>
|
||||
<string name="send_scan_type">Type de requête</string>
|
||||
<string name="send_type_get_add_content">GET et ajouter simplement le contenu</string>
|
||||
<string name="send_type_get_query_string">GET avec chaîne de requête complète</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
@@ -152,6 +167,7 @@
|
||||
<string name="export_database">Exporter la base de données SQLite</string>
|
||||
<string name="saved_in_downloads">Sauvegardé dans les Téléchargements</string>
|
||||
<string name="rotate_image_cw">Tourner l\'image dans le sens horaire</string>
|
||||
<string name="toggle_free_rotation">Activer la rotation libre</string>
|
||||
<string name="pick_file">Choisir un fichier image</string>
|
||||
<string name="pick_code_to_scan">Choisissez le code à scanner</string>
|
||||
<string name="shortcut_decode">Scanner un code-barres</string>
|
||||
@@ -168,4 +184,6 @@
|
||||
<string name="wifi_anonymous_identity">Identité anonyme</string>
|
||||
<string name="wifi_identity">Identité</string>
|
||||
<string name="wifi_phase2">Méthode de la phase 2</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -15,14 +15,20 @@
|
||||
<string name="error_correction_level_m" formatted="false">Közepes (~15% javítás)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Kvartilis (~25% javítás)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Magas (~30% javítás)</string>
|
||||
<string name="issue_number">Hibaszám</string>
|
||||
<string name="orientation">Tájolás</string>
|
||||
<string name="other_meta_data">Metaadat</string>
|
||||
<string name="pdf417_extra_metadata">PDF417 metaadat</string>
|
||||
<string name="possible_country">Gyártó lehetséges országa</string>
|
||||
<string name="suggested_price">Ajánlott ár</string>
|
||||
<string name="upc_ean_extension">UPC EAN kiterjesztés</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">Hibaszám</string>
|
||||
<string name="gtin_country">Gyártó lehetséges országa</string>
|
||||
<string name="gtin_price">Ajánlott ár</string>
|
||||
<string name="gtin_add_on">UPC EAN kiterjesztés</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">Vaku be- vagy kikapcsolása</string>
|
||||
<string name="error_flash">Hiba a vaku be- vagy kikapcsolásakor</string>
|
||||
<string name="share">Megosztás</string>
|
||||
@@ -75,6 +81,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">A beolvasott adatok gyors megjelenítése folyamatos beolvasáskor.</string>
|
||||
<string name="vibrate">Rezgetés felismeréskor</string>
|
||||
<string name="vibrate_summary">Akkor engedélyezze ezt, ha rezgetni szeretné az eszközét egy kód felismerésekor.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Beolvasási előzmények mentése</string>
|
||||
<string name="use_history_summary">Felismert kódok mentése a saját eszközén.</string>
|
||||
<string name="ignore_consecutive_duplicates">Ne mentsen egymást követő azonos adatokat</string>
|
||||
@@ -85,10 +100,10 @@
|
||||
<string name="copy_immediately_summary">Beolvasott tartalom automatikus másolása a vágólapra. Ne feledje, hogy más alkalmazások megfigyelhetik a vágólapját a háttérben.</string>
|
||||
<string name="show_meta_data">Metaadatok megjelenítése</string>
|
||||
<string name="show_meta_data_summary">További adatok megjelenítése a beolvasott vonalkódokról.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">Hexakiírás megjelenítése</string>
|
||||
<string name="show_hex_dump_summary">A beolvasott tartalom hexakiírásának megjelenítése.</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">Ugrás vissza másolás vagy megosztás után</string>
|
||||
<string name="close_automatically_summary">Automatikus visszatérés a beolvasási képernyőre a beolvasott tartalom másolása vagy megosztása után.</string>
|
||||
<string name="default_search_engine">Ismeretlen adatok megnyitása ebben</string>
|
||||
@@ -151,6 +166,7 @@
|
||||
<string name="export_database">SQLite adatbázis</string>
|
||||
<string name="saved_in_downloads">Elmentve a letöltésekbe</string>
|
||||
<string name="rotate_image_cw">Kép forgatása jobbra</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">Képfájl kiválasztása</string>
|
||||
<string name="pick_code_to_scan">Kód kiválasztása a beolvasáshoz</string>
|
||||
<string name="shortcut_decode">Vonalkód beolvasása</string>
|
||||
@@ -167,4 +183,6 @@
|
||||
<string name="wifi_anonymous_identity">Névtelen személyazonosság</string>
|
||||
<string name="wifi_identity">Személyazonosság</string>
|
||||
<string name="wifi_phase2">Phase 2 módszer</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -14,16 +14,22 @@
|
||||
<string name="error_correction_level_m" formatted="false">Medium (~15% koreksi)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Kuartil (~25% koreksi)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Tinggi (~30% koreksi)</string>
|
||||
<string name="issue_number">Nomor pindaian</string>
|
||||
<string name="orientation">Orientasi</string>
|
||||
<string name="other_meta_data">Metadata</string>
|
||||
<string name="pdf417_extra_metadata">Metadata PDF417</string>
|
||||
<string name="possible_country">Kemungkinan negara pembuat</string>
|
||||
<string name="suggested_price">Harga yang disarankan</string>
|
||||
<string name="upc_ean_extension">Ekstensi UPC EAN</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">Muka dan latar belakang</string>
|
||||
<string name="colors_black_on_white">Hitam di atas putih</string>
|
||||
<string name="colors_white_on_black">Putih di atas hitam</string>
|
||||
<string name="colors_black_on_transparent">Hitam di atas tansparan</string>
|
||||
<string name="colors_white_on_transparent">Putih di atas tansparan</string>
|
||||
<string name="sequence_size">Ukuran sekuens</string>
|
||||
<string name="sequence_index">Indeks sekuens</string>
|
||||
<string name="sequence_id">ID Sekuens</string>
|
||||
<string name="gtin_issue_number">Nomor pindaian</string>
|
||||
<string name="gtin_country">Kemungkinan negara pembuat</string>
|
||||
<string name="gtin_price">Harga yang disarankan</string>
|
||||
<string name="gtin_add_on">Ekstensi UPC EAN</string>
|
||||
<string name="barcode_version_number">Versi</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modul)</string>
|
||||
<string name="toggle_flash">Nyala/matikan blitz</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="error_flash">Galat nyala/matikan blitz</string>
|
||||
<string name="share">Bagikan</string>
|
||||
<string name="share_as">Bagikan sebagai?</string>
|
||||
<string name="copy_to_clipboard">Salin ke clipboard</string>
|
||||
@@ -44,16 +50,16 @@
|
||||
<string name="info">Info</string>
|
||||
<string name="switch_camera">Ganti kamera</string>
|
||||
<string name="bulk_mode">Pindai tanpa henti</string>
|
||||
<string name="bulk_mode_summary">Always start scanning continuously.</string>
|
||||
<string name="bulk_mode_delay">Delay between continuous scans</string>
|
||||
<string name="restrict_format">Restrict format</string>
|
||||
<string name="remove_restriction">Remove restriction</string>
|
||||
<string name="scan_format">Scan %s</string>
|
||||
<string name="quarter_second">A quarter second</string>
|
||||
<string name="half_second">Half a second</string>
|
||||
<string name="a_second">One second</string>
|
||||
<string name="two_seconds">Two seconds</string>
|
||||
<string name="five_seconds">Five seconds</string>
|
||||
<string name="bulk_mode_summary">Selalu mulai pemindaian tanpa henti.</string>
|
||||
<string name="bulk_mode_delay">Tundaan antara pemindaian tanpa henti</string>
|
||||
<string name="restrict_format">Batasi format</string>
|
||||
<string name="remove_restriction">Hapus pembatasan</string>
|
||||
<string name="scan_format">Pindai %s</string>
|
||||
<string name="quarter_second">Seperempat detik</string>
|
||||
<string name="half_second">Setengah detik</string>
|
||||
<string name="a_second">Satu detik</string>
|
||||
<string name="two_seconds">Dua detik</string>
|
||||
<string name="five_seconds">Lima detik</string>
|
||||
<string name="history">Riwayat</string>
|
||||
<string name="preferences">Preferensi</string>
|
||||
<string name="scan_category">Pemindaian</string>
|
||||
@@ -63,17 +69,26 @@
|
||||
<string name="follow_system_settings">Ikuti pengaturan sistem</string>
|
||||
<string name="show_crop_handle">Tampilkan pembatas pemotongan</string>
|
||||
<string name="show_crop_handle_summary">Batasi pemindaian ke batas area tertentu.</string>
|
||||
<string name="barcode_formats">Barcode formats</string>
|
||||
<string name="barcode_formats">Format barcode</string>
|
||||
<string name="zoom_by_swiping">Geser ke atas/bawah untuk memperbesar</string>
|
||||
<string name="zoom_by_swiping_summary">Geser layar kamera ke atas atau ke bawah untuk mengontrol perbesaran gambar.</string>
|
||||
<string name="auto_rotate">Kenali barcode vertikal 1D</string>
|
||||
<string name="auto_rotate_summary">Otomatis putar frame kamera mengenali barcode vertikal 1D. Tergantung pada perangkat, mungkin akan berpengaruh pada performa.</string>
|
||||
<string name="try_harder">Optimalkan akurasi pembaca</string>
|
||||
<string name="try_harder_summary">Aktifkan opsi ini untuk kode yang susah dibaca. Akan berpengaruh pada performa.</string>
|
||||
<string name="show_toast_in_bulk_mode">Show data in continuous mode</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Briefly show the scanned data when scanning continuously.</string>
|
||||
<string name="show_toast_in_bulk_mode">Tampilkan data dalam mode tanpa henti</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Tampilkan data secara singkat saat memindai tanpa henti.</string>
|
||||
<string name="vibrate">Bergetar saat mendeteksi</string>
|
||||
<string name="vibrate_summary">Aktifkan opsi ini jika anda ingin perangkat anda bergetar ketika kode berhasil dipindai.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Simpan riwayat pemindaian</string>
|
||||
<string name="use_history_summary">Simpan kode yang berhasil dipindai pada perangkat anda.</string>
|
||||
<string name="ignore_consecutive_duplicates">Abaikan duplikat</string>
|
||||
@@ -84,31 +99,31 @@
|
||||
<string name="copy_immediately_summary">Otomatis menyalin konten yang dipindai ke dalam clipboard. Harap diingat bahwa apl lain bisa melihat isi dari clipboard anda di latar belakang.</string>
|
||||
<string name="show_meta_data">Tampilkan metadata</string>
|
||||
<string name="show_meta_data_summary">Tampilkan data tambahan tentang barcode yang dipindai.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">Tampilkan hex dump</string>
|
||||
<string name="show_hex_dump_summary">Tampilkan hex dump dari konten hasil pemindaian.</string>
|
||||
<string name="close_automatically">Go back after Copy/Share</string>
|
||||
<string name="close_automatically_summary">Automatically return to the scan screen after copying or sharing the read contents.</string>
|
||||
<string name="default_search_engine">Open unknown data in</string>
|
||||
<string name="always_ask">Always ask</string>
|
||||
<string name="show_recreation">Tampilkan barcode yang dibuat ulang</string>
|
||||
<string name="show_recreation_summary">Buat ulang dan tampilkan barcode dari isi konten jika memungkinkan.</string>
|
||||
<string name="close_automatically">Kembali setelah Salin/Berbagi</string>
|
||||
<string name="close_automatically_summary">Otomatis kembali ke layar pemindaian setelah menyalin atau berbagi isi konten.</string>
|
||||
<string name="default_search_engine">Buka data tak dikenal di</string>
|
||||
<string name="always_ask">Selalu tanya</string>
|
||||
<string name="open_with_url">Buka data tak dikenal dengan URL</string>
|
||||
<string name="clear_network_suggestions">Clear network suggestions</string>
|
||||
<string name="clear_network_suggestions_summary">Remove all of the network suggestions that were previously provided by this app.</string>
|
||||
<string name="really_remove_all_networks">Really remove all networks?</string>
|
||||
<string name="clear_network_suggestions_success">Network suggestions cleared</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Nothing to remove</string>
|
||||
<string name="clear_network_suggestions">Hapus saran jaringan</string>
|
||||
<string name="clear_network_suggestions_summary">Hapus semua saran jaringan yang sebelumnya disediakan oleh aplikasi ini.</string>
|
||||
<string name="really_remove_all_networks">Yakin menghapus semua jaringan?</string>
|
||||
<string name="clear_network_suggestions_success">Saran jaringan dihapus</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Tidak ada yang perlu dihapus</string>
|
||||
<string name="send_category">Penerusan</string>
|
||||
<string name="send_scan_active">Forward scans</string>
|
||||
<string name="send_scan_active_summary">Enable to forward scans to a the given URL</string>
|
||||
<string name="send_scan_active">Teruskan pemindaian</string>
|
||||
<string name="send_scan_active_summary">Aktifkan penerusan pemindaian ke URL berikut</string>
|
||||
<string name="send_scan_url">Kirim setiap pindaian ke URL</string>
|
||||
<string name="send_scan_type">Tipe permintaan untuk setiap pindaian</string>
|
||||
<string name="send_type_get_add_content">GET dan tambahkan konten</string>
|
||||
<string name="send_type_get_query_string">GET dengan kueri lema lengkap</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Open in external browser</string>
|
||||
<string name="test_url">Test URL</string>
|
||||
<string name="send_type_external_browser">Buka di peramban eksternal</string>
|
||||
<string name="test_url">URL Tes</string>
|
||||
<string name="really_remove_scan">Yakin menghapus pindaian?</string>
|
||||
<string name="really_remove_all_scans">Yakin menghapus semua pindaian?</string>
|
||||
<string name="really_remove_selected_scans">Yakin menghapus pindaian yang dipilih?</string>
|
||||
@@ -150,20 +165,23 @@
|
||||
<string name="export_database">Ekspor basis data SQLite</string>
|
||||
<string name="saved_in_downloads">Simpan di dalam unduhan</string>
|
||||
<string name="rotate_image_cw">Putar gambar searah jarum jam</string>
|
||||
<string name="toggle_free_rotation">Nyala/matikan rotasi bebas</string>
|
||||
<string name="pick_file">Pilih berkas gambar</string>
|
||||
<string name="pick_code_to_scan">Pilih kode untuk dipindai</string>
|
||||
<string name="shortcut_decode">Pindai barcode</string>
|
||||
<string name="shortcut_encode">Buat barcode</string>
|
||||
<string name="shortcut_preferences">Pengaturan</string>
|
||||
<string name="background_request_failed">Permintaan latar belakang gagal</string>
|
||||
<string name="entry_type">Type</string>
|
||||
<string name="wifi_network">Wi-Fi network</string>
|
||||
<string name="wifi_ssid">Name</string>
|
||||
<string name="wifi_type">Authentication type</string>
|
||||
<string name="wifi_password">Password</string>
|
||||
<string name="wifi_hidden">Hidden network</string>
|
||||
<string name="wifi_eap">EAP method</string>
|
||||
<string name="wifi_anonymous_identity">Anonymous identity</string>
|
||||
<string name="wifi_identity">Identity</string>
|
||||
<string name="wifi_phase2">Phase 2 method</string>
|
||||
<string name="entry_type">Tipe</string>
|
||||
<string name="wifi_network">Jaringan Wi-Fi</string>
|
||||
<string name="wifi_ssid">Nama</string>
|
||||
<string name="wifi_type">Tipe otentikasi</string>
|
||||
<string name="wifi_password">Sandi</string>
|
||||
<string name="wifi_hidden">Jaringan tersembunyi</string>
|
||||
<string name="wifi_eap">Metode EAP</string>
|
||||
<string name="wifi_anonymous_identity">Identitas anonim</string>
|
||||
<string name="wifi_identity">Identitas</string>
|
||||
<string name="wifi_phase2">Metode fase 2</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">Quest\'app non ha alcun senso senza l\'accesso alla fotocamera. Ciao.</string>
|
||||
<string name="camera_error">Impossibile accedere alla fotocamera, riprova</string>
|
||||
<string name="camera_error">Impossibile accedere alla fotocamera. Riprova</string>
|
||||
<string name="scan_code">Scansiona codice</string>
|
||||
<string name="compose_barcode">Crea codice a barre</string>
|
||||
<string name="decode_barcode">Decodifica codice a barre</string>
|
||||
@@ -10,34 +10,40 @@
|
||||
<item quantity="one">%2$d carattere, %1$s</item>
|
||||
<item quantity="other">%2$d caratteri, %1$s</item>
|
||||
</plurals>
|
||||
<string name="error_correction_level">Livello di correzione errori</string>
|
||||
<string name="error_correction_level_l" formatted="false">Low (~7% correction)</string>
|
||||
<string name="error_correction_level_m" formatted="false">Medium (~15% correction)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartile (~25% correction)</string>
|
||||
<string name="error_correction_level_h" formatted="false">High (~30% correction)</string>
|
||||
<string name="issue_number">Numero di edizione</string>
|
||||
<string name="orientation">Orientamento</string>
|
||||
<string name="other_meta_data">Metadati</string>
|
||||
<string name="pdf417_extra_metadata">Metadati PDF417</string>
|
||||
<string name="possible_country">Probabile Paese di fabbricazione</string>
|
||||
<string name="suggested_price">Prezzo consigliato</string>
|
||||
<string name="upc_ean_extension">Estensione UPC EAN</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="toggle_flash">Flash</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="error_correction_level">Livello correzione errori</string>
|
||||
<string name="error_correction_level_l" formatted="false">Basso (correzione del ~7%)</string>
|
||||
<string name="error_correction_level_m" formatted="false">Medio (correzione del ~15%)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartile (correzione del ~25%)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Alto (correzione del ~30%)</string>
|
||||
<string name="colors">Colore primo piano/sfondo</string>
|
||||
<string name="colors_black_on_white">Nero su bianco</string>
|
||||
<string name="colors_white_on_black">Bianco su nero</string>
|
||||
<string name="colors_black_on_transparent">Nero su trasparente</string>
|
||||
<string name="colors_white_on_transparent">Bianco su trasparente</string>
|
||||
<string name="sequence_size">Dimensione sequenza</string>
|
||||
<string name="sequence_index">Indice sequenza</string>
|
||||
<string name="sequence_id">ID sequenza</string>
|
||||
<string name="gtin_issue_number">Numero edizione</string>
|
||||
<string name="gtin_country">Probabile nazione fabbricazione</string>
|
||||
<string name="gtin_price">Prezzo consigliato</string>
|
||||
<string name="gtin_add_on">Estensione UPC EAN</string>
|
||||
<string name="barcode_version_number">Versione</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d moduli)</string>
|
||||
<string name="toggle_flash">Attiva/disattiva flash</string>
|
||||
<string name="error_flash">Errore durante l\'attivazione/disattivazione del flash</string>
|
||||
<string name="share">Condividi</string>
|
||||
<string name="share_as">Share as?</string>
|
||||
<string name="copy_to_clipboard">Copia negli appunti</string>
|
||||
<string name="copied_to_clipboard">Copiato negli appunti</string>
|
||||
<string name="copy_password">Copia password negli appunti</string>
|
||||
<string name="copied_password_to_clipboard">Password copiata negli appunti</string>
|
||||
<string name="share_as">Condividi come?</string>
|
||||
<string name="copy_to_clipboard">Copia negli Appunti</string>
|
||||
<string name="copied_to_clipboard">Copiato negli Appunti</string>
|
||||
<string name="copy_password">Copia password negli Appunti</string>
|
||||
<string name="copied_password_to_clipboard">Password copiata negli Appunti</string>
|
||||
<string name="open_url">Apri URL</string>
|
||||
<string name="cannot_resolve_action">Nessuna app può aprirlo</string>
|
||||
<string name="pick_search_engine">Scegli un motore di ricerca</string>
|
||||
<string name="pick_search_engine">Scegli motore di ricerca</string>
|
||||
<string name="format">Formato</string>
|
||||
<string name="size">Dimensioni in pixel</string>
|
||||
<string name="size">Dimensioni (pixel)</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="input_content_here">Inserisci il contenuto qui</string>
|
||||
<string name="input_content_here">Inserisci qui il contenuto</string>
|
||||
<string name="encode">CODIFICA</string>
|
||||
<string name="error_no_content">Contenuto mancante</string>
|
||||
<string name="error_encoding_barcode">Il codice a barre non può essere generato</string>
|
||||
@@ -45,86 +51,95 @@
|
||||
<string name="info">Info</string>
|
||||
<string name="switch_camera">Cambia fotocamera</string>
|
||||
<string name="bulk_mode">Scansione continua</string>
|
||||
<string name="bulk_mode_summary">Always start scanning continuously.</string>
|
||||
<string name="bulk_mode_delay">Delay between continuous scans</string>
|
||||
<string name="restrict_format">Restrict format</string>
|
||||
<string name="remove_restriction">Remove restriction</string>
|
||||
<string name="scan_format">Scan %s</string>
|
||||
<string name="quarter_second">A quarter second</string>
|
||||
<string name="half_second">Half a second</string>
|
||||
<string name="a_second">One second</string>
|
||||
<string name="two_seconds">Two seconds</string>
|
||||
<string name="five_seconds">Five seconds</string>
|
||||
<string name="bulk_mode_summary">Avvia sempre la scansione in modo continuo.</string>
|
||||
<string name="bulk_mode_delay">Ritardo tra scansioni continue</string>
|
||||
<string name="restrict_format">Limita formato</string>
|
||||
<string name="remove_restriction">Rimuovi la limitazione</string>
|
||||
<string name="scan_format">Scansiona %s</string>
|
||||
<string name="quarter_second">Un quarto di secondo</string>
|
||||
<string name="half_second">Mezzo secondo</string>
|
||||
<string name="a_second">Un secondo</string>
|
||||
<string name="two_seconds">Due secondi</string>
|
||||
<string name="five_seconds">Cinque secondi</string>
|
||||
<string name="history">Cronologia</string>
|
||||
<string name="preferences">Preferenze</string>
|
||||
<string name="scan_category">Scansione</string>
|
||||
<string name="content_category">Contenuto</string>
|
||||
<string name="locale_category">Language</string>
|
||||
<string name="custom_locale">Custom language</string>
|
||||
<string name="follow_system_settings">Follow system settings</string>
|
||||
<string name="show_crop_handle">Mostra riquadro di limite</string>
|
||||
<string name="locale_category">Lingua</string>
|
||||
<string name="custom_locale">Lingua personalizzata</string>
|
||||
<string name="follow_system_settings">Usa le impostazioni di sistema</string>
|
||||
<string name="show_crop_handle">Visualizza riquadro limite</string>
|
||||
<string name="show_crop_handle_summary">Limita la scansione ad una regione personalizzata.</string>
|
||||
<string name="barcode_formats">Barcode formats</string>
|
||||
<string name="barcode_formats">Formati codici a barre</string>
|
||||
<string name="zoom_by_swiping">Zoom fotocamera scorrendo su/giù</string>
|
||||
<string name="zoom_by_swiping_summary">Scorri su o giù per controllare lo zoom della fotocamera.</string>
|
||||
<string name="auto_rotate">Riconosci i codici a barre 1D verticalmente</string>
|
||||
<string name="auto_rotate_summary">Ruota automaticamente la fotocamera per riconoscere i codici a barre 1D verticali. In base al dispositivo, potrebbe ridurre le prestazioni.</string>
|
||||
<string name="try_harder">Ottimizza il lettore per accuratezza, non velocità</string>
|
||||
<string name="auto_rotate">Riconosci codici a barre verticali</string>
|
||||
<string name="auto_rotate_summary">Ruota automaticamente la fotocamera per riconoscere i codici a barre verticali. In base al dispositivo, potrebbe ridurre le prestazioni.</string>
|
||||
<string name="try_harder">Ottimizza il lettore per accuratezza</string>
|
||||
<string name="try_harder_summary">Attiva questa opzione per codici molto difficili da leggere. Riduce le prestazioni.</string>
|
||||
<string name="show_toast_in_bulk_mode">Show data in continuous mode</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Briefly show the scanned data when scanning continuously.</string>
|
||||
<string name="show_toast_in_bulk_mode">Visualizza i dati in modalità continua</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Durante la scansione continua vsualizza brevemente i dati scansionati.</string>
|
||||
<string name="vibrate">Vibra quando rilevato</string>
|
||||
<string name="vibrate_summary">Attivalo se vuoi che il dispositivo vibri quando viene riconosciuto un codice.</string>
|
||||
<string name="use_history">Salva cronologia delle scansioni</string>
|
||||
<string name="use_history_summary">Salva i codici riconosciuti sul dispositivo.</string>
|
||||
<string name="ignore_consecutive_duplicates">Non salvare doppi consecutivi</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">Non salvare doppi consecutivi nella cronologia di scansione.</string>
|
||||
<string name="open_immediately">Salta l\'analisi e apri i contenuti direttamente</string>
|
||||
<string name="open_immediately_summary">Salta l\'analisi e apri i contenuti direttamente. Se attivo potrebbe aprire contenuti dannosi.</string>
|
||||
<string name="copy_immediately">Copia negli appunti</string>
|
||||
<string name="copy_immediately_summary">Copia automaticamente i contenuti scansionati negli appunti. Nota che altre app potrebbero leggere gli appunti in secondo piano.</string>
|
||||
<string name="show_meta_data">Mostra metadati</string>
|
||||
<string name="show_meta_data_summary">Mostra dati aggiuntivi sul codice a barre scansionato.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">Mostra dump esadecimale</string>
|
||||
<string name="show_hex_dump_summary">Mostra un dump esadecimale dei contenuti scansionati.</string>
|
||||
<string name="close_automatically">Go back after Copy/Share</string>
|
||||
<string name="close_automatically_summary">Automatically return to the scan screen after copying or sharing the read contents.</string>
|
||||
<string name="default_search_engine">Open unknown data in</string>
|
||||
<string name="always_ask">Always ask</string>
|
||||
<string name="beep">Beep al rilevamento</string>
|
||||
<string name="beep_summary">Abilita questa opzione se vuoi che il dispositivo emetta un beep quando viene riconosciuto un codice.</string>
|
||||
<string name="beep_tone">Tono beep</string>
|
||||
<string name="tone_cdma_confirm">Conferma CDMA</string>
|
||||
<string name="tone_sup_confirm">Conferma supervisione chiamata</string>
|
||||
<string name="tone_sup_radio_ack">Riconoscimento percorso radio supervisione chiamata</string>
|
||||
<string name="tone_prop_ack">Riconoscimento positivo</string>
|
||||
<string name="tone_prop_beep">Beep generale</string>
|
||||
<string name="tone_prop_beep2">Doppio beep generale</string>
|
||||
<string name="use_history">Salva cronologia scansioni</string>
|
||||
<string name="use_history_summary">Salva i codici riconosciuti nel dispositivo.</string>
|
||||
<string name="ignore_consecutive_duplicates">Ignora i duplicati</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">Non salvare duplicati consecutivi nella cronologia di scansione.</string>
|
||||
<string name="open_immediately">Apri subito</string>
|
||||
<string name="open_immediately_summary">Salta l\'ispezione e apri i contenuti immediatamente. Se abilitato può aprire contenuti dannosi.</string>
|
||||
<string name="copy_immediately">Copia negli Appunti</string>
|
||||
<string name="copy_immediately_summary">Copia automaticamente i contenuti scansionati negli Appunti. Nota che altre app potrebbero leggere gli Appunti in secondo piano.</string>
|
||||
<string name="show_meta_data">Visualizza metadati</string>
|
||||
<string name="show_meta_data_summary">Visualizza dati aggiuntivi sul codice a barre scansionato.</string>
|
||||
<string name="show_hex_dump">Visualizza dump esadecimale</string>
|
||||
<string name="show_hex_dump_summary">Visualizza un dump esadecimale dei contenuti scansionati.</string>
|
||||
<string name="show_recreation">Visualizza il codice a barre ricreato</string>
|
||||
<string name="show_recreation_summary">Ricrea e visualizza, se possibile, il codice a barre dal contenuto letto.</string>
|
||||
<string name="close_automatically">Vai indietro dopo la copia/condivisione</string>
|
||||
<string name="close_automatically_summary">Dopo aver copiato o condiviso i contenuti letti torna automaticamente alla schermata di scansione.</string>
|
||||
<string name="default_search_engine">Apri dati sconosciuti in</string>
|
||||
<string name="always_ask">Chiedi sempre</string>
|
||||
<string name="open_with_url">Apri dati sconosciuti con URL</string>
|
||||
<string name="clear_network_suggestions">Clear network suggestions</string>
|
||||
<string name="clear_network_suggestions_summary">Remove all of the network suggestions that were previously provided by this app.</string>
|
||||
<string name="really_remove_all_networks">Really remove all networks?</string>
|
||||
<string name="clear_network_suggestions_success">Network suggestions cleared</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Nothing to remove</string>
|
||||
<string name="clear_network_suggestions">Cancella suggerimenti di rete</string>
|
||||
<string name="clear_network_suggestions_summary">Cancella tutti i suggerimenti di rete precedentemente forniti da questa app.</string>
|
||||
<string name="really_remove_all_networks">Vuoi rimuovere tutte le reti?</string>
|
||||
<string name="clear_network_suggestions_success">Suggerimenti di rete cancellati</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Niente da rimuovere</string>
|
||||
<string name="send_category">Inoltro</string>
|
||||
<string name="send_scan_active">Forward scans</string>
|
||||
<string name="send_scan_active_summary">Enable to forward scans to a the given URL</string>
|
||||
<string name="send_scan_url">Invia ogni scansione ad un URL</string>
|
||||
<string name="send_scan_type">Tipo di richiesta per ogni scansione</string>
|
||||
<string name="send_type_get_add_content">GET e aggiungi il contenuto</string>
|
||||
<string name="send_type_get_query_string">GET con stringa completa della richiesta</string>
|
||||
<string name="send_scan_active">Inoltra le scansioni</string>
|
||||
<string name="send_scan_active_summary">Abilita per inoltrare le scansioni a un URL specificato</string>
|
||||
<string name="send_scan_url">URL a cui inoltrare</string>
|
||||
<string name="send_scan_type">Tipo di richiesta</string>
|
||||
<string name="send_type_get_add_content">OTTIENI e aggiungi il contenuto</string>
|
||||
<string name="send_type_get_query_string">OTTIENI con stringa completa della richiesta</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Open in external browser</string>
|
||||
<string name="test_url">Test URL</string>
|
||||
<string name="really_remove_scan">Vuoi veramente rimuovere la scansione?</string>
|
||||
<string name="really_remove_all_scans">Vuoi veramente rimuovere tutte le scansioni?</string>
|
||||
<string name="really_remove_selected_scans">Vuoi veramente rimuovere le scansioni selezionate?</string>
|
||||
<string name="clear_history">Pulisci cronologia</string>
|
||||
<string name="send_type_external_browser">Apri nel browser esterno</string>
|
||||
<string name="test_url">Prova URL</string>
|
||||
<string name="really_remove_scan">Vuoi rimuovere la scansione?</string>
|
||||
<string name="really_remove_all_scans">Vuoi rimuovere tutte le scansioni?</string>
|
||||
<string name="really_remove_selected_scans">Vuoi rimuovere le scansioni selezionate?</string>
|
||||
<string name="clear_history">Azzera cronologia</string>
|
||||
<string name="copy_scan">Copia scansione</string>
|
||||
<string name="edit_scan">Modifica etichetta</string>
|
||||
<string name="remove_scan">Rimuovi scansione</string>
|
||||
<string name="enter_name">Inserisci un nome per descrivere la scansione</string>
|
||||
<string name="enter_name_hint">Nome della scansione</string>
|
||||
<string name="enter_name_hint">Nome scansione</string>
|
||||
<string name="no_barcode_found">Nessun codice a barre trovato</string>
|
||||
<string name="pick_list_separator">Come separare elementi della lista?</string>
|
||||
<string name="separator_line_break">Interruzione di linea</string>
|
||||
<string name="separator_ruler">Righello</string>
|
||||
<string name="save_as_file_name">Salvare come file?</string>
|
||||
<string name="file_name">Nome del file</string>
|
||||
<string name="save_as_file_name">Salva come file nei Download?</string>
|
||||
<string name="file_name">Nome file</string>
|
||||
<string name="error_saving_file">Impossibile salvare il file</string>
|
||||
<string name="error_file_exists">Il file esiste già</string>
|
||||
<string name="connect_to_wifi">Connetti al WiFi</string>
|
||||
@@ -144,27 +159,30 @@
|
||||
<string name="search_web">Cerca nel web</string>
|
||||
<string name="search_scan">Cerca scansione</string>
|
||||
<string name="export_to_file">Esporta su file</string>
|
||||
<string name="export_as">Esportare come?</string>
|
||||
<string name="export_as">Come esportare?</string>
|
||||
<string name="export_csv_comma">CSV con virgole</string>
|
||||
<string name="export_csv_semicolon">CSV con punti e virgola</string>
|
||||
<string name="export_json">Esporta come JSON</string>
|
||||
<string name="export_database">Esporta database SQLite</string>
|
||||
<string name="export_json">File JSON</string>
|
||||
<string name="export_database">Database SQLite</string>
|
||||
<string name="saved_in_downloads">Salvato nei download</string>
|
||||
<string name="rotate_image_cw">Ruota immagine in senso orario</string>
|
||||
<string name="toggle_free_rotation">Abilita/disabilita rotazione libera</string>
|
||||
<string name="pick_file">Scegli file immagine</string>
|
||||
<string name="pick_code_to_scan">Scegli codice da scansionare</string>
|
||||
<string name="shortcut_decode">Scansiona un codice a barre</string>
|
||||
<string name="shortcut_encode">Crea un codice a barre</string>
|
||||
<string name="shortcut_preferences">Impostazioni</string>
|
||||
<string name="background_request_failed">Richiesta in secondo piano fallita</string>
|
||||
<string name="entry_type">Type</string>
|
||||
<string name="wifi_network">Wi-Fi network</string>
|
||||
<string name="wifi_ssid">Name</string>
|
||||
<string name="wifi_type">Authentication type</string>
|
||||
<string name="entry_type">Tipo</string>
|
||||
<string name="wifi_network">Rete WiFi</string>
|
||||
<string name="wifi_ssid">Nome</string>
|
||||
<string name="wifi_type">Tipo di autenticazione</string>
|
||||
<string name="wifi_password">Password</string>
|
||||
<string name="wifi_hidden">Hidden network</string>
|
||||
<string name="wifi_eap">EAP method</string>
|
||||
<string name="wifi_anonymous_identity">Anonymous identity</string>
|
||||
<string name="wifi_identity">Identity</string>
|
||||
<string name="wifi_phase2">Phase 2 method</string>
|
||||
<string name="wifi_hidden">Rete nascosta</string>
|
||||
<string name="wifi_eap">Metodo EAP</string>
|
||||
<string name="wifi_anonymous_identity">Identità anonima</string>
|
||||
<string name="wifi_identity">Identità</string>
|
||||
<string name="wifi_phase2">Metodo fase 2</string>
|
||||
<string name="network_suggestions">Suggerimenti di rete</string>
|
||||
<string name="remove_suggestion">Cancella suggerimento</string>
|
||||
</resources>
|
||||
|
||||
@@ -14,14 +14,20 @@
|
||||
<string name="error_correction_level_m" formatted="false">中 (~15% の正確性)</string>
|
||||
<string name="error_correction_level_q" formatted="false">高 (~25% の正確性)</string>
|
||||
<string name="error_correction_level_h" formatted="false">最高 (~30% の正確性)</string>
|
||||
<string name="issue_number">発行番号</string>
|
||||
<string name="orientation">方向</string>
|
||||
<string name="other_meta_data">メタデータ</string>
|
||||
<string name="pdf417_extra_metadata">PDF417 メタデータ</string>
|
||||
<string name="possible_country">製造国</string>
|
||||
<string name="suggested_price">価格</string>
|
||||
<string name="upc_ean_extension">UPC/EAN 拡張型</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">背面と前面</string>
|
||||
<string name="colors_black_on_white">白地に黒色</string>
|
||||
<string name="colors_white_on_black">黒地に白色</string>
|
||||
<string name="colors_black_on_transparent">透明に黒色</string>
|
||||
<string name="colors_white_on_transparent">透明に白色</string>
|
||||
<string name="sequence_size">配列寸法</string>
|
||||
<string name="sequence_index">配列番号</string>
|
||||
<string name="sequence_id">配列ID</string>
|
||||
<string name="gtin_issue_number">発行番号</string>
|
||||
<string name="gtin_country">製造国</string>
|
||||
<string name="gtin_price">価格</string>
|
||||
<string name="gtin_add_on">UPC/EAN 拡張型</string>
|
||||
<string name="barcode_version_number">バージョン</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">フラッシュの切り替え</string>
|
||||
<string name="error_flash">フラッシュの切り替えエラー</string>
|
||||
<string name="share">共有</string>
|
||||
@@ -74,6 +80,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">「まとめてスキャンする」オプションが有効の際、スキャンしたデータを簡潔に表示するようにします。</string>
|
||||
<string name="vibrate">認識時に振動する</string>
|
||||
<string name="vibrate_summary">バーコードが認識されたときにバイブレーションを行います。</string>
|
||||
<string name="beep">検出時にビープ音を鳴らす</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">ビープ音</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">一般的なビープ音</string>
|
||||
<string name="tone_prop_beep2">一般的なダブルビープ音</string>
|
||||
<string name="use_history">スキャン履歴を保存する</string>
|
||||
<string name="use_history_summary">認識されたバーコードを端末に保存しておきます。</string>
|
||||
<string name="ignore_consecutive_duplicates">重複を破棄する</string>
|
||||
@@ -84,10 +99,10 @@
|
||||
<string name="copy_immediately_summary">スキャンされたコンテンツを自動的にクリップボードにコピーします。他のアプリはクリップボードの内容を見ることができることにご注意ください。</string>
|
||||
<string name="show_meta_data">メタデータを表示</string>
|
||||
<string name="show_meta_data_summary">スキャンされたバーコードの追加データを確認できるようにします。</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">16進数を表示</string>
|
||||
<string name="show_hex_dump_summary">スキャンされたコンテンツの16進数データを確認できるようにします。</string>
|
||||
<string name="show_recreation">再生成したバーコードを表示</string>
|
||||
<string name="show_recreation_summary">可能であれば、読み取ったコンテンツからバーコードを再生成して表示します。</string>
|
||||
<string name="close_automatically">コピー/共有後に戻る</string>
|
||||
<string name="close_automatically_summary">コンテンツをコピー/共有した後、自動的にスキャン画面に戻るようにします。</string>
|
||||
<string name="default_search_engine">未知のデータの表示方法</string>
|
||||
@@ -150,6 +165,7 @@
|
||||
<string name="export_database">SQLiteデータベース</string>
|
||||
<string name="saved_in_downloads">ダウンロードフォルダに保存されました</string>
|
||||
<string name="rotate_image_cw">時計回りに回転</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">画像を選択して読み込み</string>
|
||||
<string name="pick_code_to_scan">スキャンするバーコードを選択</string>
|
||||
<string name="shortcut_decode">バーコードをスキャン</string>
|
||||
@@ -162,8 +178,10 @@
|
||||
<string name="wifi_type">認証方式</string>
|
||||
<string name="wifi_password">パスワード</string>
|
||||
<string name="wifi_hidden">非表示のネットワーク</string>
|
||||
<string name="wifi_eap">EAP method</string>
|
||||
<string name="wifi_eap">EAP方式</string>
|
||||
<string name="wifi_anonymous_identity">Anonymous identity</string>
|
||||
<string name="wifi_identity">Identity</string>
|
||||
<string name="wifi_phase2">Phase 2 method</string>
|
||||
<string name="wifi_phase2">フェーズ2方式</string>
|
||||
<string name="network_suggestions">ネットワークに関する提案</string>
|
||||
<string name="remove_suggestion">提案の削除</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,170 +1,188 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">ამ აპლიკაციის გამოყენება შეუძლებელია კამერაზე ნებართვის მინიჭების გარეშე</string>
|
||||
<string name="camera_error">კამერაზე წვდომის მოპოვება ვერ ხერხდება, გთხოვთ, კიდევ სცადეთ</string>
|
||||
<string name="scan_code">შტრიხ-კოდის სკანირება</string>
|
||||
<string name="compose_barcode">შტრიხ-კოდის შექმნა</string>
|
||||
<string name="decode_barcode">შტრიხ-კოდის დეკოდირება</string>
|
||||
<string name="content">ტექსტი</string>
|
||||
<string name="binary_data">(ორობითი მონაცემები)</string>
|
||||
<plurals name="barcode_info">
|
||||
<item quantity="one">%2$d სიმბოლო, %1$s</item>
|
||||
<item quantity="other">%2$d სიმბოლო, %1$s</item>
|
||||
</plurals>
|
||||
<string name="error_correction_level">შეცდომების კორექციის დონე</string>
|
||||
<string name="error_correction_level_l" formatted="false">Low (~7% correction)</string>
|
||||
<string name="error_correction_level_m" formatted="false">Medium (~15% correction)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartile (~25% correction)</string>
|
||||
<string name="error_correction_level_h" formatted="false">High (~30% correction)</string>
|
||||
<string name="issue_number">გამოშვების ნომერი</string>
|
||||
<string name="orientation">ორიენტაცია</string>
|
||||
<string name="other_meta_data">მეტამონაცემები</string>
|
||||
<string name="pdf417_extra_metadata">PDF417 მეტამონაცემები</string>
|
||||
<string name="possible_country">შესაძლო მწარმოებელი ქვეყანა</string>
|
||||
<string name="suggested_price">დაახლოებითი ფასი</string>
|
||||
<string name="upc_ean_extension">UPC EAN გაფართოება</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="toggle_flash">განათების ჩართვა</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="share">გაზიარება</string>
|
||||
<string name="share_as">Share as?</string>
|
||||
<string name="copy_to_clipboard">გაცვლის ბუფერში კოპირება</string>
|
||||
<string name="copied_to_clipboard">კოპირებულია გაცვლის ბუფერში</string>
|
||||
<string name="copy_password">პაროლის გაცვლით ბუფერში კოპირება</string>
|
||||
<string name="copied_password_to_clipboard">პაროლი კოპირებულია გაცვლის ბუფერში</string>
|
||||
<string name="open_url">ბმულის გახსნა</string>
|
||||
<string name="cannot_resolve_action">ამ მოქმედებისთვის აპლიკაცია ნაპოვნი არაა</string>
|
||||
<string name="pick_search_engine">აირჩიეთ საძიებო სისტემა</string>
|
||||
<string name="format">ფორმატი</string>
|
||||
<string name="size">ზომა პიქსელებში</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="input_content_here">შეიყვანეთ ტექსტი აქ</string>
|
||||
<string name="encode">შექმნა"</string>
|
||||
<string name="error_no_content">მონაცემები არაა</string>
|
||||
<string name="error_encoding_barcode">შტრიხ-კოდის შექმნა შეუძლებელია</string>
|
||||
<string name="view_barcode">შტრიხ-კოდის ნახვა</string>
|
||||
<string name="info">ინფორმაცია</string>
|
||||
<string name="switch_camera">კამერის გადართვა</string>
|
||||
<string name="bulk_mode">სკანირება უწყვეტად</string>
|
||||
<string name="bulk_mode_summary">Always start scanning continuously.</string>
|
||||
<string name="bulk_mode_delay">Delay between continuous scans</string>
|
||||
<string name="restrict_format">Restrict format</string>
|
||||
<string name="remove_restriction">Remove restriction</string>
|
||||
<string name="scan_format">Scan %s</string>
|
||||
<string name="quarter_second">A quarter second</string>
|
||||
<string name="half_second">Half a second</string>
|
||||
<string name="a_second">One second</string>
|
||||
<string name="two_seconds">Two seconds</string>
|
||||
<string name="five_seconds">Five seconds</string>
|
||||
<string name="history">ისტორია</string>
|
||||
<string name="preferences">პარამეტრები</string>
|
||||
<string name="scan_category">სკანირება</string>
|
||||
<string name="content_category">კონტენტი</string>
|
||||
<string name="locale_category">Language</string>
|
||||
<string name="custom_locale">Custom language</string>
|
||||
<string name="follow_system_settings">Follow system settings</string>
|
||||
<string name="show_crop_handle">სკანირების არეალის ჩვენება</string>
|
||||
<string name="show_crop_handle_summary">სკანირების შეზღუდვა შერჩეული არეალით.</string>
|
||||
<string name="barcode_formats">Barcode formats</string>
|
||||
<string name="zoom_by_swiping">მასშტაბირება თითის მოძრაობით მაღლა/დაბლა</string>
|
||||
<string name="zoom_by_swiping_summary">გაატარეთ თითი მაღლა ან დაბლა კამერის მასშტაბირების სამართავად.</string>
|
||||
<string name="auto_rotate">1D ვერტიკალური შტრიხ-კოდების ამოცნობა</string>
|
||||
<string name="auto_rotate_summary">კამერის ავტომატური შეტრიალება ვერტიკალური 1D შტრიხ-კოდების ამოსაცნობად. მოწყობილობიდან გამომდინარე, შესაძლოა იმოქმედოს წარმადობაზე.</string>
|
||||
<string name="try_harder">წაკითხვის ოპტიმიზირება სიზუსტეზე და არა სისწრაფეზე</string>
|
||||
<string name="try_harder_summary">ეს პარამეტრი ჩართეთ იმ შტრიხ-კოდებისთვის, რომელთა ამოცნობაც ძალიან ძნელია. მოქმედებს წარმადობაზე.</string>
|
||||
<string name="show_toast_in_bulk_mode">Show data in continuous mode</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Briefly show the scanned data when scanning continuously.</string>
|
||||
<string name="vibrate">ვიბრირება პოვნისას</string>
|
||||
<string name="vibrate_summary">ჩართეთ ეს პარამეტრი, თუ გსურთ მოწყობილობის ვიბრირება,როდესაც შტრიხ-კოდი ამოცნობილი იქნება.</string>
|
||||
<string name="use_history">სკანირების ისტორიის შენახვა</string>
|
||||
<string name="use_history_summary">ამოცნობილი შტრიხ-კოდების მოწყობილობაზე შენახვა.</string>
|
||||
<string name="ignore_consecutive_duplicates">არ შევინახოთ შემდგომი ასლები</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">არ შევინახოთ შემდგომი ასლები სკანირების ისტორიაში.</string>
|
||||
<string name="open_immediately">შემოწმების გამოტოვება და მყისიერი გახსნა</string>
|
||||
<string name="open_immediately_summary">შემოწმების გამოტოვება და მყისიერი გახსნა. შესაძლოა გამოიწვიოს არასასარგებლო კონტენტის ჩვენება.</string>
|
||||
<string name="copy_immediately">გაცვლის ბუფერში ავტომატური კოპირება</string>
|
||||
<string name="copy_immediately_summary">სკანირებული შტრიხ-კოდის კონტენტის ავტომატური კოპირება გაცვლის ბუფერში. გთხოვთ გაითვალისწინოთ,ზოგიერთ პროგრამას შესაძლოა ჰქონდეს ფონური წვდომა გაცვლის ბუფერთან.</string>
|
||||
<string name="show_meta_data">მეტამონაცემების ჩვენება</string>
|
||||
<string name="show_meta_data_summary">სკანირებულ შტრიხ-კოდებზე დამატებითი ინფორმაციის ჩვენება.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">თექვსმეტობითი dump-ის ჩვენება</string>
|
||||
<string name="show_hex_dump_summary">სკანირებული შტრიხ-კოდის კონტენტის თექვსმეტობითი dump-ის ჩვენება.</string>
|
||||
<string name="close_automatically">Go back after Copy/Share</string>
|
||||
<string name="close_automatically_summary">Automatically return to the scan screen after copying or sharing the read contents.</string>
|
||||
<string name="default_search_engine">Open unknown data in</string>
|
||||
<string name="always_ask">Always ask</string>
|
||||
<string name="open_with_url">უცნობი მონაცემების ამ ბმულის საშუალებით გახსნა</string>
|
||||
<string name="clear_network_suggestions">Clear network suggestions</string>
|
||||
<string name="clear_network_suggestions_summary">Remove all of the network suggestions that were previously provided by this app.</string>
|
||||
<string name="really_remove_all_networks">Really remove all networks?</string>
|
||||
<string name="clear_network_suggestions_success">Network suggestions cleared</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Nothing to remove</string>
|
||||
<string name="send_category">გადაგზავნა</string>
|
||||
<string name="send_scan_active">Forward scans</string>
|
||||
<string name="send_scan_active_summary">Enable to forward scans to a the given URL</string>
|
||||
<string name="send_scan_url">ყოველი სკანირებული შტრიხ-კოდის ბმულის საშუალებით გახსნა</string>
|
||||
<string name="send_scan_type">მოთხოვნის ტიპი ყოველი სკანირებული შტრიხ-კოდისთვის</string>
|
||||
<string name="send_type_get_add_content">GET კონტენტის დამატებით</string>
|
||||
<string name="send_type_get_query_string">GET მოთხოვნის სრული პარამეტრებით</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Open in external browser</string>
|
||||
<string name="test_url">Test URL</string>
|
||||
<string name="really_remove_scan">ნამდვილად გსურთ სკანირების წაშლა?</string>
|
||||
<string name="really_remove_all_scans">ნამდვილად გსურთ ყველაფრის წაშლა?</string>
|
||||
<string name="really_remove_selected_scans">ნამდვილად გსურთ შერჩეული შტრიხ-კოდების წაშლა?</string>
|
||||
<string name="clear_history">ისტორიის გასუფთავება</string>
|
||||
<string name="copy_scan">კოპირება</string>
|
||||
<string name="edit_scan">რედაქტირება</string>
|
||||
<string name="remove_scan">სკანირების წაშლა</string>
|
||||
<string name="enter_name">მიანიჭეთ სახელი სკანირებას</string>
|
||||
<string name="enter_name_hint">სკანირების სახელი</string>
|
||||
<string name="no_barcode_found">შტრიხ-კოდი ვერ მოიძებნა</string>
|
||||
<string name="pick_list_separator">რითი გავყოთ სიის ელემენტები?</string>
|
||||
<string name="separator_line_break">ხაზის გამყოფი</string>
|
||||
<string name="separator_ruler">ჰორიზონტალური ხაზი</string>
|
||||
<string name="save_as_file_name">ფაილის შენახვა როგორც</string>
|
||||
<string name="file_name">ფაილის სახელი</string>
|
||||
<string name="error_saving_file">ფაილის შენახვა ვერ ხერხდება</string>
|
||||
<string name="error_file_exists">ფაილი უკვე არსებობს</string>
|
||||
<string name="connect_to_wifi">დაკავშირება WiFi-სთან</string>
|
||||
<string name="wifi_config_failed">WiFi კონფიგურაცია ვერ მოხერხდა</string>
|
||||
<string name="wifi_added">WiFi დამატებულია</string>
|
||||
<string name="sms_send">შეტყობინების გაგზავნა</string>
|
||||
<string name="sms_error">შეტყობინების გაგზავნა ვერ მოხერხდა</string>
|
||||
<string name="tel_dial">ნომრის აკრეფა</string>
|
||||
<string name="tel_error">ნომრის აკრეფა ვერ მოხერხდა</string>
|
||||
<string name="mail_send">წერილის გაგზავნა</string>
|
||||
<string name="mail_error">წერილი ვერ გაიგზავნა</string>
|
||||
<string name="vcard_add">კონტაქტებში დამატება</string>
|
||||
<string name="vcard_failed">კონტაქტებში დამატება ვერ მოხერხდა</string>
|
||||
<string name="vevent_add">კალენდარში დამატება</string>
|
||||
<string name="vevent_failed">კალენდარში დამატება ვერ მოხერხდა</string>
|
||||
<string name="otpauth_add">დავამატოთ 2FA</string>
|
||||
<string name="search_web">ქსელში მოძებნა</string>
|
||||
<string name="search_scan">სკანირების ძიება</string>
|
||||
<string name="export_to_file">ექსპორტი ფაილში</string>
|
||||
<string name="export_as">შესანახი ფაილის ფორმატი</string>
|
||||
<string name="export_csv_comma">CSV (გამყოფი - მძიმე)</string>
|
||||
<string name="export_csv_semicolon">CSV (გამყოფი - წერტილ-მძიმე,)</string>
|
||||
<string name="export_json">JSON</string>
|
||||
<string name="export_database">SQLite მონაცემთა ბაზა</string>
|
||||
<string name="saved_in_downloads">შენახულია გადმოწერებში</string>
|
||||
<string name="rotate_image_cw">გამოსახულების შემობრუნება საათის ისრის მიხედვით</string>
|
||||
<string name="pick_file">აირჩიეთ ფაილი გამოსახულებით</string>
|
||||
<string name="pick_code_to_scan">აირჩიეთ შტრიხ-კოდი სკანირებისთვის</string>
|
||||
<string name="shortcut_decode">შტრიხ-კოდის სკანირება</string>
|
||||
<string name="shortcut_encode">შტრიხ-კოდის შექმნა</string>
|
||||
<string name="shortcut_preferences">პარამეტრები</string>
|
||||
<string name="background_request_failed">ფონური მოთხოვნა ვერ მოხერხდა</string>
|
||||
<string name="entry_type">Type</string>
|
||||
<string name="wifi_network">Wi-Fi network</string>
|
||||
<string name="wifi_ssid">Name</string>
|
||||
<string name="wifi_type">Authentication type</string>
|
||||
<string name="wifi_password">Password</string>
|
||||
<string name="wifi_hidden">Hidden network</string>
|
||||
<string name="wifi_eap">EAP method</string>
|
||||
<string name="wifi_anonymous_identity">Anonymous identity</string>
|
||||
<string name="wifi_identity">Identity</string>
|
||||
<string name="wifi_phase2">Phase 2 method</string>
|
||||
</resources>
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">ამ აპლიკაციის გამოყენება შეუძლებელია კამერაზე ნებართვის მინიჭების გარეშე</string>
|
||||
<string name="camera_error">კამერაზე წვდომის მოპოვება ვერ ხერხდება, გთხოვთ, კიდევ სცადეთ</string>
|
||||
<string name="scan_code">შტრიხ-კოდის სკანირება</string>
|
||||
<string name="compose_barcode">შტრიხ-კოდის შექმნა</string>
|
||||
<string name="decode_barcode">შტრიხ-კოდის დეკოდირება</string>
|
||||
<string name="content">ტექსტი</string>
|
||||
<string name="binary_data">(ორობითი მონაცემები)</string>
|
||||
<plurals name="barcode_info">
|
||||
<item quantity="one">%2$d სიმბოლო, %1$s</item>
|
||||
<item quantity="other">%2$d სიმბოლო, %1$s</item>
|
||||
</plurals>
|
||||
<string name="error_correction_level">შეცდომების კორექციის დონე</string>
|
||||
<string name="error_correction_level_l" formatted="false">Low (~7% correction)</string>
|
||||
<string name="error_correction_level_m" formatted="false">Medium (~15% correction)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartile (~25% correction)</string>
|
||||
<string name="error_correction_level_h" formatted="false">High (~30% correction)</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">გამოშვების ნომერი</string>
|
||||
<string name="gtin_country">შესაძლო მწარმოებელი ქვეყანა</string>
|
||||
<string name="gtin_price">დაახლოებითი ფასი</string>
|
||||
<string name="gtin_add_on">UPC EAN გაფართოება</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">განათების ჩართვა</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="share">გაზიარება</string>
|
||||
<string name="share_as">Share as?</string>
|
||||
<string name="copy_to_clipboard">გაცვლის ბუფერში კოპირება</string>
|
||||
<string name="copied_to_clipboard">კოპირებულია გაცვლის ბუფერში</string>
|
||||
<string name="copy_password">პაროლის გაცვლით ბუფერში კოპირება</string>
|
||||
<string name="copied_password_to_clipboard">პაროლი კოპირებულია გაცვლის ბუფერში</string>
|
||||
<string name="open_url">ბმულის გახსნა</string>
|
||||
<string name="cannot_resolve_action">ამ მოქმედებისთვის აპლიკაცია ნაპოვნი არაა</string>
|
||||
<string name="pick_search_engine">აირჩიეთ საძიებო სისტემა</string>
|
||||
<string name="format">ფორმატი</string>
|
||||
<string name="size">ზომა პიქსელებში</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="input_content_here">შეიყვანეთ ტექსტი აქ</string>
|
||||
<string name="encode">შექმნა"</string>
|
||||
<string name="error_no_content">მონაცემები არაა</string>
|
||||
<string name="error_encoding_barcode">შტრიხ-კოდის შექმნა შეუძლებელია</string>
|
||||
<string name="view_barcode">შტრიხ-კოდის ნახვა</string>
|
||||
<string name="info">ინფორმაცია</string>
|
||||
<string name="switch_camera">კამერის გადართვა</string>
|
||||
<string name="bulk_mode">სკანირება უწყვეტად</string>
|
||||
<string name="bulk_mode_summary">Always start scanning continuously.</string>
|
||||
<string name="bulk_mode_delay">Delay between continuous scans</string>
|
||||
<string name="restrict_format">Restrict format</string>
|
||||
<string name="remove_restriction">Remove restriction</string>
|
||||
<string name="scan_format">Scan %s</string>
|
||||
<string name="quarter_second">A quarter second</string>
|
||||
<string name="half_second">Half a second</string>
|
||||
<string name="a_second">One second</string>
|
||||
<string name="two_seconds">Two seconds</string>
|
||||
<string name="five_seconds">Five seconds</string>
|
||||
<string name="history">ისტორია</string>
|
||||
<string name="preferences">პარამეტრები</string>
|
||||
<string name="scan_category">სკანირება</string>
|
||||
<string name="content_category">კონტენტი</string>
|
||||
<string name="locale_category">Language</string>
|
||||
<string name="custom_locale">Custom language</string>
|
||||
<string name="follow_system_settings">Follow system settings</string>
|
||||
<string name="show_crop_handle">სკანირების არეალის ჩვენება</string>
|
||||
<string name="show_crop_handle_summary">სკანირების შეზღუდვა შერჩეული არეალით.</string>
|
||||
<string name="barcode_formats">Barcode formats</string>
|
||||
<string name="zoom_by_swiping">მასშტაბირება თითის მოძრაობით მაღლა/დაბლა</string>
|
||||
<string name="zoom_by_swiping_summary">გაატარეთ თითი მაღლა ან დაბლა კამერის მასშტაბირების სამართავად.</string>
|
||||
<string name="auto_rotate">1D ვერტიკალური შტრიხ-კოდების ამოცნობა</string>
|
||||
<string name="auto_rotate_summary">კამერის ავტომატური შეტრიალება ვერტიკალური 1D შტრიხ-კოდების ამოსაცნობად. მოწყობილობიდან გამომდინარე, შესაძლოა იმოქმედოს წარმადობაზე.</string>
|
||||
<string name="try_harder">წაკითხვის ოპტიმიზირება სიზუსტეზე და არა სისწრაფეზე</string>
|
||||
<string name="try_harder_summary">ეს პარამეტრი ჩართეთ იმ შტრიხ-კოდებისთვის, რომელთა ამოცნობაც ძალიან ძნელია. მოქმედებს წარმადობაზე.</string>
|
||||
<string name="show_toast_in_bulk_mode">Show data in continuous mode</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Briefly show the scanned data when scanning continuously.</string>
|
||||
<string name="vibrate">ვიბრირება პოვნისას</string>
|
||||
<string name="vibrate_summary">ჩართეთ ეს პარამეტრი, თუ გსურთ მოწყობილობის ვიბრირება,როდესაც შტრიხ-კოდი ამოცნობილი იქნება.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">სკანირების ისტორიის შენახვა</string>
|
||||
<string name="use_history_summary">ამოცნობილი შტრიხ-კოდების მოწყობილობაზე შენახვა.</string>
|
||||
<string name="ignore_consecutive_duplicates">არ შევინახოთ შემდგომი ასლები</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">არ შევინახოთ შემდგომი ასლები სკანირების ისტორიაში.</string>
|
||||
<string name="open_immediately">შემოწმების გამოტოვება და მყისიერი გახსნა</string>
|
||||
<string name="open_immediately_summary">შემოწმების გამოტოვება და მყისიერი გახსნა. შესაძლოა გამოიწვიოს არასასარგებლო კონტენტის ჩვენება.</string>
|
||||
<string name="copy_immediately">გაცვლის ბუფერში ავტომატური კოპირება</string>
|
||||
<string name="copy_immediately_summary">სკანირებული შტრიხ-კოდის კონტენტის ავტომატური კოპირება გაცვლის ბუფერში. გთხოვთ გაითვალისწინოთ,ზოგიერთ პროგრამას შესაძლოა ჰქონდეს ფონური წვდომა გაცვლის ბუფერთან.</string>
|
||||
<string name="show_meta_data">მეტამონაცემების ჩვენება</string>
|
||||
<string name="show_meta_data_summary">სკანირებულ შტრიხ-კოდებზე დამატებითი ინფორმაციის ჩვენება.</string>
|
||||
<string name="show_hex_dump">თექვსმეტობითი dump-ის ჩვენება</string>
|
||||
<string name="show_hex_dump_summary">სკანირებული შტრიხ-კოდის კონტენტის თექვსმეტობითი dump-ის ჩვენება.</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">Go back after Copy/Share</string>
|
||||
<string name="close_automatically_summary">Automatically return to the scan screen after copying or sharing the read contents.</string>
|
||||
<string name="default_search_engine">Open unknown data in</string>
|
||||
<string name="always_ask">Always ask</string>
|
||||
<string name="open_with_url">უცნობი მონაცემების ამ ბმულის საშუალებით გახსნა</string>
|
||||
<string name="clear_network_suggestions">Remove network suggestions</string>
|
||||
<string name="clear_network_suggestions_summary">Remove network suggestions that were previously added with this app.</string>
|
||||
<string name="really_remove_all_networks">Really remove all networks?</string>
|
||||
<string name="clear_network_suggestions_success">Network suggestions cleared</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Nothing to remove</string>
|
||||
<string name="send_category">გადაგზავნა</string>
|
||||
<string name="send_scan_active">Forward scans</string>
|
||||
<string name="send_scan_active_summary">Enable to forward scans to a the given URL</string>
|
||||
<string name="send_scan_url">ყოველი სკანირებული შტრიხ-კოდის ბმულის საშუალებით გახსნა</string>
|
||||
<string name="send_scan_type">მოთხოვნის ტიპი ყოველი სკანირებული შტრიხ-კოდისთვის</string>
|
||||
<string name="send_type_get_add_content">GET კონტენტის დამატებით</string>
|
||||
<string name="send_type_get_query_string">GET მოთხოვნის სრული პარამეტრებით</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Open in external browser</string>
|
||||
<string name="test_url">Test URL</string>
|
||||
<string name="really_remove_scan">ნამდვილად გსურთ სკანირების წაშლა?</string>
|
||||
<string name="really_remove_all_scans">ნამდვილად გსურთ ყველაფრის წაშლა?</string>
|
||||
<string name="really_remove_selected_scans">ნამდვილად გსურთ შერჩეული შტრიხ-კოდების წაშლა?</string>
|
||||
<string name="clear_history">ისტორიის გასუფთავება</string>
|
||||
<string name="copy_scan">კოპირება</string>
|
||||
<string name="edit_scan">რედაქტირება</string>
|
||||
<string name="remove_scan">სკანირების წაშლა</string>
|
||||
<string name="enter_name">მიანიჭეთ სახელი სკანირებას</string>
|
||||
<string name="enter_name_hint">სკანირების სახელი</string>
|
||||
<string name="no_barcode_found">შტრიხ-კოდი ვერ მოიძებნა</string>
|
||||
<string name="pick_list_separator">რითი გავყოთ სიის ელემენტები?</string>
|
||||
<string name="separator_line_break">ხაზის გამყოფი</string>
|
||||
<string name="separator_ruler">ჰორიზონტალური ხაზი</string>
|
||||
<string name="save_as_file_name">ფაილის შენახვა როგორც</string>
|
||||
<string name="file_name">ფაილის სახელი</string>
|
||||
<string name="error_saving_file">ფაილის შენახვა ვერ ხერხდება</string>
|
||||
<string name="error_file_exists">ფაილი უკვე არსებობს</string>
|
||||
<string name="connect_to_wifi">დაკავშირება WiFi-სთან</string>
|
||||
<string name="wifi_config_failed">WiFi კონფიგურაცია ვერ მოხერხდა</string>
|
||||
<string name="wifi_added">WiFi დამატებულია</string>
|
||||
<string name="sms_send">შეტყობინების გაგზავნა</string>
|
||||
<string name="sms_error">შეტყობინების გაგზავნა ვერ მოხერხდა</string>
|
||||
<string name="tel_dial">ნომრის აკრეფა</string>
|
||||
<string name="tel_error">ნომრის აკრეფა ვერ მოხერხდა</string>
|
||||
<string name="mail_send">წერილის გაგზავნა</string>
|
||||
<string name="mail_error">წერილი ვერ გაიგზავნა</string>
|
||||
<string name="vcard_add">კონტაქტებში დამატება</string>
|
||||
<string name="vcard_failed">კონტაქტებში დამატება ვერ მოხერხდა</string>
|
||||
<string name="vevent_add">კალენდარში დამატება</string>
|
||||
<string name="vevent_failed">კალენდარში დამატება ვერ მოხერხდა</string>
|
||||
<string name="otpauth_add">დავამატოთ 2FA</string>
|
||||
<string name="search_web">ქსელში მოძებნა</string>
|
||||
<string name="search_scan">სკანირების ძიება</string>
|
||||
<string name="export_to_file">ექსპორტი ფაილში</string>
|
||||
<string name="export_as">შესანახი ფაილის ფორმატი</string>
|
||||
<string name="export_csv_comma">CSV (გამყოფი - მძიმე)</string>
|
||||
<string name="export_csv_semicolon">CSV (გამყოფი - წერტილ-მძიმე,)</string>
|
||||
<string name="export_json">JSON</string>
|
||||
<string name="export_database">SQLite მონაცემთა ბაზა</string>
|
||||
<string name="saved_in_downloads">შენახულია გადმოწერებში</string>
|
||||
<string name="rotate_image_cw">გამოსახულების შემობრუნება საათის ისრის მიხედვით</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">აირჩიეთ ფაილი გამოსახულებით</string>
|
||||
<string name="pick_code_to_scan">აირჩიეთ შტრიხ-კოდი სკანირებისთვის</string>
|
||||
<string name="shortcut_decode">შტრიხ-კოდის სკანირება</string>
|
||||
<string name="shortcut_encode">შტრიხ-კოდის შექმნა</string>
|
||||
<string name="shortcut_preferences">პარამეტრები</string>
|
||||
<string name="background_request_failed">ფონური მოთხოვნა ვერ მოხერხდა</string>
|
||||
<string name="entry_type">Type</string>
|
||||
<string name="wifi_network">Wi-Fi network</string>
|
||||
<string name="wifi_ssid">Name</string>
|
||||
<string name="wifi_type">Authentication type</string>
|
||||
<string name="wifi_password">Password</string>
|
||||
<string name="wifi_hidden">Hidden network</string>
|
||||
<string name="wifi_eap">EAP method</string>
|
||||
<string name="wifi_anonymous_identity">Anonymous identity</string>
|
||||
<string name="wifi_identity">Identity</string>
|
||||
<string name="wifi_phase2">Phase 2 method</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">This app does not make any sense without camera access. Good bye.</string>
|
||||
<string name="camera_error">카메라를 접근할 수 없습니다. 다시 시도하세요</string>
|
||||
<string name="scan_code">Scan code</string>
|
||||
<string name="compose_barcode">Compose barcode</string>
|
||||
<string name="decode_barcode">Decode barcode</string>
|
||||
<string name="content">Content</string>
|
||||
<string name="binary_data">(binary data)</string>
|
||||
<plurals name="barcode_info">
|
||||
<item quantity="one">%2$d character, %1$s</item>
|
||||
<item quantity="other">%2$d characters, %1$s</item>
|
||||
</plurals>
|
||||
<string name="error_correction_level">Error correction level</string>
|
||||
<string name="error_correction_level_l" formatted="false">Low (~7% correction)</string>
|
||||
<string name="error_correction_level_m" formatted="false">Medium (~15% correction)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartile (~25% correction)</string>
|
||||
<string name="error_correction_level_h" formatted="false">High (~30% correction)</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">이슈번호</string>
|
||||
<string name="gtin_country">Possible country of manufacture</string>
|
||||
<string name="gtin_price">Suggested price</string>
|
||||
<string name="gtin_add_on">UPC EAN extension</string>
|
||||
<string name="barcode_version_number">버전</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">Toggle flash</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="share">Share</string>
|
||||
<string name="share_as">Share as?</string>
|
||||
<string name="copy_to_clipboard">Copy to clipboard</string>
|
||||
<string name="copied_to_clipboard">Copied to clipboard</string>
|
||||
<string name="copy_password">Copy password into clipboard</string>
|
||||
<string name="copied_password_to_clipboard">Password copied to clipboard</string>
|
||||
<string name="open_url">Open url</string>
|
||||
<string name="cannot_resolve_action">No application can open that</string>
|
||||
<string name="pick_search_engine">Pick a search engine</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="size">Size in pixels</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="input_content_here">Input content here</string>
|
||||
<string name="encode">ENCODE</string>
|
||||
<string name="error_no_content">Missing content</string>
|
||||
<string name="error_encoding_barcode">Barcode cannot be generated</string>
|
||||
<string name="view_barcode">View barcode</string>
|
||||
<string name="info">Info</string>
|
||||
<string name="switch_camera">Switch camera</string>
|
||||
<string name="bulk_mode">Scan continuously</string>
|
||||
<string name="bulk_mode_summary">Always start scanning continuously.</string>
|
||||
<string name="bulk_mode_delay">Delay between continuous scans</string>
|
||||
<string name="restrict_format">Restrict format</string>
|
||||
<string name="remove_restriction">Remove restriction</string>
|
||||
<string name="scan_format">Scan %s</string>
|
||||
<string name="quarter_second">A quarter second</string>
|
||||
<string name="half_second">Half a second</string>
|
||||
<string name="a_second">One second</string>
|
||||
<string name="two_seconds">Two seconds</string>
|
||||
<string name="five_seconds">Five seconds</string>
|
||||
<string name="history">History</string>
|
||||
<string name="preferences">Preferences</string>
|
||||
<string name="scan_category">Scan</string>
|
||||
<string name="content_category">Content</string>
|
||||
<string name="locale_category">Language</string>
|
||||
<string name="custom_locale">Custom language</string>
|
||||
<string name="follow_system_settings">Follow system settings</string>
|
||||
<string name="show_crop_handle">Show cropping limiter</string>
|
||||
<string name="show_crop_handle_summary">Restrict scanning to a customizable region.</string>
|
||||
<string name="barcode_formats">Barcode formats</string>
|
||||
<string name="zoom_by_swiping">Swipe up/down to zoom</string>
|
||||
<string name="zoom_by_swiping_summary">Swipe up or down in camera screen to control the camera zoom.</string>
|
||||
<string name="auto_rotate">Recognize vertical 1D barcodes</string>
|
||||
<string name="auto_rotate_summary">Automatically rotate the camera frame to recognize vertical 1D barcodes. Depending on the device, this may affect performance.</string>
|
||||
<string name="try_harder">Optimize reader for accuracy</string>
|
||||
<string name="try_harder_summary">Enable this option for very hard to read codes. Will affect performance.</string>
|
||||
<string name="show_toast_in_bulk_mode">Show data in continuous mode</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Briefly show the scanned data when scanning continuously.</string>
|
||||
<string name="vibrate">Vibrate on detection</string>
|
||||
<string name="vibrate_summary">Enable this if you want your device to vibrate when a code is recognized.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Save scan history</string>
|
||||
<string name="use_history_summary">Save recognized codes on your device.</string>
|
||||
<string name="ignore_consecutive_duplicates">Ignore duplicates</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">Do not save consecutive duplicates in the scan history.</string>
|
||||
<string name="open_immediately">Open immediately</string>
|
||||
<string name="open_immediately_summary">Skip inspection and open contents immediately. May open harmful content if enabled.</string>
|
||||
<string name="copy_immediately">Put into clipboard</string>
|
||||
<string name="copy_immediately_summary">Automatically copy scanned contents into clipboard. Please note that other apps may snoop on your clipboard in the background.</string>
|
||||
<string name="show_meta_data">Show metadata</string>
|
||||
<string name="show_meta_data_summary">Show additional data about the scanned barcode.</string>
|
||||
<string name="show_hex_dump">Show hex dump</string>
|
||||
<string name="show_hex_dump_summary">Show a hex dump of the scanned contents.</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">Go back after Copy/Share</string>
|
||||
<string name="close_automatically_summary">Automatically return to the scan screen after copying or sharing the read contents.</string>
|
||||
<string name="default_search_engine">Open unknown data in</string>
|
||||
<string name="always_ask">Always ask</string>
|
||||
<string name="open_with_url">Open unknown data with URL</string>
|
||||
<string name="clear_network_suggestions">Remove network suggestions</string>
|
||||
<string name="clear_network_suggestions_summary">Remove network suggestions that were previously added with this app.</string>
|
||||
<string name="really_remove_all_networks">Really remove all networks?</string>
|
||||
<string name="clear_network_suggestions_success">Network suggestions cleared</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Nothing to remove</string>
|
||||
<string name="send_category">Forwarding</string>
|
||||
<string name="send_scan_active">Forward scans</string>
|
||||
<string name="send_scan_active_summary">Enable to forward scans to a the given URL.</string>
|
||||
<string name="send_scan_url">URL to forward to</string>
|
||||
<string name="send_scan_type">Request type</string>
|
||||
<string name="send_type_get_add_content">GET and simply add content</string>
|
||||
<string name="send_type_get_query_string">GET with complete query string</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Open in external browser</string>
|
||||
<string name="test_url">Test URL</string>
|
||||
<string name="really_remove_scan">Really remove scan?</string>
|
||||
<string name="really_remove_all_scans">Really remove all scans?</string>
|
||||
<string name="really_remove_selected_scans">Really remove selected scans?</string>
|
||||
<string name="clear_history">Clear history</string>
|
||||
<string name="copy_scan">Copy scan</string>
|
||||
<string name="edit_scan">Edit label</string>
|
||||
<string name="remove_scan">Remove scan</string>
|
||||
<string name="enter_name">Enter a name to describe the scan</string>
|
||||
<string name="enter_name_hint">Name of the scan</string>
|
||||
<string name="no_barcode_found">No barcode found</string>
|
||||
<string name="pick_list_separator">How to separate list items?</string>
|
||||
<string name="separator_line_break">Line break</string>
|
||||
<string name="separator_ruler">Ruler</string>
|
||||
<string name="save_as_file_name">Save as in Downloads file?</string>
|
||||
<string name="file_name">File name</string>
|
||||
<string name="error_saving_file">Cannot save file</string>
|
||||
<string name="error_file_exists">File already exists</string>
|
||||
<string name="connect_to_wifi">Connect to WiFi</string>
|
||||
<string name="wifi_config_failed">Could not configure WiFi</string>
|
||||
<string name="wifi_added">WiFi added</string>
|
||||
<string name="sms_send">Send SMS</string>
|
||||
<string name="sms_error">Could not send SMS</string>
|
||||
<string name="tel_dial">Dial number</string>
|
||||
<string name="tel_error">Could not dial number</string>
|
||||
<string name="mail_send">Send mail</string>
|
||||
<string name="mail_error">Could not send mail</string>
|
||||
<string name="vcard_add">Add to contacts</string>
|
||||
<string name="vcard_failed">Could not add to contacts</string>
|
||||
<string name="vevent_add">Add to calendar</string>
|
||||
<string name="vevent_failed">Could not add to calendar</string>
|
||||
<string name="otpauth_add">Add 2FA</string>
|
||||
<string name="search_web">Search the web</string>
|
||||
<string name="search_scan">Search scan</string>
|
||||
<string name="export_to_file">Export to file</string>
|
||||
<string name="export_as">Export as?</string>
|
||||
<string name="export_csv_comma">CSV file with commas</string>
|
||||
<string name="export_csv_semicolon">CSV file with semicolons</string>
|
||||
<string name="export_json">JSON file</string>
|
||||
<string name="export_database">SQLite database</string>
|
||||
<string name="saved_in_downloads">Saved in downloads</string>
|
||||
<string name="rotate_image_cw">Rotate image clockwise</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">Pick image file</string>
|
||||
<string name="pick_code_to_scan">Pick code to scan</string>
|
||||
<string name="shortcut_decode">Scan a barcode</string>
|
||||
<string name="shortcut_encode">Create a barcode</string>
|
||||
<string name="shortcut_preferences">Settings</string>
|
||||
<string name="background_request_failed">Background request failed</string>
|
||||
<string name="entry_type">Type</string>
|
||||
<string name="wifi_network">Wi-Fi network</string>
|
||||
<string name="wifi_ssid">Name</string>
|
||||
<string name="wifi_type">Authentication type</string>
|
||||
<string name="wifi_password">Password</string>
|
||||
<string name="wifi_hidden">Hidden network</string>
|
||||
<string name="wifi_eap">EAP method</string>
|
||||
<string name="wifi_anonymous_identity">Anonymous identity</string>
|
||||
<string name="wifi_identity">Identity</string>
|
||||
<string name="wifi_phase2">Phase 2 method</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
@@ -15,14 +15,20 @@
|
||||
<string name="error_correction_level_m" formatted="false">Middelhoog (~15% correction)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Kwartiel (~25% correction)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Hoog (~30% correction)</string>
|
||||
<string name="issue_number">Uitgiftenummer</string>
|
||||
<string name="orientation">Oriëntatie</string>
|
||||
<string name="other_meta_data">Metadata</string>
|
||||
<string name="pdf417_extra_metadata">PDF417 metadata</string>
|
||||
<string name="possible_country">Mogelijk land van fabricage</string>
|
||||
<string name="suggested_price">Adviesprijs</string>
|
||||
<string name="upc_ean_extension">UPC EAN extensie</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">Uitgiftenummer</string>
|
||||
<string name="gtin_country">Mogelijk land van fabricage</string>
|
||||
<string name="gtin_price">Adviesprijs</string>
|
||||
<string name="gtin_add_on">UPC EAN extensie</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">Zaklamp aan/uit</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="share">Delen</string>
|
||||
@@ -75,6 +81,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">Kort de gescande gegevens tonen bij continu scannen.</string>
|
||||
<string name="vibrate">Trillen bij herkennen</string>
|
||||
<string name="vibrate_summary">Schakel dit in als u wilt dat uw toestel trilt wanneer een code wordt herkend.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Scancodes bewaren</string>
|
||||
<string name="use_history_summary">Bewaar herkende codes op je toestel.</string>
|
||||
<string name="ignore_consecutive_duplicates">Duplicaten negeren</string>
|
||||
@@ -85,10 +100,10 @@
|
||||
<string name="copy_immediately_summary">Kopieer de gescande inhoud automatisch naar het klembord. Let op: andere apps kunnen mogelijk meelezen op de achtergrond.</string>
|
||||
<string name="show_meta_data">Metadata tonen</string>
|
||||
<string name="show_meta_data_summary">Toon extra gegevens over de gescande barcode.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">Hex-dump tonen</string>
|
||||
<string name="show_hex_dump_summary">Hex-dump van de gescande inhoud tonen.</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">Teruggaan na kopiëren/delen</string>
|
||||
<string name="close_automatically_summary">Automatisch terugkeren naar het scanscherm na het kopiëren of delen van de gelezen inhoud.</string>
|
||||
<string name="default_search_engine">Onbekende data openen in</string>
|
||||
@@ -151,6 +166,7 @@
|
||||
<string name="export_database">SQLite database</string>
|
||||
<string name="saved_in_downloads">Opgeslagen in downloads</string>
|
||||
<string name="rotate_image_cw">Afbeelding rechtsom draaien</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">Beeldbestand kiezen</string>
|
||||
<string name="pick_code_to_scan">Kies code om te scannen</string>
|
||||
<string name="shortcut_decode">Een barcode scannen</string>
|
||||
@@ -167,4 +183,6 @@
|
||||
<string name="wifi_anonymous_identity">Anonieme identiteit</string>
|
||||
<string name="wifi_identity">Identiteit</string>
|
||||
<string name="wifi_phase2">Phase 2 methode</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -30,6 +30,14 @@
|
||||
<string name="error_correction_level_m" formatted="false">Średni (~15% korekcji)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Kwartyl (~25% korekcji)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Wysoki (~30% korekcji)</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="export_csv_comma">CSV z przecinkami</string>
|
||||
<string name="export_csv_semicolon">CSV ze średnikami</string>
|
||||
<string name="shortcut_encode">Stwórz kod kreskowy</string>
|
||||
@@ -43,6 +51,7 @@
|
||||
<string name="sms_error">Nie można wysłać SMS-a</string>
|
||||
<string name="mail_error">Nie można wysłać e-maila</string>
|
||||
<string name="rotate_image_cw">Obróć obraz zgodnie z ruchem wskazówek zegara</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="edit_scan">Edytuj etykietę</string>
|
||||
<string name="enter_name_hint">Nazwa skanu</string>
|
||||
<string name="camera_error">Nie można uzyskać dostępu do kamery, spróbuj ponownie</string>
|
||||
@@ -57,12 +66,12 @@
|
||||
<string name="binary_data">(dane binarne)</string>
|
||||
<string name="show_hex_dump">Pokazuj zrzut szesnastkowy</string>
|
||||
<string name="show_hex_dump_summary">Pokaż zeskanowaną zawartośc w postaci szesnastkowej</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">Wróć po skopiowaniu/udostępnieniu</string>
|
||||
<string name="close_automatically_summary">Automatycznie powracaj do ekranu skanowania po skopiowaniu lub udostępnieniu przeczytanej zawartości.</string>
|
||||
<string name="show_meta_data">Pokazuj metadane</string>
|
||||
<string name="show_meta_data_summary">Pokaż dodatkowe dane o zeskanowanym kodzie kreskowym.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="switch_camera">Przełącz aparat</string>
|
||||
<string name="bulk_mode">Skanuj w sposób ciągły</string>
|
||||
<string name="bulk_mode_summary">Zawsze rozpoczynaj skanowanie w sposób ciągły.</string>
|
||||
@@ -81,10 +90,8 @@
|
||||
<string name="zoom_by_swiping">Przybliżaj kamerę, przesuwając w górę/dół</string>
|
||||
<string name="zoom_by_swiping_summary">Przesuń palcem w górę lub w dół na ekranie aparatu, aby sterować powiększeniem aparatu.</string>
|
||||
<string name="view_barcode">Wyświetl kod kreskowy</string>
|
||||
<string name="orientation">Orientacja</string>
|
||||
<string name="error_encoding_barcode">Nie można utworzyć kodu kreskowego</string>
|
||||
<string name="otpauth_add">Dodaj 2FA</string>
|
||||
<string name="other_meta_data">Metadane</string>
|
||||
<string name="remove_scan">Usuń skan</string>
|
||||
<string name="separator_line_break">Przerwanie linii</string>
|
||||
<string name="shortcut_decode">Zeskanuj kod kreskowy</string>
|
||||
@@ -92,6 +99,15 @@
|
||||
<string name="use_history_summary">Zapisz rozpoznane kody na swoim urządzeniu.</string>
|
||||
<string name="vibrate">Wibruj po wykryciu</string>
|
||||
<string name="vibrate_summary">Włącz tę opcję, jeśli chcesz, aby urządzenie wibrowało po rozpoznaniu kodu.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="open_immediately">Pomiń kontrolę i natychmiast otwórz zawartość</string>
|
||||
<string name="open_immediately_summary">Pomiń kontrolę i natychmiast otwórz zawartość. Może otwierać szkodliwą zawartość, jeśli jest włączona.</string>
|
||||
<string name="copy_immediately">Automatycznie skopiuj zawartość do schowka</string>
|
||||
@@ -125,8 +141,7 @@
|
||||
<string name="test_url">Testuj URL</string>
|
||||
<string name="copy_password">Skopiuj hasło do schowka</string>
|
||||
<string name="copied_password_to_clipboard">Hasło skopiowane do schowka</string>
|
||||
<string name="pdf417_extra_metadata">Metadane PDF417</string>
|
||||
<string name="suggested_price">Sugerowana cena</string>
|
||||
<string name="gtin_price">Sugerowana cena</string>
|
||||
<string name="preferences">Ustawienia</string>
|
||||
<string name="scan_category">Skanowanie</string>
|
||||
<string name="content_category">Zawarość</string>
|
||||
@@ -134,9 +149,10 @@
|
||||
<string name="custom_locale">Język niestandardowy</string>
|
||||
<string name="follow_system_settings">Zgodny z ustawieniami systemu</string>
|
||||
<string name="decode_barcode">Dekoduj kod kreskowy</string>
|
||||
<string name="upc_ean_extension">Dodatek UPC EAN</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="possible_country">Możliwy kraj produkcji</string>
|
||||
<string name="gtin_add_on">Dodatek UPC EAN</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="gtin_country">Możliwy kraj produkcji</string>
|
||||
<string name="encode">ZAKODUJ</string>
|
||||
<string name="error_no_content">Brak zawartości</string>
|
||||
<string name="try_harder">Zoptymalizuj czytnik pod kątem dokładności, a nie prędkości</string>
|
||||
@@ -151,7 +167,7 @@
|
||||
<string name="auto_rotate">Rozpoznawaj kody kreskowe 1D pionowo</string>
|
||||
<string name="auto_rotate_summary">Automatycznie obracaj ramkę aparatu, aby rozpoznać pionowe kody kreskowe 1D. W zależności od urządzenia może to mieć wpływ na wydajność.</string>
|
||||
<string name="save_as_file_name">Jak zapisać plik w pobranych?</string>
|
||||
<string name="issue_number">Numer wydania</string>
|
||||
<string name="gtin_issue_number">Numer wydania</string>
|
||||
<string name="background_request_failed">Żądanie w tle nie powiodło się</string>
|
||||
<string name="entry_type">Typ</string>
|
||||
<string name="wifi_network">Sieć Wi-Fi</string>
|
||||
@@ -163,4 +179,6 @@
|
||||
<string name="wifi_anonymous_identity">Anonimowa tożsamość</string>
|
||||
<string name="wifi_identity">Tożsamość</string>
|
||||
<string name="wifi_phase2">Metoda fazy 2</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">Infelizmente você não poderá usar este app sem acesso à câmera.</string>
|
||||
<string name="no_camera_no_fun">Infelizmente você não poderá usar este app sem conceder acesso à câmera.</string>
|
||||
<string name="camera_error">Não foi possível acessar a câmera, por favor tente novamente</string>
|
||||
<string name="scan_code">Escaneie código</string>
|
||||
<string name="scan_code">Aponte ao código</string>
|
||||
<string name="compose_barcode">Criar código</string>
|
||||
<string name="decode_barcode">Reconhecer código</string>
|
||||
<string name="content">Conteúdo</string>
|
||||
@@ -15,46 +15,52 @@
|
||||
<string name="error_correction_level_m" formatted="false">Médio (~15% correção)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartil (~25% correção)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Alto (~30% correção)</string>
|
||||
<string name="issue_number">Número de emissão</string>
|
||||
<string name="orientation">Orientação</string>
|
||||
<string name="other_meta_data">Metadados</string>
|
||||
<string name="pdf417_extra_metadata">Metadados PDF417</string>
|
||||
<string name="possible_country">Possível país de fabricação</string>
|
||||
<string name="suggested_price">Preço sugerido</string>
|
||||
<string name="upc_ean_extension">Extensão UPC EAN</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="toggle_flash">Ativar lanterna</string>
|
||||
<string name="colors">Modo de exibição</string>
|
||||
<string name="colors_black_on_white">Preto sobre fundo branco</string>
|
||||
<string name="colors_white_on_black">Branco sobre fundo preto</string>
|
||||
<string name="colors_black_on_transparent">Preto sobre fundo transparente</string>
|
||||
<string name="colors_white_on_transparent">Branco sobre fundo transparente</string>
|
||||
<string name="sequence_size">Tamanho de sequência</string>
|
||||
<string name="sequence_index">Índice de sequência</string>
|
||||
<string name="sequence_id">ID de sequência</string>
|
||||
<string name="gtin_issue_number">Número de emissão</string>
|
||||
<string name="gtin_country">Possível país de fabricação</string>
|
||||
<string name="gtin_price">Preço sugerido</string>
|
||||
<string name="gtin_add_on">Extensão UPC EAN</string>
|
||||
<string name="barcode_version_number">Versão</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">Ligar lanterna</string>
|
||||
<string name="error_flash">Falha ao ligar a lanterna</string>
|
||||
<string name="share">Compartilhar</string>
|
||||
<string name="share_as">Compartilhar como?</string>
|
||||
<string name="share">Compartilhe</string>
|
||||
<string name="share_as">Compartilhar em qual formato?</string>
|
||||
<string name="copy_to_clipboard">Copiar ao clipboard</string>
|
||||
<string name="copied_to_clipboard">Copiado ao clipboard</string>
|
||||
<string name="copy_password">Copiar senha ao clipboard</string>
|
||||
<string name="copied_password_to_clipboard">Senha copiada ao clipboard</string>
|
||||
<string name="open_url">Abrir a URL</string>
|
||||
<string name="cannot_resolve_action">Nenhum app pode abrir isto</string>
|
||||
<string name="cannot_resolve_action">Nenhum app consegue abrir isto</string>
|
||||
<string name="pick_search_engine">Escolha site de busca</string>
|
||||
<string name="format">Formato</string>
|
||||
<string name="size">Tamanho em píxeis</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="input_content_here">Digite conteúdo aqui</string>
|
||||
<string name="input_content_here">Digite algum conteúdo aqui</string>
|
||||
<string name="encode">CODIFICAR</string>
|
||||
<string name="error_no_content">Conteúdo indisponível</string>
|
||||
<string name="error_encoding_barcode">Não foi possível gerar o código</string>
|
||||
<string name="error_no_content">Digite algum conteúdo acima</string>
|
||||
<string name="error_encoding_barcode">Não foi possível gerar este código</string>
|
||||
<string name="view_barcode">Ver código</string>
|
||||
<string name="info">Detalhes</string>
|
||||
<string name="switch_camera">Alterar câmera</string>
|
||||
<string name="bulk_mode">Digitalização contínua</string>
|
||||
<string name="bulk_mode_summary">Sempre executar em modo contínuo.</string>
|
||||
<string name="bulk_mode_delay">Adiar em escaneamentos contínuos</string>
|
||||
<string name="bulk_mode_delay">Adiar durante digitalização contínua</string>
|
||||
<string name="restrict_format">Limitar formato</string>
|
||||
<string name="remove_restriction">Remover limitação</string>
|
||||
<string name="scan_format">Escanear %s</string>
|
||||
<string name="quarter_second">Um quarto de segundo</string>
|
||||
<string name="half_second">Meio segundo</string>
|
||||
<string name="a_second">Um segundo</string>
|
||||
<string name="two_seconds">Dois segundos</string>
|
||||
<string name="five_seconds">Cinco segundos</string>
|
||||
<string name="a_second">1 segundo</string>
|
||||
<string name="two_seconds">2 segundos</string>
|
||||
<string name="five_seconds">5 segundos</string>
|
||||
<string name="history">Histórico</string>
|
||||
<string name="preferences">Preferências</string>
|
||||
<string name="scan_category">Digitalização</string>
|
||||
@@ -62,95 +68,105 @@
|
||||
<string name="locale_category">Idioma</string>
|
||||
<string name="custom_locale">Idioma da interface</string>
|
||||
<string name="follow_system_settings">Adaptar do sistema</string>
|
||||
<string name="show_crop_handle">Mostrar limitador de corte</string>
|
||||
<string name="show_crop_handle_summary">Limitar a uma área personalizável.</string>
|
||||
<string name="barcode_formats">Tipos de código</string>
|
||||
<string name="zoom_by_swiping">Deslize para baixo/cima para ajustar zoom</string>
|
||||
<string name="show_crop_handle">Mostrar limitador customizável</string>
|
||||
<string name="show_crop_handle_summary">Permite limitar a uma área específica.</string>
|
||||
<string name="barcode_formats">Tipo de código</string>
|
||||
<string name="zoom_by_swiping">Deslize para ajustar zoom</string>
|
||||
<string name="zoom_by_swiping_summary">Deslize para baixo/cima na tela para ajustar zoom da câmera.</string>
|
||||
<string name="auto_rotate">Reconhecer códigos 1D verticais</string>
|
||||
<string name="auto_rotate_summary">Girar automaticamente a câmera para reconhecer códigos 1D verticais. Dependendo do dispositivo, isto pode afetar o desempenho.</string>
|
||||
<string name="try_harder">Otimizar o leitor para precisão</string>
|
||||
<string name="try_harder">Otimizar leitor para precisão</string>
|
||||
<string name="try_harder_summary">Ative esta opção para códigos muito difíceis de ler. Isto afetará o desempenho.</string>
|
||||
<string name="show_toast_in_bulk_mode">Mostrar dados em modo contínuo</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Mostrar brevemente os dados durante digitalização contínua.</string>
|
||||
<string name="vibrate">Vibrar ao reconhecer</string>
|
||||
<string name="vibrate_summary">Ative a opção se quiser que seu dispositivo vibre quando um código for reconhecido.</string>
|
||||
<string name="use_history">Salvar histórico de escaneamentos</string>
|
||||
<string name="vibrate_summary">Ative esta opção se quiser que seu dispositivo vibre ao reconhecer um código.</string>
|
||||
<string name="beep">Bipar ao reconhecer</string>
|
||||
<string name="beep_summary">Ative esta opção se quiser ouvir um bip ao reconhecer um código.</string>
|
||||
<string name="beep_tone">Sinal sonoro</string>
|
||||
<string name="tone_cdma_confirm">Confirmação do CDMA</string>
|
||||
<string name="tone_sup_confirm">Solicitar confirmação de controle</string>
|
||||
<string name="tone_sup_radio_ack">Solicitar confirmação do caminho de rádio</string>
|
||||
<string name="tone_prop_ack">Reconhecimento positivo</string>
|
||||
<string name="tone_prop_beep">Bip geral</string>
|
||||
<string name="tone_prop_beep2">Bip duplo geral</string>
|
||||
<string name="use_history">Ativar histórico de digitalizações</string>
|
||||
<string name="use_history_summary">Salve códigos reconhecidos no seu dispositivo.</string>
|
||||
<string name="ignore_consecutive_duplicates">Ignorar duplicações</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">Não salvar duplicações consecutivas no histórico de escaneamentos.</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">Não salvar duplicações consecutivas no histórico de digitalizações.</string>
|
||||
<string name="open_immediately">Abrir imediatamente</string>
|
||||
<string name="open_immediately_summary">Pular a inspeção e abrir o conteúdo imediatamente. Se ativado pode abrir conteúdo perigoso.</string>
|
||||
<string name="open_immediately_summary">Pular a inspeção e abrir um conteúdo no mesmo instante. Quando ativado, pode abrir conteúdo perigoso.</string>
|
||||
<string name="copy_immediately">Copiar ao clipboard</string>
|
||||
<string name="copy_immediately_summary">Copiar automaticamente o conteúdo escaneado ao clipboard. Tem cuidado porque outros apps podem examinar seu clipboard em segundo plano.</string>
|
||||
<string name="copy_immediately_summary">Copiar automaticamente um conteúdo digitalizado ao clipboard. Tem cuidado porque outros apps podem examinar seu clipboard em segundo plano.</string>
|
||||
<string name="show_meta_data">Mostrar metadados</string>
|
||||
<string name="show_meta_data_summary">Mostrar dados adicionais de código escaneado.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_meta_data_summary">Mostrar dados adicionais de código digitalizado.</string>
|
||||
<string name="show_hex_dump">Mostrar impressão hexadecimal</string>
|
||||
<string name="show_hex_dump_summary">Mostrar a impressão hexadecimal de conteúdo escaneado.</string>
|
||||
<string name="show_hex_dump_summary">Mostrar impressão hexadecimal de conteúdo digitalizado.</string>
|
||||
<string name="show_recreation">Mostrar código recriado</string>
|
||||
<string name="show_recreation_summary">Se possível, recriar e mostrar código de conteúdo lido.</string>
|
||||
<string name="close_automatically">Voltar após copiar/compartilhar</string>
|
||||
<string name="close_automatically_summary">Voltar automaticamente à tela de digitalização após copiar ou compartilhar o código consultado.</string>
|
||||
<string name="close_automatically_summary">Voltar automaticamente à tela de digitalização após copiar ou compartilhar um código examinado.</string>
|
||||
<string name="default_search_engine">Abrir dados desconhecidos em</string>
|
||||
<string name="always_ask">Sempre perguntar</string>
|
||||
<string name="open_with_url">Abrir dados desconhecidos via URL</string>
|
||||
<string name="clear_network_suggestions">Remover sugestões da rede</string>
|
||||
<string name="clear_network_suggestions_summary">Remover todas as sugestões da rede que foram anteriormente fornecidas pelo app.</string>
|
||||
<string name="really_remove_all_networks">Realmente remover todas as redes?</string>
|
||||
<string name="clear_network_suggestions_success">Sugestões da rede removidas</string>
|
||||
<string name="really_remove_all_networks">Deseja remover todas as redes?</string>
|
||||
<string name="clear_network_suggestions_success">Sugestões da rede foram removidas</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Nada para remover</string>
|
||||
<string name="send_category">Encaminhamento</string>
|
||||
<string name="send_scan_active">Encaminhar escaneamentos</string>
|
||||
<string name="send_scan_active_summary">Ativar para encaminhar escaneamentos à URL definida</string>
|
||||
<string name="send_scan_active">Encaminhar conteúdo digitalizado</string>
|
||||
<string name="send_scan_active_summary">Ative para encaminhar conteúdo digitalizado à URL definida</string>
|
||||
<string name="send_scan_url">URL à qual encaminhar</string>
|
||||
<string name="send_scan_type">Tipo de solicitação</string>
|
||||
<string name="send_type_get_add_content">GET e apenas adicionar o conteúdo</string>
|
||||
<string name="send_type_get_query_string">GET com sequência completa da consulta</string>
|
||||
<string name="send_type_get_add_content">GET e somente adicionar um conteúdo</string>
|
||||
<string name="send_type_get_query_string">GET com sequência completa de consulta</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Abrir num navegador externo</string>
|
||||
<string name="send_type_external_browser">Abrir em navegador externo</string>
|
||||
<string name="test_url">Testar a URL</string>
|
||||
<string name="really_remove_scan">Realmente quer remover este escaneamento?</string>
|
||||
<string name="really_remove_all_scans">Realmente quer remover todos os escaneamentos?</string>
|
||||
<string name="really_remove_selected_scans">Realmente remover escaneamentos selecionados?</string>
|
||||
<string name="really_remove_scan">Deseja remover esta digitalização?</string>
|
||||
<string name="really_remove_all_scans">Deseja remover todas as digitalizações?</string>
|
||||
<string name="really_remove_selected_scans">Deseja remover digitalizações selecionados?</string>
|
||||
<string name="clear_history">Limpar histórico</string>
|
||||
<string name="copy_scan">Copiar digitalização</string>
|
||||
<string name="edit_scan">Editar identificação</string>
|
||||
<string name="remove_scan">Remover digitalização</string>
|
||||
<string name="enter_name">Digite nome para identificar a digitalização</string>
|
||||
<string name="enter_name">Digite nome para identificar esta digitalização</string>
|
||||
<string name="enter_name_hint">Nome da digitalização</string>
|
||||
<string name="no_barcode_found">Nenhum código encontrado</string>
|
||||
<string name="pick_list_separator">Como separar itens da lista?</string>
|
||||
<string name="separator_line_break">Quebra de linha</string>
|
||||
<string name="separator_ruler">Régua</string>
|
||||
<string name="save_as_file_name">Salvar em Downloads?</string>
|
||||
<string name="save_as_file_name">Salvar para Downloads?</string>
|
||||
<string name="file_name">Nome do arquivo</string>
|
||||
<string name="error_saving_file">Não foi possível salvar o arquivo</string>
|
||||
<string name="error_saving_file">Não foi possível salvar este arquivo</string>
|
||||
<string name="error_file_exists">Arquivo já existe</string>
|
||||
<string name="connect_to_wifi">Conectar via WiFi</string>
|
||||
<string name="connect_to_wifi">Conectar a WiFi</string>
|
||||
<string name="wifi_config_failed">Não foi possível configurar WiFi</string>
|
||||
<string name="wifi_added">WiFi adicionado</string>
|
||||
<string name="sms_send">Envie SMS</string>
|
||||
<string name="sms_error">Não foi possível enviar SMS</string>
|
||||
<string name="tel_dial">Disque número</string>
|
||||
<string name="tel_error">Não foi possível discar número</string>
|
||||
<string name="tel_error">Não foi possível discar este número</string>
|
||||
<string name="mail_send">Envie e-mail</string>
|
||||
<string name="mail_error">Não foi possível enviar e-mail</string>
|
||||
<string name="vcard_add">Adicionar para contatos</string>
|
||||
<string name="mail_error">Não foi possível enviar este e-mail</string>
|
||||
<string name="vcard_add">Adicionar aos contatos</string>
|
||||
<string name="vcard_failed">Não foi possível adicionar aos contatos</string>
|
||||
<string name="vevent_add">Adicionar ao calendário</string>
|
||||
<string name="vevent_failed">Não foi possível adicionar ao calendário</string>
|
||||
<string name="otpauth_add">Adicionar 2FA</string>
|
||||
<string name="search_web">Pesquisar na internet</string>
|
||||
<string name="search_scan">Pesquisar em conteúdo já digitalizado</string>
|
||||
<string name="search_web">Buscar na internet</string>
|
||||
<string name="search_scan">Buscar em digitalizações feitas</string>
|
||||
<string name="export_to_file">Exportar para arquivo</string>
|
||||
<string name="export_as">Exportar como?</string>
|
||||
<string name="export_as">Exportar em qual formato?</string>
|
||||
<string name="export_csv_comma">Arquivo CSV com vírgulas</string>
|
||||
<string name="export_csv_semicolon">Arquivo CSV com ponto-e-vírgula</string>
|
||||
<string name="export_json">Arquivo JSON</string>
|
||||
<string name="export_database">Base de dados SQLite</string>
|
||||
<string name="saved_in_downloads">Salvo em Downloads</string>
|
||||
<string name="rotate_image_cw">Girar a imagem no sentido horário</string>
|
||||
<string name="toggle_free_rotation">Ativar rotação livre</string>
|
||||
<string name="pick_file">Escolha imagem</string>
|
||||
<string name="pick_code_to_scan">Escolha código para digitalizar</string>
|
||||
<string name="shortcut_decode">Escaneie código</string>
|
||||
@@ -167,4 +183,6 @@
|
||||
<string name="wifi_anonymous_identity">Identidade anônima</string>
|
||||
<string name="wifi_identity">Identidade</string>
|
||||
<string name="wifi_phase2">Método Phase 2</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -17,14 +17,20 @@
|
||||
<string name="error_correction_level_m" formatted="false">Средний (≈15% исправлений)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Квартиль (≈25% исправлений)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Высокий (≈30% исправлений)</string>
|
||||
<string name="issue_number">Номер выпуска</string>
|
||||
<string name="orientation">Ориентация</string>
|
||||
<string name="other_meta_data">Метаданные</string>
|
||||
<string name="pdf417_extra_metadata">Метаданные PDF417</string>
|
||||
<string name="possible_country">Возможная страна изготовления</string>
|
||||
<string name="suggested_price">Предположительная цена</string>
|
||||
<string name="upc_ean_extension">Расширение UPC EAN</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">Цвета</string>
|
||||
<string name="colors_black_on_white">Чёрный на белом</string>
|
||||
<string name="colors_white_on_black">Белый на чёрном</string>
|
||||
<string name="colors_black_on_transparent">Чёрный на прозрачном</string>
|
||||
<string name="colors_white_on_transparent">Белый на прозрачном</string>
|
||||
<string name="sequence_size">Размер последовательности</string>
|
||||
<string name="sequence_index">Индекс последовательности</string>
|
||||
<string name="sequence_id">Идентификатор последовательности</string>
|
||||
<string name="gtin_issue_number">Номер выпуска</string>
|
||||
<string name="gtin_country">Возможная страна изготовления</string>
|
||||
<string name="gtin_price">Предположительная цена</string>
|
||||
<string name="gtin_add_on">Расширение UPC EAN</string>
|
||||
<string name="barcode_version_number">Версия</string>
|
||||
<string name="qr_version_and_modules">%1$s (модули: %2$d)</string>
|
||||
<string name="toggle_flash">Включить вспышку</string>
|
||||
<string name="error_flash">Ошибка при переключении вспышки</string>
|
||||
<string name="share">Поделиться</string>
|
||||
@@ -68,15 +74,24 @@
|
||||
<string name="show_crop_handle_summary">Ограничить сканирование изменяемой областью.</string>
|
||||
<string name="barcode_formats">Форматы штрих-кодов</string>
|
||||
<string name="zoom_by_swiping">Масштабировать жестом вверх/вниз</string>
|
||||
<string name="zoom_by_swiping_summary">Проведите пальцем вверх или вниз для управления масштабированием камеры.</string>
|
||||
<string name="zoom_by_swiping_summary">Жест пальцем вверх или вниз для управления масштабированием камеры.</string>
|
||||
<string name="auto_rotate">Распознавать 1D штрих-коды вертикально</string>
|
||||
<string name="auto_rotate_summary">Автоматически поворачивать камеру для распознавания вертикальных 1D штрих-кодов. В зависимости от устройства, это может повлиять на производительность.</string>
|
||||
<string name="try_harder">Приоритет точности считывания</string>
|
||||
<string name="try_harder_summary">Включите эту настройку для штрих-кодов, которые очень сложно прочитать. Влияет на производительность.</string>
|
||||
<string name="try_harder_summary">Включайте для сложно распознаваемых штрих-кодов. Влияет на производительность.</string>
|
||||
<string name="show_toast_in_bulk_mode">Показывать данные в непрерывном режиме</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Кратко показывать считанные данные в режиме непрерывного сканирования.</string>
|
||||
<string name="vibrate">Вибрация при обнаружении</string>
|
||||
<string name="vibrate_summary">Включите эту настройку, если хотите, чтобы устройство вибрировало после распознавания штрих-кода.</string>
|
||||
<string name="vibrate_summary">Если включено, устройство будет вибрировать после распознавания штрих-кода.</string>
|
||||
<string name="beep">Звук при обнаружении</string>
|
||||
<string name="beep_summary">Если включено, устройство издаст звуковой сигнал после распознавания штрих-кода.</string>
|
||||
<string name="beep_tone">Тон звука</string>
|
||||
<string name="tone_cdma_confirm">Подтверждение CDMA</string>
|
||||
<string name="tone_sup_confirm">Подтверждение диспетчерского вызова</string>
|
||||
<string name="tone_sup_radio_ack">Подтверждение приёма по радиоканалу</string>
|
||||
<string name="tone_prop_ack">Положительное подтверждение</string>
|
||||
<string name="tone_prop_beep">Обычный сигнал</string>
|
||||
<string name="tone_prop_beep2">Обычный двойной сигнал</string>
|
||||
<string name="use_history">Сохранять историю сканирования</string>
|
||||
<string name="use_history_summary">Сохранять распознанные штрих-коды на устройстве.</string>
|
||||
<string name="ignore_consecutive_duplicates">Не хранить дубликаты</string>
|
||||
@@ -87,17 +102,17 @@
|
||||
<string name="copy_immediately_summary">Автоматически копировать содержимое считанного штрих-кода в буфер обмена. Имейте в виду, что другие приложения могут иметь доступ к буферу обмена в фоне.</string>
|
||||
<string name="show_meta_data">Показывать метаданные</string>
|
||||
<string name="show_meta_data_summary">Показывать дополнительную информацию о считанных штрих-кодах.</string>
|
||||
<string name="show_qr_version">Показывать версию QR</string>
|
||||
<string name="show_qr_version_summary">Показывать номер версии QR-кода.</string>
|
||||
<string name="show_hex_dump">Показывать шестнадцатеричный дамп</string>
|
||||
<string name="show_hex_dump_summary">Показывать шестнадцатеричный дамп содержимого считанного штрих-кода.</string>
|
||||
<string name="show_recreation">Показывать восстановленный штрих-код</string>
|
||||
<string name="show_recreation_summary">Показывать штрих-код, восстановленный из считанного содержимого.</string>
|
||||
<string name="close_automatically">Возврат после копирования/обмена</string>
|
||||
<string name="close_automatically_summary">Автоматически возвращаться к экрану сканирования после копирования или передачу через функцию «Поделиться» считанного содержимого.</string>
|
||||
<string name="default_search_engine">Поиск неизвестных данных в</string>
|
||||
<string name="always_ask">Всегда спрашивать</string>
|
||||
<string name="open_with_url">Открывать неизвестные данные по URL</string>
|
||||
<string name="clear_network_suggestions">Очистить сетевые предложения</string>
|
||||
<string name="clear_network_suggestions_summary">Удалить все сетевые предложения, ранее предложенные этим приложением.</string>
|
||||
<string name="clear_network_suggestions">Удалить сетевые предложения</string>
|
||||
<string name="clear_network_suggestions_summary">Удалить все сетевые предложения, ранее добавленные этим приложением.</string>
|
||||
<string name="really_remove_all_networks">Удалить все сетевые предложения?</string>
|
||||
<string name="clear_network_suggestions_success">Сетевые предложения удалены</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Нечего удалять</string>
|
||||
@@ -153,6 +168,7 @@
|
||||
<string name="export_database">База данных SQLite</string>
|
||||
<string name="saved_in_downloads">Сохранено в загрузках</string>
|
||||
<string name="rotate_image_cw">Повернуть изображение по часовой стрелке</string>
|
||||
<string name="toggle_free_rotation">Переключить свободный поворот</string>
|
||||
<string name="pick_file">Открыть файл с изображением</string>
|
||||
<string name="pick_code_to_scan">Выберите штрих-код для сканирования</string>
|
||||
<string name="shortcut_decode">Сканировать штрих-код</string>
|
||||
@@ -169,4 +185,6 @@
|
||||
<string name="wifi_anonymous_identity">Аноним</string>
|
||||
<string name="wifi_identity">Пользователь</string>
|
||||
<string name="wifi_phase2">Двухэтапный метод</string>
|
||||
<string name="network_suggestions">Сетевые предложения</string>
|
||||
<string name="remove_suggestion">Удалить предложение</string>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<resources>
|
||||
<string-array name="search_engines_names">
|
||||
<item>@string/always_ask</item>
|
||||
<item>Google</item>
|
||||
<item>DuckDuckGo</item>
|
||||
<item>Qwant</item>
|
||||
<item>Bing</item>
|
||||
<item>Yandex</item>
|
||||
<item>ebay</item>
|
||||
<item>Amazon</item>
|
||||
<item>OpenFoodFacts.org</item>
|
||||
<item>OpenBeautyFacts.org</item>
|
||||
<item>OpenPetFoodFacts.org</item>
|
||||
<item>Barcode Lookup</item>
|
||||
</string-array>
|
||||
<string-array name="search_engines_values">
|
||||
<item></item>
|
||||
<item>https://www.google.com.tr/search?q=</item>
|
||||
<item>https://duckduckgo.com/?q=</item>
|
||||
<item>https://www.qwant.com/?q=</item>
|
||||
<item>https://bing.com/?q=</item>
|
||||
<item>https://yandex.com.tr/search/?text=</item>
|
||||
<item>https://www.ebay.com/sch/i.html?_nkw=</item>
|
||||
<item>https://www.amazon.com.tr/s?k=</item>
|
||||
<item>https://world.openfoodfacts.org/cgi/search.pl?search_terms=</item>
|
||||
<item>https://world.openbeautyfacts.org/cgi/search.pl?search_terms=</item>
|
||||
<item>https://world.openpetfoodfacts.org/cgi/search.pl?search_terms=</item>
|
||||
<item>https://www.barcodelookup.com/</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -15,16 +15,22 @@
|
||||
<string name="error_correction_level_m" formatted="false">Orta (~%15 düzeltim)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Dörtte Bir (~%25 düzeltim)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Yüksek (~%30 düzeltim)</string>
|
||||
<string name="issue_number">Basım sayısı</string>
|
||||
<string name="orientation">Yönelim</string>
|
||||
<string name="other_meta_data">Üst veri</string>
|
||||
<string name="pdf417_extra_metadata">PDF417 üst verisi</string>
|
||||
<string name="possible_country">Olası üretim yeri</string>
|
||||
<string name="suggested_price">Önerilen fiyat</string>
|
||||
<string name="upc_ean_extension">UPC EAN eklentisi</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">Ön ve arka plan</string>
|
||||
<string name="colors_black_on_white">Beyaz üzerine siyah</string>
|
||||
<string name="colors_white_on_black">Siyah üzerine beyaz</string>
|
||||
<string name="colors_black_on_transparent">Şeffaf üzerine siyah</string>
|
||||
<string name="colors_white_on_transparent">Şeffaf üzerine beyaz</string>
|
||||
<string name="sequence_size">Dizi boyutu</string>
|
||||
<string name="sequence_index">Dizi indeksi</string>
|
||||
<string name="sequence_id">Dizi kimliği</string>
|
||||
<string name="gtin_issue_number">Basım sayısı</string>
|
||||
<string name="gtin_country">Olası üretim yeri</string>
|
||||
<string name="gtin_price">Önerilen fiyat</string>
|
||||
<string name="gtin_add_on">UPC EAN eklentisi</string>
|
||||
<string name="barcode_version_number">Sürüm</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modül)</string>
|
||||
<string name="toggle_flash">Flaşı aç</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="error_flash">Flaş açılırken hata oluştu</string>
|
||||
<string name="share">Paylaş</string>
|
||||
<string name="share_as">Şöyle paylaş:</string>
|
||||
<string name="copy_to_clipboard">Panoya kopyala</string>
|
||||
@@ -47,9 +53,9 @@
|
||||
<string name="bulk_mode">Sürekli tara</string>
|
||||
<string name="bulk_mode_summary">Her zaman sürekli taramaya başla.</string>
|
||||
<string name="bulk_mode_delay">Sürekli taramalar arasındaki gecikme</string>
|
||||
<string name="restrict_format">Restrict format</string>
|
||||
<string name="remove_restriction">Remove restriction</string>
|
||||
<string name="scan_format">Scan %s</string>
|
||||
<string name="restrict_format">Biçimi kısıtla</string>
|
||||
<string name="remove_restriction">Kısıtlamayı kaldır</string>
|
||||
<string name="scan_format">%s tara</string>
|
||||
<string name="quarter_second">Çeyrek saniye</string>
|
||||
<string name="half_second">Yarım saniye</string>
|
||||
<string name="a_second">Bir saniye</string>
|
||||
@@ -75,6 +81,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">Sürekli tarama yaparken taranan verileri kısaca göster.</string>
|
||||
<string name="vibrate">Tanıyınca titre</string>
|
||||
<string name="vibrate_summary">Kod tanındığında aygıtınızın titremesini istiyorsanız bunu etkinleştirin.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Tarama geçmişini kaydet</string>
|
||||
<string name="use_history_summary">Tanınan kodları aygıtınızda saklayın.</string>
|
||||
<string name="ignore_consecutive_duplicates">Yinelemeleri göz ardı et</string>
|
||||
@@ -85,10 +100,10 @@
|
||||
<string name="copy_immediately_summary">Taranan içerikleri kendiliğinden panoya kopyala. Unutmayın ki, diğer uygulamalar arka planda panonuzu gözetleyebilir.</string>
|
||||
<string name="show_meta_data">Üst veriyi göster</string>
|
||||
<string name="show_meta_data_summary">Taranan barkod ile ilgili ek veriyi göster</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">Hex yığınını göster</string>
|
||||
<string name="show_hex_dump_summary">Taranan içeriklerin hex yığınını göster.</string>
|
||||
<string name="show_recreation">Yeniden oluşturulan barkodu göster</string>
|
||||
<string name="show_recreation_summary">Mümkünse okunan içerikten barkodu yeniden oluştur ve göster.</string>
|
||||
<string name="close_automatically">Kopyala/Paylaş\'tan sonra geri dön</string>
|
||||
<string name="close_automatically_summary">Okunan içeriği kopyaladıktan veya paylaştıktan sonra kendiliğinden tarama ekranına dön.</string>
|
||||
<string name="default_search_engine">Bilinmeyen verileri şurada aç</string>
|
||||
@@ -100,8 +115,8 @@
|
||||
<string name="clear_network_suggestions_success">Ağ önerileri temizlendi</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Kaldırılacak bir şey yok</string>
|
||||
<string name="send_category">Yönlendirme</string>
|
||||
<string name="send_scan_active">Forward scans</string>
|
||||
<string name="send_scan_active_summary">Enable to forward scans to a the given URL</string>
|
||||
<string name="send_scan_active">Taramaları gönder</string>
|
||||
<string name="send_scan_active_summary">Taramaları belirtilen URL\'ye göndermeyi etkinleştir</string>
|
||||
<string name="send_scan_url">Her taramayı URL\'ye gönder</string>
|
||||
<string name="send_scan_type">Her tarama için isteğin türü</string>
|
||||
<string name="send_type_get_add_content">GET ve basitçe içeriği ekle</string>
|
||||
@@ -151,6 +166,7 @@
|
||||
<string name="export_database">SQLite veri tabanı olarak dışa aktar</string>
|
||||
<string name="saved_in_downloads">İndirilenlere kaydedildi</string>
|
||||
<string name="rotate_image_cw">Görüntüyü saat yönünde döndür</string>
|
||||
<string name="toggle_free_rotation">Serbest dönüşü değiştir</string>
|
||||
<string name="pick_file">Görüntü dosyası seç</string>
|
||||
<string name="pick_code_to_scan">Taranacak kod seç</string>
|
||||
<string name="shortcut_decode">Barkod tara</string>
|
||||
@@ -167,4 +183,6 @@
|
||||
<string name="wifi_anonymous_identity">Anonim kimlik</string>
|
||||
<string name="wifi_identity">Kimlik</string>
|
||||
<string name="wifi_phase2">2. aşama yöntemi</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -16,14 +16,20 @@
|
||||
<string name="error_correction_level_m" formatted="false">Середній (~15% виправлення)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Квартиль (~25% виправлення)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Високий (~30% виправлення)</string>
|
||||
<string name="issue_number">Номер випуску</string>
|
||||
<string name="orientation">Орієнтація</string>
|
||||
<string name="other_meta_data">Метадані</string>
|
||||
<string name="pdf417_extra_metadata">Метадані PDF417</string>
|
||||
<string name="possible_country">Можлива країна-виробник</string>
|
||||
<string name="suggested_price">Рекомендована ціна</string>
|
||||
<string name="upc_ean_extension">Розширення UPC EAN</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">Номер випуску</string>
|
||||
<string name="gtin_country">Можлива країна-виробник</string>
|
||||
<string name="gtin_price">Рекомендована ціна</string>
|
||||
<string name="gtin_add_on">Розширення UPC EAN</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">Увімкнути спалах</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="share">Поділитися</string>
|
||||
@@ -76,6 +82,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">Коротко показати відскановані дані під час безперервного сканування.</string>
|
||||
<string name="vibrate">Вібрувати при виявленні</string>
|
||||
<string name="vibrate_summary">Увімкніть це, якщо хочете, щоб пристрій вібрував, коли код розпізнано.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Зберігати історію сканування</string>
|
||||
<string name="use_history_summary">Збережіть розпізнані коди на своєму пристрої.</string>
|
||||
<string name="ignore_consecutive_duplicates">Ігнорувати дублікати</string>
|
||||
@@ -86,10 +101,10 @@
|
||||
<string name="copy_immediately_summary">Автоматично копіювати відсканований вміст у буфер обміну. Зверніть увагу, що інші програми можуть стежити за буфером обміну в фоновому режимі.</string>
|
||||
<string name="show_meta_data">Показувати метадані</string>
|
||||
<string name="show_meta_data_summary">Показувати додаткові дані про відскановані штрих-коди.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">Показувати шістнадцятковий дамп</string>
|
||||
<string name="show_hex_dump_summary">Показувати шістнадцятковий дамп відсканованого вмісту.</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">Повернутися після копіювання/поширення</string>
|
||||
<string name="close_automatically_summary">Автоматично повернутися на екран сканування після копіювання або поширення прочитаного вмісту.</string>
|
||||
<string name="default_search_engine">Відкривати невідомі дані в</string>
|
||||
@@ -152,6 +167,7 @@
|
||||
<string name="export_database">Експортувати базу даних SQLite</string>
|
||||
<string name="saved_in_downloads">Збережено в Завантаженнях</string>
|
||||
<string name="rotate_image_cw">Повернути зображення за годинниковою стрілкою</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">Вибрати файл зображення</string>
|
||||
<string name="pick_code_to_scan">Вибрати код для сканування</string>
|
||||
<string name="shortcut_decode">Сканувати штрих-код</string>
|
||||
@@ -168,4 +184,6 @@
|
||||
<string name="wifi_anonymous_identity">Анонімна особа</string>
|
||||
<string name="wifi_identity">Користувач</string>
|
||||
<string name="wifi_phase2">Phase 2 метод</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -14,14 +14,20 @@
|
||||
<string name="error_correction_level_m" formatted="false">Trung bình (sửa ~15%)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Một phần tư (sửa ~25%)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Cao (sửa ~30%)</string>
|
||||
<string name="issue_number">Số</string>
|
||||
<string name="orientation">Hướng</string>
|
||||
<string name="other_meta_data">Dữ liệu</string>
|
||||
<string name="pdf417_extra_metadata">Dữ liệu PDF417</string>
|
||||
<string name="possible_country">Có thể được sản xuất ở nước</string>
|
||||
<string name="suggested_price">Giá được gợi ý</string>
|
||||
<string name="upc_ean_extension">Phần mở rộng UPC EAN</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">Fore and background</string>
|
||||
<string name="colors_black_on_white">Black on white</string>
|
||||
<string name="colors_white_on_black">White on black</string>
|
||||
<string name="colors_black_on_transparent">Black on transparent</string>
|
||||
<string name="colors_white_on_transparent">White on transparent</string>
|
||||
<string name="sequence_size">Sequence size</string>
|
||||
<string name="sequence_index">Sequence index</string>
|
||||
<string name="sequence_id">Sequence ID</string>
|
||||
<string name="gtin_issue_number">Số</string>
|
||||
<string name="gtin_country">Có thể được sản xuất ở nước</string>
|
||||
<string name="gtin_price">Giá được gợi ý</string>
|
||||
<string name="gtin_add_on">Phần mở rộng UPC EAN</string>
|
||||
<string name="barcode_version_number">Version</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">Bật/tắt đèn</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="share">Chia sẻ</string>
|
||||
@@ -74,6 +80,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">Hiện nhanh dữ liệu trong khi quét liên tục.</string>
|
||||
<string name="vibrate">Rung khi xác định được mã</string>
|
||||
<string name="vibrate_summary">Kích hoạt nếu bạn muốn máy của bạn rung khi nhận dạng được mã.</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">Lưu lịch sử quét</string>
|
||||
<string name="use_history_summary">Lưu mã đã nhận dạng được trên máy của bạn.</string>
|
||||
<string name="ignore_consecutive_duplicates">Bỏ qua trùng lặp</string>
|
||||
@@ -84,10 +99,10 @@
|
||||
<string name="copy_immediately_summary">Tự động sao chép kết quả. Lưu ý: ứng dụng khác có thể xem nội dung bạn đã sao chép.</string>
|
||||
<string name="show_meta_data">Hiện dữ liệu</string>
|
||||
<string name="show_meta_data_summary">Hiện thêm thông tin về mã vạch quét được.</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">Hiện mã thập lục phân</string>
|
||||
<string name="show_hex_dump_summary">Hiện mã thập lục phân từ mã quét được.</string>
|
||||
<string name="show_recreation">Show recreated barcode</string>
|
||||
<string name="show_recreation_summary">Recreate and show barcode from read content if possible.</string>
|
||||
<string name="close_automatically">Quay lại sau khi Sao chép/Chia sẻ</string>
|
||||
<string name="close_automatically_summary">Tự động quay trở về màn hình quét sao khi sao chép hoặc chia sẻ nội dung đọc được.</string>
|
||||
<string name="default_search_engine">Mở dữ liệu không xác định bằng</string>
|
||||
@@ -150,6 +165,7 @@
|
||||
<string name="export_database">Cơ sở dữ liệu SQLite</string>
|
||||
<string name="saved_in_downloads">Lưu vào Downloads</string>
|
||||
<string name="rotate_image_cw">Quay ảnh theo chiều kim đồng hồ</string>
|
||||
<string name="toggle_free_rotation">Toggle free rotation</string>
|
||||
<string name="pick_file">Chọn tệp ảnh</string>
|
||||
<string name="pick_code_to_scan">Chọn mã để quét</string>
|
||||
<string name="shortcut_decode">Quét mã vạch</string>
|
||||
@@ -166,4 +182,6 @@
|
||||
<string name="wifi_anonymous_identity">Anonymous identity</string>
|
||||
<string name="wifi_identity">Identity</string>
|
||||
<string name="wifi_phase2">Phase 2 method</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -10,18 +10,24 @@
|
||||
<item quantity="other">%2$d 字符, %1$s</item>
|
||||
</plurals>
|
||||
<string name="error_correction_level">纠错级别</string>
|
||||
<string name="error_correction_level_l" formatted="false">Low (~7% 准确度)</string>
|
||||
<string name="error_correction_level_m" formatted="false">Medium (~15% 准确度)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartile (~25% 准确度)</string>
|
||||
<string name="error_correction_level_h" formatted="false">High (~30% 准确度)</string>
|
||||
<string name="issue_number">发行编号</string>
|
||||
<string name="orientation">方向</string>
|
||||
<string name="other_meta_data">元数据</string>
|
||||
<string name="pdf417_extra_metadata">PDF417 元数据</string>
|
||||
<string name="possible_country">可能产地</string>
|
||||
<string name="suggested_price">建议价格</string>
|
||||
<string name="upc_ean_extension">UPC EAN 扩展</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="error_correction_level_l" formatted="false">低 (~7% 准确度)</string>
|
||||
<string name="error_correction_level_m" formatted="false">中 (~15% 准确度)</string>
|
||||
<string name="error_correction_level_q" formatted="false">较高 (~25% 准确度)</string>
|
||||
<string name="error_correction_level_h" formatted="false">高 (~30% 准确度)</string>
|
||||
<string name="colors">前景和背景</string>
|
||||
<string name="colors_black_on_white">白底黑字</string>
|
||||
<string name="colors_white_on_black">黑底白字</string>
|
||||
<string name="colors_black_on_transparent">透明底黑字</string>
|
||||
<string name="colors_white_on_transparent">透明底白字</string>
|
||||
<string name="sequence_size">序列大小</string>
|
||||
<string name="sequence_index">序列索引</string>
|
||||
<string name="sequence_id">序列 ID</string>
|
||||
<string name="gtin_issue_number">发行编号</string>
|
||||
<string name="gtin_country">可能产地</string>
|
||||
<string name="gtin_price">建议价格</string>
|
||||
<string name="gtin_add_on">UPC EAN 扩展</string>
|
||||
<string name="barcode_version_number">版本</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">开关闪光灯</string>
|
||||
<string name="error_flash">开关闪光灯出错</string>
|
||||
<string name="share">分享</string>
|
||||
@@ -46,7 +52,7 @@
|
||||
<string name="bulk_mode">连续扫描</string>
|
||||
<string name="bulk_mode_summary">始终开启连续扫描</string>
|
||||
<string name="bulk_mode_delay">连续扫描之间的延迟</string>
|
||||
<string name="restrict_format">受限格式</string>
|
||||
<string name="restrict_format">严格模式(扫描指定编码格式)</string>
|
||||
<string name="remove_restriction">解除限制</string>
|
||||
<string name="scan_format">扫描 %s</string>
|
||||
<string name="quarter_second">四分之一秒</string>
|
||||
@@ -74,6 +80,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">连续扫描时简要显示扫描数据。</string>
|
||||
<string name="vibrate">识别时震动</string>
|
||||
<string name="vibrate_summary">如果你希望在识别到条码后震动设备,请启用该选项。</string>
|
||||
<string name="beep">识别时提示音</string>
|
||||
<string name="beep_summary">如果你希望在识别到条码后发出提示音,请启用该选项。</string>
|
||||
<string name="beep_tone">选择提示音</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">保存扫描历史</string>
|
||||
<string name="use_history_summary">在本地保存扫描历史</string>
|
||||
<string name="ignore_consecutive_duplicates">不保存重复历史</string>
|
||||
@@ -84,10 +99,10 @@
|
||||
<string name="copy_immediately_summary">注意其他 APP 可能会在后台监控剪贴板</string>
|
||||
<string name="show_meta_data">显示元数据</string>
|
||||
<string name="show_meta_data_summary">显示已扫描条码的额外数据</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">显示16进制数据</string>
|
||||
<string name="show_hex_dump_summary">显示已扫描条码的16进制数据</string>
|
||||
<string name="show_recreation">显示重新创建的条码</string>
|
||||
<string name="show_recreation_summary">如果可以,就从读取内容中重新创建并显示条码。</string>
|
||||
<string name="close_automatically">复制/分享后自动返回</string>
|
||||
<string name="close_automatically_summary">复制或分享读取的内容后自动返回扫描主界面。</string>
|
||||
<string name="default_search_engine">打开未知数据方式</string>
|
||||
@@ -149,7 +164,8 @@
|
||||
<string name="export_json">JSON</string>
|
||||
<string name="export_database">导出 SQLite 数据库</string>
|
||||
<string name="saved_in_downloads">已保存到下载目录</string>
|
||||
<string name="rotate_image_cw">旋转图片</string>
|
||||
<string name="rotate_image_cw">顺时针旋转图片</string>
|
||||
<string name="toggle_free_rotation">切换自由旋转</string>
|
||||
<string name="pick_file">选择图片文件</string>
|
||||
<string name="pick_code_to_scan">选择扫描编码</string>
|
||||
<string name="shortcut_decode">扫描条码</string>
|
||||
@@ -166,4 +182,6 @@
|
||||
<string name="wifi_anonymous_identity">匿名身份</string>
|
||||
<string name="wifi_identity">身份</string>
|
||||
<string name="wifi_phase2">阶段 2 方法</string>
|
||||
<string name="network_suggestions">网络建议</string>
|
||||
<string name="remove_suggestion">删除建议</string>
|
||||
</resources>
|
||||
|
||||
@@ -12,18 +12,24 @@
|
||||
<string name="error_correction_level">糾錯等級</string>
|
||||
<string name="error_correction_level_l" formatted="false">低 (~7% 準確度)</string>
|
||||
<string name="error_correction_level_m" formatted="false">中 (~15% 準確度)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartile (~25% 準確度)</string>
|
||||
<string name="error_correction_level_q" formatted="false">較高 (~25% 準確度)</string>
|
||||
<string name="error_correction_level_h" formatted="false">高 (~30% 準確度)</string>
|
||||
<string name="issue_number">發行編號</string>
|
||||
<string name="orientation">方向</string>
|
||||
<string name="other_meta_data">Metadata</string>
|
||||
<string name="pdf417_extra_metadata">PDF417 metadata</string>
|
||||
<string name="possible_country">可能製作國家</string>
|
||||
<string name="suggested_price">建議價格</string>
|
||||
<string name="upc_ean_extension">UPC EAN 擴充</string>
|
||||
<string name="qr_version">QR version</string>
|
||||
<string name="colors">前景和背景</string>
|
||||
<string name="colors_black_on_white">白底黑字</string>
|
||||
<string name="colors_white_on_black">黑底白字</string>
|
||||
<string name="colors_black_on_transparent">透明底黑字</string>
|
||||
<string name="colors_white_on_transparent">透明底白字</string>
|
||||
<string name="sequence_size">序列大小</string>
|
||||
<string name="sequence_index">序列索引</string>
|
||||
<string name="sequence_id">序列 ID</string>
|
||||
<string name="gtin_issue_number">發行編號</string>
|
||||
<string name="gtin_country">可能製作國家</string>
|
||||
<string name="gtin_price">建議價格</string>
|
||||
<string name="gtin_add_on">UPC EAN 擴充</string>
|
||||
<string name="barcode_version_number">版本</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">開關閃光燈</string>
|
||||
<string name="error_flash">Error toggling flash</string>
|
||||
<string name="error_flash">開關閃光燈時發生錯誤</string>
|
||||
<string name="share">分享</string>
|
||||
<string name="share_as">以何種方式分享?</string>
|
||||
<string name="copy_to_clipboard">複製到剪貼簿</string>
|
||||
@@ -46,9 +52,9 @@
|
||||
<string name="bulk_mode">連續掃描</string>
|
||||
<string name="bulk_mode_summary">始終開啟連續掃描。</string>
|
||||
<string name="bulk_mode_delay">連續掃描間的延遲</string>
|
||||
<string name="restrict_format">Restrict format</string>
|
||||
<string name="remove_restriction">Remove restriction</string>
|
||||
<string name="scan_format">Scan %s</string>
|
||||
<string name="restrict_format">限制格式</string>
|
||||
<string name="remove_restriction">刪除限制</string>
|
||||
<string name="scan_format">掃描 %s</string>
|
||||
<string name="quarter_second">四分之一秒</string>
|
||||
<string name="half_second">半秒</string>
|
||||
<string name="a_second">一秒</string>
|
||||
@@ -58,7 +64,7 @@
|
||||
<string name="preferences">偏好設定</string>
|
||||
<string name="scan_category">掃描</string>
|
||||
<string name="content_category">內容</string>
|
||||
<string name="locale_category">語言</string>
|
||||
<string name="locale_category">語言</string>
|
||||
<string name="custom_locale">設定語言</string>
|
||||
<string name="follow_system_settings">跟隨系統設定</string>
|
||||
<string name="show_crop_handle">顯示裁切範圍選擇器</string>
|
||||
@@ -74,6 +80,15 @@
|
||||
<string name="show_toast_in_bulk_mode_summary">連續掃描時簡要顯示掃描資料。</string>
|
||||
<string name="vibrate">振動提示</string>
|
||||
<string name="vibrate_summary">識別條碼時振動提示。</string>
|
||||
<string name="beep">Beep on detection</string>
|
||||
<string name="beep_summary">Enable this if you want your device to beep when a code is recognized.</string>
|
||||
<string name="beep_tone">Beep tone</string>
|
||||
<string name="tone_cdma_confirm">CDMA confirm</string>
|
||||
<string name="tone_sup_confirm">Call supervisory confirm</string>
|
||||
<string name="tone_sup_radio_ack">Call supervisory radio path acknowledgment</string>
|
||||
<string name="tone_prop_ack">Positive acknowledgment</string>
|
||||
<string name="tone_prop_beep">General beep</string>
|
||||
<string name="tone_prop_beep2">General double beep</string>
|
||||
<string name="use_history">儲存掃描記錄</string>
|
||||
<string name="use_history_summary">在本機儲存掃描記錄。</string>
|
||||
<string name="ignore_consecutive_duplicates">不儲存重複歷史記錄</string>
|
||||
@@ -84,10 +99,10 @@
|
||||
<string name="copy_immediately_summary">自動將掃描的內容複製到剪貼簿。請注意,其他 App 可能會在背景監控剪貼簿。</string>
|
||||
<string name="show_meta_data">顯示 Metadata</string>
|
||||
<string name="show_meta_data_summary">顯示已掃描條碼的額外資訊。</string>
|
||||
<string name="show_qr_version">Show QR version</string>
|
||||
<string name="show_qr_version_summary">Show QR version number.</string>
|
||||
<string name="show_hex_dump">顯示 Hex dump</string>
|
||||
<string name="show_hex_dump_summary">顯示已掃描條碼的 Hex dump。</string>
|
||||
<string name="show_recreation">顯示重新創建的條碼</string>
|
||||
<string name="show_recreation_summary">如果可以,就從讀取內容中重新創建並顯示條碼。</string>
|
||||
<string name="close_automatically">複製/分享後自動返回</string>
|
||||
<string name="close_automatically_summary">複製或分享讀取的內容後自動返回掃描主要界面。</string>
|
||||
<string name="default_search_engine">使用何種方式開啟未知資料</string>
|
||||
@@ -99,15 +114,15 @@
|
||||
<string name="clear_network_suggestions_success">網路建議已清除</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">沒有什麼可以移除的</string>
|
||||
<string name="send_category">轉發</string>
|
||||
<string name="send_scan_active">Forward scans</string>
|
||||
<string name="send_scan_active_summary">Enable to forward scans to a the given URL</string>
|
||||
<string name="send_scan_active">轉發掃描</string>
|
||||
<string name="send_scan_active_summary">啟用以將掃描轉發到給定的 URL</string>
|
||||
<string name="send_scan_url">將每個掃描結果傳送到 URL</string>
|
||||
<string name="send_scan_type">每次掃描的請求類型</string>
|
||||
<string name="send_type_get_add_content">GET 簡單附加資料</string>
|
||||
<string name="send_type_get_query_string">GET 完整查詢資料</string>
|
||||
<string name="send_type_post_form">POST application/x-www-form-urlencoded</string>
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Open in external browser</string>
|
||||
<string name="send_type_external_browser">在外部瀏覽器中開啟</string>
|
||||
<string name="test_url">測試 URL</string>
|
||||
<string name="really_remove_scan">確定刪除記錄?</string>
|
||||
<string name="really_remove_all_scans">確定刪除全部掃描記錄?</string>
|
||||
@@ -147,9 +162,10 @@
|
||||
<string name="export_csv_comma">逗號分隔的 CSV 檔案</string>
|
||||
<string name="export_csv_semicolon">分號分隔的 CSV 檔案</string>
|
||||
<string name="export_json">JSON 檔案</string>
|
||||
<string name="export_database">SQLite 資料庫</string>
|
||||
<string name="export_database">導出 SQLite 資料庫</string>
|
||||
<string name="saved_in_downloads">已儲存到下載目錄</string>
|
||||
<string name="rotate_image_cw">順時針旋轉圖片</string>
|
||||
<string name="toggle_free_rotation">切換自由旋轉</string>
|
||||
<string name="pick_file">選擇圖片檔案</string>
|
||||
<string name="pick_code_to_scan">選擇要掃描的條碼</string>
|
||||
<string name="shortcut_decode">掃描條碼</string>
|
||||
@@ -166,4 +182,6 @@
|
||||
<string name="wifi_anonymous_identity">匿名身分</string>
|
||||
<string name="wifi_identity">身分</string>
|
||||
<string name="wifi_phase2">Phase 2 method</string>
|
||||
<string name="network_suggestions">Network suggestions</string>
|
||||
<string name="remove_suggestion">Remove suggestion</string>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<resources>
|
||||
<string-array name="colors">
|
||||
<item>@string/colors_black_on_white</item>
|
||||
<item>@string/colors_white_on_black</item>
|
||||
<item>@string/colors_black_on_transparent</item>
|
||||
<item>@string/colors_white_on_transparent</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -5,6 +5,8 @@
|
||||
<item>CODE 39</item>
|
||||
<item>CODE 93</item>
|
||||
<item>CODE 128</item>
|
||||
<item>DATA BAR</item>
|
||||
<item>DATA BAR EXPANDED</item>
|
||||
<item>DATA MATRIX</item>
|
||||
<item>EAN 8</item>
|
||||
<item>EAN 13</item>
|
||||
@@ -12,11 +14,9 @@
|
||||
<item>MAXICODE</item>
|
||||
<item>PDF 417</item>
|
||||
<item>QR CODE</item>
|
||||
<item>RSS 14</item>
|
||||
<item>RSS EXPANDED</item>
|
||||
<item>MICRO QR CODE</item>
|
||||
<item>UPC A</item>
|
||||
<item>UPC E</item>
|
||||
<item>UPC EAN EXTENSION</item>
|
||||
</string-array>
|
||||
<string-array name="barcode_formats_values">
|
||||
<item>AZTEC</item>
|
||||
@@ -24,6 +24,8 @@
|
||||
<item>CODE_39</item>
|
||||
<item>CODE_93</item>
|
||||
<item>CODE_128</item>
|
||||
<item>DATA_BAR</item>
|
||||
<item>DATA_BAR_EXPANDED</item>
|
||||
<item>DATA_MATRIX</item>
|
||||
<item>EAN_8</item>
|
||||
<item>EAN_13</item>
|
||||
@@ -31,10 +33,8 @@
|
||||
<item>MAXICODE</item>
|
||||
<item>PDF_417</item>
|
||||
<item>QR_CODE</item>
|
||||
<item>RSS_14</item>
|
||||
<item>RSS_EXPANDED</item>
|
||||
<item>MICRO_QR_CODE</item>
|
||||
<item>UPC_A</item>
|
||||
<item>UPC_E</item>
|
||||
<item>UPC_EAN_EXTENSION</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user