Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
180339269f | ||
|
|
49af17cba8 | ||
|
|
a03a187d2d | ||
|
|
84806e70d7 | ||
|
|
058de5a141 | ||
|
|
d330fbd195 | ||
|
|
f5bc6f664f | ||
|
|
464279807c | ||
|
|
f7e5ef473a | ||
|
|
ff733ef59e | ||
|
|
35b110a472 | ||
|
|
58eabf4754 | ||
|
|
1f273a48a5 | ||
|
|
785a64725d | ||
|
|
7a42e1de73 | ||
|
|
9856ab7b6b | ||
|
|
746ff143d8 | ||
|
|
b0d4d94973 | ||
|
|
c604ad5ef2 | ||
|
|
91c2b324ac | ||
|
|
df59fd7446 | ||
|
|
449fd1f26c | ||
|
|
72d839c6e2 | ||
|
|
ab8c993a81 | ||
|
|
5f5bd913d6 | ||
|
|
92fe4dd55f | ||
|
|
dab95176f0 | ||
|
|
650503ba70 | ||
|
|
61078f214e | ||
|
|
a4b639edfe | ||
|
|
f37878dbb8 | ||
|
|
10fde7c3d6 | ||
|
|
a098fcb48c | ||
|
|
f162977640 | ||
|
|
66cab58d7b | ||
|
|
e99e2d7dcc | ||
|
|
9045a27a5d | ||
|
|
9e1208c72b | ||
|
|
90410f232a | ||
|
|
6769fa7e37 | ||
|
|
72444f5081 | ||
|
|
9a3ca4ffa3 | ||
|
|
f572923720 | ||
|
|
4971f58f44 | ||
|
|
0bf24080a8 | ||
|
|
04a21f71ef | ||
|
|
e22a215863 | ||
|
|
881829e7b2 | ||
|
|
2ad261f3b6 | ||
|
|
e0fdda78b3 | ||
|
|
9c3710c56d | ||
|
|
ddcab46d47 | ||
|
|
076da26075 | ||
|
|
dbc37714f9 | ||
|
|
50e57eaf25 | ||
|
|
340f7f9d1d | ||
|
|
a42bd793bb | ||
|
|
6e531f5395 | ||
|
|
79b3fddcf8 | ||
|
|
09f3c8f193 | ||
|
|
5f82f216fd | ||
|
|
8424e3ea31 | ||
|
|
15ce34aa92 | ||
|
|
8dfc1e37c0 | ||
|
|
a0d3b7ba87 | ||
|
|
a234dc3a9a | ||
|
|
a00f70e25b | ||
|
|
ef555c0153 | ||
|
|
9fffb53f73 | ||
|
|
b82c6200c0 | ||
|
|
5bb347c392 | ||
|
|
f8033614fa | ||
|
|
46cc2fb1a1 | ||
|
|
f2ac1e77bb | ||
|
|
89c84880c6 | ||
|
|
352fe07850 | ||
|
|
00abe33314 | ||
|
|
142df25d7e | ||
|
|
021d775835 | ||
|
|
06df0c4d64 | ||
|
|
32c70af812 | ||
|
|
7cc1777e7a | ||
|
|
23e0564594 | ||
|
|
0447384bea | ||
|
|
b4d66e28e2 | ||
|
|
ee1c56d99f | ||
|
|
33ef78443e | ||
|
|
9f1e34b06d | ||
|
|
24766f55d4 | ||
|
|
0ae7d080e3 | ||
|
|
7d8c6016db | ||
|
|
3d923035e3 | ||
|
|
a489f3aa22 | ||
|
|
7dfd7a1303 | ||
|
|
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 |
@@ -1,5 +1,96 @@
|
||||
# Change Log
|
||||
|
||||
## 1.61.2
|
||||
* Fix quick settings tile for Android 14
|
||||
* Fix Xiaomi MIUI lockscreen barcode shortcut
|
||||
* Update French translation
|
||||
* Update Czech translation
|
||||
* Update Russian translation
|
||||
|
||||
## 1.61.1
|
||||
* Share scanned contents as a file
|
||||
* Recreate binary barcodes too
|
||||
* Add Bulgarian translation and Brave search engine
|
||||
* Update Russian translation
|
||||
* Fix general format restriction from preferences
|
||||
|
||||
## 1.61.0
|
||||
* Support encoding binary data
|
||||
* Add margin parameter for encoding
|
||||
* Add copying binary data as hex dump
|
||||
* Fix parsing TYPE argument in VCARDs
|
||||
* Update Russian translation
|
||||
* Update Brazilian Portuguese translation
|
||||
* Update Ukrainian translation
|
||||
* Update Chinese translation
|
||||
|
||||
## 1.60.3
|
||||
* Fix saving custom language
|
||||
* Update Brazilian Portuguese translation
|
||||
* Update Chinese translation
|
||||
* Update Czech localisation
|
||||
* Update Russian translation
|
||||
* Update Italian language
|
||||
|
||||
## 1.60.2
|
||||
* Expand escape sequences in encoding input
|
||||
* Update Taiwan translation
|
||||
|
||||
## 1.60.1
|
||||
* Support sending scans via bluetooth
|
||||
* Fix resolving error correction level for recreation
|
||||
* Improve asset image compression
|
||||
* Update ZXing C++
|
||||
* Update Italian translation
|
||||
* Update Russian translation
|
||||
|
||||
## 1.59.0
|
||||
* Add setting error correction for AZTEC/PDF417
|
||||
* Fix setting error correction level for QR Codes
|
||||
* Make error beeps follow beep settings too
|
||||
* Don't close the app when cameras is unavailable
|
||||
|
||||
## 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -33,6 +33,11 @@ testurl:
|
||||
-c android.intent.category.BROWSABLE \
|
||||
-d 'http://markusfisch.de/BinaryEye?ret=http%3A%2F%2Fmarkusfisch.de%2F%3Fresult%3D{RESULT}'
|
||||
|
||||
testxiaomi:
|
||||
adb shell am start -a android.intent.action.VIEW \
|
||||
-c android.intent.category.BROWSABLE \
|
||||
-d 'market://details?id=com.xiaomi.scanner'
|
||||
|
||||
install:
|
||||
adb $(TARGET) install -r app/build/outputs/apk/debug/app-debug.apk
|
||||
|
||||
|
||||
@@ -12,11 +12,18 @@ 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.
|
||||
|
||||
### [BLUETOOTH][BLUETOOTH], [BLUETOOTH_ADMIN][BLUETOOTH_ADMIN] and [BLUETOOTH_CONNECT][BLUETOOTH_CONNECT]
|
||||
|
||||
Required to optionally forward scans to a Bluetooth device.
|
||||
|
||||
[BLUETOOTH][BLUETOOTH] and [BLUETOOTH_ADMIN][BLUETOOTH_ADMIN] are required
|
||||
before Android S. [BLUETOOTH_CONNECT][BLUETOOTH_CONNECT] from Android S on.
|
||||
|
||||
### [CAMERA][CAMERA]
|
||||
|
||||
Required to read a barcode from the camera image.
|
||||
@@ -46,15 +53,23 @@ 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
|
||||
[BLUETOOTH]: https://developer.android.com/reference/android/Manifest.permission#BLUETOOTH
|
||||
[BLUETOOTH_ADMIN]: https://developer.android.com/reference/android/Manifest.permission#BLUETOOTH_ADMIN
|
||||
[BLUETOOTH_CONNECT]: https://developer.android.com/reference/android/Manifest.permission#BLUETOOTH_CONNECT
|
||||
[CAMERA]: https://developer.android.com/reference/android/Manifest.permission#CAMERA
|
||||
[INTERNET]: https://developer.android.com/reference/android/Manifest.permission#INTERNET
|
||||
[VIBRATE]: https://developer.android.com/reference/android/Manifest.permission#VIBRATE
|
||||
[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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -4,13 +4,12 @@ apply plugin: 'kotlin-android'
|
||||
android {
|
||||
namespace 'de.markusfisch.android.binaryeye'
|
||||
compileSdkVersion sdk_version
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 9
|
||||
targetSdkVersion sdk_version
|
||||
|
||||
versionCode 106
|
||||
versionName '1.56.0'
|
||||
versionCode 123
|
||||
versionName '1.61.2'
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
@@ -59,12 +58,12 @@ dependencies {
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
|
||||
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.github.markusfisch:CameraView:1.9.1'
|
||||
implementation 'com.github.markusfisch:ScalingImageView:1.4.0'
|
||||
implementation 'com.github.markusfisch:zxing-cpp:v1.4.0.7'
|
||||
implementation 'com.github.markusfisch:CameraView:1.9.2'
|
||||
implementation 'com.github.markusfisch:ScalingImageView:1.4.1'
|
||||
implementation 'com.github.markusfisch:zxing-cpp:v2.1.0.2'
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.2 KiB |
@@ -6,14 +6,18 @@
|
||||
android:xlargeScreens="true"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
|
||||
android:maxSdkVersion="28"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"
|
||||
android:maxSdkVersion="30"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
|
||||
android:maxSdkVersion="30"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<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"/>
|
||||
@@ -68,10 +72,8 @@
|
||||
<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"/>
|
||||
<data android:host="details" android:scheme="market"
|
||||
android:pathSuffix="id=com.xiaomi.scanner"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package de.markusfisch.android.binaryeye.actions.vtype
|
||||
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
|
||||
object VTypeParser {
|
||||
private const val BACKSLASH_R_LEGACY =
|
||||
@@ -39,6 +39,6 @@ data class VTypeProperty(
|
||||
} ?: this.info.firstOrNull()
|
||||
|
||||
companion object {
|
||||
private val typeRegex = """^(?:TYPE=)(.+?)[:;]?.*$""".toRegex(RegexOption.IGNORE_CASE)
|
||||
private val typeRegex = """^TYPE=([A-Z_]+)[:;]?.*$""".toRegex(RegexOption.IGNORE_CASE)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import android.provider.ContactsContract
|
||||
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 java.util.Locale
|
||||
|
||||
object VCardAction : IntentAction() {
|
||||
override val iconResId: Int
|
||||
@@ -45,10 +45,13 @@ object VCardAction : IntentAction() {
|
||||
val (extraPhoneType, extraPhone) = when (index) {
|
||||
0 -> ContactsContract.Intents.Insert.PHONE_TYPE to
|
||||
ContactsContract.Intents.Insert.PHONE
|
||||
|
||||
1 -> ContactsContract.Intents.Insert.SECONDARY_PHONE_TYPE to
|
||||
ContactsContract.Intents.Insert.SECONDARY_PHONE
|
||||
|
||||
2 -> ContactsContract.Intents.Insert.TERTIARY_PHONE_TYPE to
|
||||
ContactsContract.Intents.Insert.TERTIARY_PHONE_TYPE
|
||||
|
||||
else -> return@forEachIndexed
|
||||
}
|
||||
phoneProperty.firstTypeOrFirstInfo?.also {
|
||||
@@ -65,10 +68,13 @@ object VCardAction : IntentAction() {
|
||||
val (extraMailType, extraMail) = when (index) {
|
||||
0 -> ContactsContract.Intents.Insert.EMAIL_TYPE to
|
||||
ContactsContract.Intents.Insert.EMAIL
|
||||
|
||||
1 -> ContactsContract.Intents.Insert.SECONDARY_EMAIL_TYPE to
|
||||
ContactsContract.Intents.Insert.SECONDARY_EMAIL
|
||||
|
||||
2 -> ContactsContract.Intents.Insert.TERTIARY_EMAIL_TYPE to
|
||||
ContactsContract.Intents.Insert.TERTIARY_EMAIL
|
||||
|
||||
else -> return@forEachIndexed
|
||||
}
|
||||
mailProperty.firstTypeOrFirstInfo?.also {
|
||||
@@ -184,7 +190,7 @@ object VCardAction : IntentAction() {
|
||||
}
|
||||
|
||||
private val String.addressType: Int?
|
||||
get() = when (this.toUpperCase(Locale.US)) {
|
||||
get() = when (this.uppercase()) {
|
||||
"HOME" -> ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME
|
||||
"WORK" -> ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK
|
||||
"OTHER" -> ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER
|
||||
|
||||
@@ -7,9 +7,7 @@ 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
|
||||
)
|
||||
"^(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
|
||||
|
||||
@@ -22,10 +22,9 @@ object WifiAction : IAction {
|
||||
context: Context,
|
||||
data: ByteArray
|
||||
) = withContext(Dispatchers.IO) {
|
||||
val wifiConfig = WifiConnector.parse(
|
||||
String(data)
|
||||
) ?: return@withContext
|
||||
val message = WifiConnector.addNetwork(context, wifiConfig)
|
||||
val message = WifiConnector.parse(String(data))?.let {
|
||||
WifiConnector.addNetwork(context, it)
|
||||
} ?: R.string.wifi_config_failed
|
||||
withContext(Dispatchers.Main) {
|
||||
context.toast(message)
|
||||
}
|
||||
|
||||
@@ -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,12 +44,21 @@ object WifiConnector {
|
||||
passwordBlock?.apply {
|
||||
invoke(parsedData.password)
|
||||
}
|
||||
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
// WifiConfiguration is deprecated in Android Q.
|
||||
@Suppress("DEPRECATION")
|
||||
WifiConfiguration().apply(parsedData)
|
||||
} else {
|
||||
WifiNetworkSuggestion.Builder().apply(parsedData)
|
||||
return try {
|
||||
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 {
|
||||
WifiNetworkSuggestion.Builder().apply(parsedData)
|
||||
}
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// Some arguments may be out of range, e.g. SSIDs cannot
|
||||
// be longer than 32 characters in some versions of Android.
|
||||
// See: https://github.com/markusfisch/BinaryEye/issues/402
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,33 +66,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 +90,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 +119,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 +136,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,10 +172,11 @@ object WifiConnector {
|
||||
data: SimpleDataAccessor
|
||||
): WifiNetworkSuggestion.Builder? {
|
||||
try {
|
||||
when (data.securityType) {
|
||||
when (data.securityType.uppercase()) {
|
||||
"WPA", "WPA2" -> {
|
||||
data.password?.let { setWpa2Passphrase(it) }
|
||||
}
|
||||
|
||||
"WPA2-EAP" -> {
|
||||
setWpa2EnterpriseConfig(WifiEnterpriseConfig().apply {
|
||||
identity = data.identity
|
||||
@@ -192,9 +186,11 @@ object WifiConnector {
|
||||
data.phase2Method?.let { phase2Method = it }
|
||||
})
|
||||
}
|
||||
|
||||
"WPA3" -> {
|
||||
data.password?.let { setWpa3Passphrase(it) }
|
||||
}
|
||||
|
||||
"WPA3-EAP" -> {
|
||||
setWpa3EnterpriseConfig(WifiEnterpriseConfig().apply {
|
||||
identity = data.identity
|
||||
@@ -240,8 +236,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
|
||||
@@ -254,6 +250,7 @@ object WifiConnector {
|
||||
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40)
|
||||
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104)
|
||||
}
|
||||
|
||||
"WPA" -> {
|
||||
passwordWithQuotes?.let {
|
||||
preSharedKey = it
|
||||
@@ -270,6 +267,7 @@ object WifiConnector {
|
||||
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
|
||||
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
|
||||
}
|
||||
|
||||
"WPA2-EAP" -> requireSdk(Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
passwordWithQuotes?.let {
|
||||
preSharedKey = it
|
||||
@@ -303,11 +301,32 @@ 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()
|
||||
private val String.unescape: String
|
||||
get() = this.replace(escapedRegex) { escaped ->
|
||||
get() = replace(escapedRegex) { escaped ->
|
||||
escaped.groupValues[1]
|
||||
}
|
||||
|
||||
|
||||
@@ -8,11 +8,8 @@ import android.content.pm.PackageManager
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.Rect
|
||||
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
|
||||
@@ -24,6 +21,7 @@ import android.widget.SeekBar
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.adapter.prettifyFormatName
|
||||
import de.markusfisch.android.binaryeye.app.*
|
||||
import de.markusfisch.android.binaryeye.bluetooth.sendBluetoothAsync
|
||||
import de.markusfisch.android.binaryeye.content.copyToClipboard
|
||||
import de.markusfisch.android.binaryeye.content.execShareIntent
|
||||
import de.markusfisch.android.binaryeye.content.openUrl
|
||||
@@ -33,20 +31,20 @@ 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.net.urlEncode
|
||||
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.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.cameraview.widget.CameraView
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Format
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Binarizer
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.DecodeHints
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Result
|
||||
import java.nio.charset.Charset
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
@@ -55,13 +53,12 @@ class CameraActivity : AppCompatActivity() {
|
||||
private val frameRoi = Rect()
|
||||
private val matrix = Matrix()
|
||||
|
||||
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 formats = setOf<String>()
|
||||
private var formatsToRead = setOf<String>()
|
||||
private var frameMetrics = FrameMetrics()
|
||||
private var decoding = true
|
||||
private var returnResult = false
|
||||
@@ -82,8 +79,7 @@ class CameraActivity : AppCompatActivity() {
|
||||
PERMISSION_CAMERA -> if (grantResults.isNotEmpty() &&
|
||||
grantResults[0] != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
toast(R.string.no_camera_no_fun)
|
||||
finish()
|
||||
toast(R.string.camera_error)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,8 +114,6 @@ class CameraActivity : AppCompatActivity() {
|
||||
// custom locale.
|
||||
setTitle(R.string.scan_code)
|
||||
|
||||
vibrator = getVibrator()
|
||||
|
||||
initSystemBars(this)
|
||||
setSupportActionBar(findViewById(R.id.toolbar) as Toolbar)
|
||||
|
||||
@@ -144,6 +138,7 @@ class CameraActivity : AppCompatActivity() {
|
||||
fallbackBuffer = null
|
||||
saveZoom()
|
||||
detectorView.saveCropHandlePos()
|
||||
releaseToneGenerators()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@@ -163,7 +158,7 @@ class CameraActivity : AppCompatActivity() {
|
||||
|
||||
private fun updateHints() {
|
||||
val restriction = restrictFormat
|
||||
formats = if (restriction != null) {
|
||||
formatsToRead = if (restriction != null) {
|
||||
title = getString(
|
||||
R.string.scan_format,
|
||||
prettifyFormatName(restriction)
|
||||
@@ -180,6 +175,7 @@ class CameraActivity : AppCompatActivity() {
|
||||
intent?.action == "com.google.zxing.client.android.SCAN" -> {
|
||||
returnResult = true
|
||||
}
|
||||
|
||||
intent?.dataString?.isReturnUrl() == true -> {
|
||||
finishAfterShowingResult = true
|
||||
returnUrlTemplate = intent.data?.getQueryParameter("ret")
|
||||
@@ -248,44 +244,52 @@ class CameraActivity : AppCompatActivity() {
|
||||
createBarcode()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.history -> {
|
||||
startActivity(MainActivity.getHistoryIntent(this))
|
||||
true
|
||||
}
|
||||
|
||||
R.id.pick_file -> {
|
||||
startActivityForResult(
|
||||
Intent.createChooser(
|
||||
Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||
type = "image/*"
|
||||
},
|
||||
getString(R.string.pick_file)
|
||||
getString(R.string.pick_image_file)
|
||||
),
|
||||
PICK_FILE_RESULT_CODE
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.switch_camera -> {
|
||||
switchCamera()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.bulk_mode -> {
|
||||
bulkMode = bulkMode xor true
|
||||
item.isChecked = bulkMode
|
||||
ignoreNext = null
|
||||
true
|
||||
}
|
||||
|
||||
R.id.restrict_format -> {
|
||||
showRestrictionDialog()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.preferences -> {
|
||||
startActivity(MainActivity.getPreferencesIntent(this))
|
||||
true
|
||||
}
|
||||
|
||||
R.id.info -> {
|
||||
openReadme()
|
||||
true
|
||||
}
|
||||
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
@@ -354,6 +358,7 @@ class CameraActivity : AppCompatActivity() {
|
||||
progress = zoomBar.progress
|
||||
return true
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
if (prefs.zoomBySwiping) {
|
||||
v ?: return false
|
||||
@@ -367,6 +372,7 @@ class CameraActivity : AppCompatActivity() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_UP -> {
|
||||
// Stop calling focusTo() as soon as it returns false
|
||||
// to avoid throwing and catching future exceptions.
|
||||
@@ -414,7 +420,6 @@ class CameraActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCameraError() {
|
||||
this@CameraActivity.toast(R.string.camera_error)
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onCameraReady(camera: Camera) {
|
||||
@@ -426,22 +431,39 @@ class CameraActivity : AppCompatActivity() {
|
||||
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,
|
||||
maxNumberOfSymbols = 1
|
||||
)
|
||||
var useLocalAverage = false
|
||||
camera.setPreviewCallback { frameData, _ ->
|
||||
if (decoding) {
|
||||
useLocalAverage = useLocalAverage xor true
|
||||
ZxingCpp.readByteArray(
|
||||
frameData,
|
||||
frameMetrics.width,
|
||||
frameRoi.left, frameRoi.top,
|
||||
frameRoi.width(), frameRoi.height(),
|
||||
frameMetrics.orientation,
|
||||
formats.joinToString(),
|
||||
prefs.tryHarder,
|
||||
prefs.autoRotate,
|
||||
tryInvert = true,
|
||||
tryDownscale = true
|
||||
)?.let { result ->
|
||||
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 { results ->
|
||||
val result = results.first()
|
||||
if (result.text != ignoreNext) {
|
||||
postResult(result.redact())
|
||||
postResult(result)
|
||||
decoding = false
|
||||
}
|
||||
}
|
||||
@@ -561,7 +583,7 @@ class CameraActivity : AppCompatActivity() {
|
||||
detectorView.coordinates
|
||||
)
|
||||
)
|
||||
vibrator.vibrate()
|
||||
scanFeedback()
|
||||
val returnUri = returnUrlTemplate?.let {
|
||||
try {
|
||||
completeUrl(it, result)
|
||||
@@ -577,16 +599,13 @@ class CameraActivity : AppCompatActivity() {
|
||||
setResult(Activity.RESULT_OK, getReturnIntent(result))
|
||||
finish()
|
||||
}
|
||||
|
||||
returnUri != null -> execShareIntent(
|
||||
Intent(Intent.ACTION_VIEW, returnUri)
|
||||
)
|
||||
|
||||
else -> {
|
||||
showResult(
|
||||
this@CameraActivity,
|
||||
result,
|
||||
vibrator,
|
||||
bulkMode
|
||||
)
|
||||
showResult(result, bulkMode)
|
||||
// If this app was invoked via a deep link but without
|
||||
// a return URI, we probably don't want to return to
|
||||
// the camera screen after scanning, but to the caller.
|
||||
@@ -596,7 +615,9 @@ class CameraActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
if (bulkMode) {
|
||||
ignoreNext = result.text
|
||||
if (prefs.ignoreConsecutiveDuplicates) {
|
||||
ignoreNext = result.text
|
||||
}
|
||||
if (prefs.showToastInBulkMode) {
|
||||
toast(result.text)
|
||||
}
|
||||
@@ -617,42 +638,12 @@ class CameraActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
fun Result.redact() = if (
|
||||
format == Format.PDF_417.name &&
|
||||
text.isNotEmpty()
|
||||
) {
|
||||
Result(
|
||||
format,
|
||||
contentType,
|
||||
String(
|
||||
text.toByteArray(Charset.forName("ISO-8859-1")),
|
||||
Charset.forName("UTF-8")
|
||||
),
|
||||
position,
|
||||
orientation,
|
||||
rawBytes,
|
||||
ecLevel,
|
||||
symbologyIdentifier,
|
||||
sequenceSize,
|
||||
sequenceIndex,
|
||||
sequenceId,
|
||||
readerInit,
|
||||
lineCount,
|
||||
versionNumber,
|
||||
gtin
|
||||
)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
|
||||
fun showResult(
|
||||
activity: Activity,
|
||||
fun Activity.showResult(
|
||||
result: Result,
|
||||
vibrator: Vibrator,
|
||||
bulkMode: Boolean = false,
|
||||
) {
|
||||
if (prefs.copyImmediately) {
|
||||
activity.copyToClipboard(result.text)
|
||||
copyToClipboard(result.text)
|
||||
}
|
||||
val scan = result.toScan()
|
||||
if (prefs.useHistory) {
|
||||
@@ -660,7 +651,7 @@ fun showResult(
|
||||
}
|
||||
if (prefs.sendScanActive && prefs.sendScanUrl.isNotEmpty()) {
|
||||
if (prefs.sendScanType == "4") {
|
||||
activity.openUrl(
|
||||
openUrl(
|
||||
prefs.sendScanUrl + scan.content.urlEncode()
|
||||
)
|
||||
return
|
||||
@@ -670,21 +661,42 @@ fun showResult(
|
||||
prefs.sendScanType
|
||||
) { code, body ->
|
||||
if (code == null || code < 200 || code > 299) {
|
||||
vibrator.error()
|
||||
if (!activity.isSilent()) {
|
||||
beepBeepBeep()
|
||||
}
|
||||
errorFeedback()
|
||||
}
|
||||
if (body != null && body.isNotEmpty()) {
|
||||
activity.toast(body)
|
||||
toast(body)
|
||||
} else if (code == null || code > 299) {
|
||||
activity.toast(R.string.background_request_failed)
|
||||
toast(R.string.background_request_failed)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prefs.sendScanBluetooth &&
|
||||
prefs.sendScanBluetoothHost.isNotEmpty() &&
|
||||
hasBluetoothPermission()
|
||||
) {
|
||||
scan.sendBluetoothAsync(
|
||||
prefs.sendScanBluetoothHost
|
||||
) { connected, sent ->
|
||||
toast(
|
||||
when {
|
||||
!connected -> {
|
||||
errorFeedback()
|
||||
R.string.bluetooth_connect_fail
|
||||
}
|
||||
|
||||
!sent -> {
|
||||
errorFeedback()
|
||||
R.string.bluetooth_send_fail
|
||||
}
|
||||
|
||||
else -> R.string.bluetooth_send_success
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
if (!bulkMode) {
|
||||
activity.startActivity(
|
||||
MainActivity.getDecodeIntent(activity, scan)
|
||||
startActivity(
|
||||
MainActivity.getDecodeIntent(this, scan)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -715,19 +727,3 @@ private fun completeUrl(urlTemplate: String, result: Result) = Uri.parse(
|
||||
// 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
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,12 @@ import android.support.v4.app.Fragment
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.Toolbar
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.app.*
|
||||
import de.markusfisch.android.binaryeye.app.PERMISSION_LOCATION
|
||||
import de.markusfisch.android.binaryeye.app.PERMISSION_WRITE
|
||||
import de.markusfisch.android.binaryeye.app.applyLocale
|
||||
import de.markusfisch.android.binaryeye.app.permissionGrantedCallback
|
||||
import de.markusfisch.android.binaryeye.app.prefs
|
||||
import de.markusfisch.android.binaryeye.app.setFragment
|
||||
import de.markusfisch.android.binaryeye.database.Scan
|
||||
import de.markusfisch.android.binaryeye.fragment.DecodeFragment
|
||||
import de.markusfisch.android.binaryeye.fragment.EncodeFragment
|
||||
@@ -80,10 +85,14 @@ class MainActivity : AppCompatActivity() {
|
||||
return when {
|
||||
intent.hasExtra(PREFERENCES) -> PreferencesFragment()
|
||||
intent.hasExtra(HISTORY) -> HistoryFragment()
|
||||
intent.hasExtra(ENCODE) -> EncodeFragment.newInstance()
|
||||
intent.hasExtra(ENCODE) -> EncodeFragment.newInstance(
|
||||
intent.getStringExtra(ENCODE)
|
||||
)
|
||||
|
||||
intent.hasExtra(DECODED) -> DecodeFragment.newInstance(
|
||||
intent.getParcelableExtra(DECODED)!!
|
||||
)
|
||||
|
||||
else -> PreferencesFragment()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ 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.view.Menu
|
||||
@@ -21,18 +20,24 @@ 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.mapPosition
|
||||
import de.markusfisch.android.binaryeye.os.getVibrator
|
||||
import de.markusfisch.android.binaryeye.os.vibrate
|
||||
import de.markusfisch.android.binaryeye.media.releaseToneGenerators
|
||||
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.scanFeedback
|
||||
import de.markusfisch.android.binaryeye.view.setPaddingFromWindowInsets
|
||||
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.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 kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
@@ -41,8 +46,15 @@ class PickActivity : AppCompatActivity() {
|
||||
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,
|
||||
maxNumberOfSymbols = 1,
|
||||
formats = prefs.barcodeFormats.joinToString()
|
||||
)
|
||||
|
||||
private lateinit var vibrator: Vibrator
|
||||
private lateinit var cropImageView: CropImageView
|
||||
private lateinit var detectorView: DetectorView
|
||||
private lateinit var freeRotationItem: MenuItem
|
||||
@@ -62,8 +74,6 @@ class PickActivity : AppCompatActivity() {
|
||||
// locale.
|
||||
setTitle(R.string.pick_code_to_scan)
|
||||
|
||||
vibrator = getVibrator()
|
||||
|
||||
initSystemBars(this)
|
||||
val toolbar = findViewById(R.id.toolbar) as Toolbar
|
||||
recordToolbarHeight(toolbar)
|
||||
@@ -144,23 +154,13 @@ class PickActivity : AppCompatActivity() {
|
||||
)
|
||||
}
|
||||
scope.launch {
|
||||
ZxingCpp.readBitmap(
|
||||
cropped,
|
||||
0, 0,
|
||||
cropped.width, cropped.height,
|
||||
0,
|
||||
prefs.barcodeFormats.joinToString(),
|
||||
tryHarder = true,
|
||||
tryRotate = true,
|
||||
tryInvert = true,
|
||||
tryDownscale = true
|
||||
)?.let {
|
||||
cropped.decode()?.first()?.let {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (isFinishing) {
|
||||
return@withContext
|
||||
}
|
||||
result = it
|
||||
vibrator.vibrate()
|
||||
scanFeedback()
|
||||
detectorView.update(
|
||||
matrix.mapPosition(
|
||||
it.position,
|
||||
@@ -172,10 +172,31 @@ 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()
|
||||
parentJob.cancel()
|
||||
releaseToneGenerators()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
@@ -192,12 +213,14 @@ 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)
|
||||
}
|
||||
}
|
||||
@@ -231,7 +254,7 @@ class PickActivity : AppCompatActivity() {
|
||||
private fun showResult() {
|
||||
val r = result
|
||||
if (r != null) {
|
||||
showResult(this, r.redact(), vibrator)
|
||||
showResult(r)
|
||||
finish()
|
||||
} else {
|
||||
applicationContext.toast(R.string.no_barcode_found)
|
||||
|
||||
@@ -13,7 +13,7 @@ import de.markusfisch.android.binaryeye.database.Database
|
||||
import java.text.DateFormat
|
||||
import java.text.ParseException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
|
||||
class ScansAdapter(context: Context, cursor: Cursor) :
|
||||
CursorAdapter(context, cursor, false) {
|
||||
@@ -99,9 +99,11 @@ class ScansAdapter(context: Context, cursor: Cursor) :
|
||||
icon = R.drawable.ic_label
|
||||
name
|
||||
}
|
||||
content?.isEmpty() == true -> context.getString(
|
||||
|
||||
content.isNullOrEmpty() -> context.getString(
|
||||
R.string.binary_data
|
||||
)
|
||||
|
||||
else -> content
|
||||
}
|
||||
contentView.setCompoundDrawablesWithIntrinsicBounds(
|
||||
|
||||
@@ -3,6 +3,7 @@ package de.markusfisch.android.binaryeye.app
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.support.v4.app.ActivityCompat
|
||||
import android.support.v4.content.ContextCompat
|
||||
|
||||
@@ -32,6 +33,18 @@ fun Activity.hasLocationPermission(callback: () -> Any): Boolean {
|
||||
)
|
||||
}
|
||||
|
||||
const val PERMISSION_BLUETOOTH = 4
|
||||
fun Activity.hasBluetoothPermission() = if (
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
) {
|
||||
hasPermission(
|
||||
Manifest.permission.BLUETOOTH_CONNECT,
|
||||
PERMISSION_BLUETOOTH
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
private fun Activity.hasPermission(
|
||||
permission: String,
|
||||
requestCode: Int
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package de.markusfisch.android.binaryeye.bluetooth
|
||||
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.bluetooth.BluetoothSocket
|
||||
import android.support.v7.preference.ListPreference
|
||||
import de.markusfisch.android.binaryeye.database.Scan
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.IOException
|
||||
import java.io.OutputStreamWriter
|
||||
import java.util.UUID
|
||||
|
||||
fun Scan.sendBluetoothAsync(
|
||||
host: String,
|
||||
callback: (Boolean, Boolean) -> Unit
|
||||
) {
|
||||
CoroutineScope(Dispatchers.IO).launch(Dispatchers.IO) {
|
||||
val connected = if (isConnected) {
|
||||
true
|
||||
} else {
|
||||
connect(host)
|
||||
}
|
||||
val sent = if (connected) {
|
||||
send(content)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
callback(connected, sent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setBluetoothHosts(listPref: ListPreference) {
|
||||
val devices = try {
|
||||
BluetoothAdapter.getDefaultAdapter().bondedDevices
|
||||
} catch (e: SecurityException) {
|
||||
// Do nothing, either the user has denied Bluetooth access
|
||||
// or the permission was removed by the system. We're catching
|
||||
// the exception to keep the app from crashing.
|
||||
null
|
||||
} ?: return
|
||||
listPref.entries = devices.map {
|
||||
it.name
|
||||
}.toTypedArray()
|
||||
listPref.entryValues = devices.map {
|
||||
it.address
|
||||
}.toTypedArray()
|
||||
listPref.callChangeListener(listPref.value)
|
||||
}
|
||||
|
||||
private var socket: BluetoothSocket? = null
|
||||
private var writer: OutputStreamWriter? = null
|
||||
|
||||
private val blue = BluetoothAdapter.getDefaultAdapter()
|
||||
private val uuid = UUID.fromString(
|
||||
"8a8478c9-2ca8-404b-a0de-101f34ab71ae"
|
||||
)
|
||||
|
||||
private var isConnected = false
|
||||
|
||||
private fun connect(deviceName: String): Boolean = try {
|
||||
val device = findByName(deviceName) ?: throw RuntimeException(
|
||||
"Bluetooth device not found"
|
||||
)
|
||||
socket = device.createRfcommSocketToServiceRecord(uuid)
|
||||
socket?.connect()
|
||||
writer = socket?.outputStream?.writer()
|
||||
isConnected = true
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
close()
|
||||
false
|
||||
}
|
||||
|
||||
private fun send(message: String): Boolean = try {
|
||||
writer?.apply {
|
||||
write(message)
|
||||
write("\n")
|
||||
flush()
|
||||
}
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
close()
|
||||
false
|
||||
}
|
||||
|
||||
private fun close() {
|
||||
try {
|
||||
writer?.close()
|
||||
} catch (e: IOException) {
|
||||
// Catch exception if writer wasn't initialized.
|
||||
}
|
||||
try {
|
||||
socket?.close()
|
||||
} catch (e: IOException) {
|
||||
// Nothing we can do about this but keep
|
||||
// the app from crashing.
|
||||
}
|
||||
writer = null
|
||||
socket = null
|
||||
isConnected = false
|
||||
}
|
||||
|
||||
private fun findByName(findableName: String): BluetoothDevice? {
|
||||
val deviceList = blue.bondedDevices
|
||||
for (device in deviceList) {
|
||||
if (device.address == findableName) {
|
||||
return device
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -10,6 +10,8 @@ import de.markusfisch.android.binaryeye.BuildConfig
|
||||
import de.markusfisch.android.binaryeye.R
|
||||
import de.markusfisch.android.binaryeye.widget.toast
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
fun Context.execShareIntent(intent: Intent): Boolean = if (
|
||||
!startIntent(intent)
|
||||
@@ -35,11 +37,14 @@ fun Context.startIntent(intent: Intent): Boolean = try {
|
||||
false
|
||||
}
|
||||
|
||||
fun Context.openUrl(url: String): Boolean = openUri(url.parseAndNormalizeUri())
|
||||
|
||||
fun Context.openUri(uri: Uri): Boolean = execShareIntent(
|
||||
Intent(Intent.ACTION_VIEW, uri)
|
||||
)
|
||||
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 String.parseAndNormalizeUri(): Uri = Uri.parse(this).let {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
@@ -56,6 +61,39 @@ fun Context.shareText(text: String, mimeType: String = "text/plain") {
|
||||
})
|
||||
}
|
||||
|
||||
private const val SHARE_AS_TEXT_FILE_NAME = "barcode_content"
|
||||
fun Context.wipeShareFile() {
|
||||
File(externalCacheDir, SHARE_AS_TEXT_FILE_NAME).delete()
|
||||
}
|
||||
|
||||
fun <T> Context.shareAsFile(content: T) {
|
||||
val (bytes, mimeType) = when (content) {
|
||||
is ByteArray -> Pair(
|
||||
content,
|
||||
"text/plain"
|
||||
)
|
||||
|
||||
is String -> Pair(
|
||||
content.toByteArray(),
|
||||
"application/octet-stream"
|
||||
)
|
||||
|
||||
else -> throw IllegalArgumentException(
|
||||
"Unsupported content text for shareAsFile()"
|
||||
)
|
||||
}
|
||||
val file = File(externalCacheDir, SHARE_AS_TEXT_FILE_NAME)
|
||||
try {
|
||||
FileOutputStream(file).use {
|
||||
it.write(bytes)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
toast(R.string.error_saving_file)
|
||||
return
|
||||
}
|
||||
shareFile(file, mimeType)
|
||||
}
|
||||
|
||||
fun Context.shareFile(file: File, mimeType: String) {
|
||||
getUriForFile(file)?.let {
|
||||
shareUri(it, mimeType)
|
||||
|
||||
@@ -34,7 +34,7 @@ private fun exportCsv(
|
||||
Database.SCANS_FORMAT,
|
||||
Database.SCANS_CONTENT,
|
||||
Database.SCANS_ERROR_CORRECTION_LEVEL,
|
||||
Database.SCANS_VERSION_NUMBER,
|
||||
Database.SCANS_VERSION,
|
||||
Database.SCANS_SEQUENCE_SIZE,
|
||||
Database.SCANS_SEQUENCE_INDEX,
|
||||
Database.SCANS_SEQUENCE_ID,
|
||||
|
||||
@@ -36,7 +36,7 @@ class Database {
|
||||
$SCANS_RAW,
|
||||
$SCANS_FORMAT,
|
||||
$SCANS_ERROR_CORRECTION_LEVEL,
|
||||
$SCANS_VERSION_NUMBER,
|
||||
$SCANS_VERSION,
|
||||
$SCANS_SEQUENCE_SIZE,
|
||||
$SCANS_SEQUENCE_INDEX,
|
||||
$SCANS_SEQUENCE_ID,
|
||||
@@ -78,7 +78,7 @@ class Database {
|
||||
$SCANS_RAW,
|
||||
$SCANS_FORMAT,
|
||||
$SCANS_ERROR_CORRECTION_LEVEL,
|
||||
$SCANS_VERSION_NUMBER,
|
||||
$SCANS_VERSION,
|
||||
$SCANS_SEQUENCE_SIZE,
|
||||
$SCANS_SEQUENCE_INDEX,
|
||||
$SCANS_SEQUENCE_ID,
|
||||
@@ -96,7 +96,7 @@ class Database {
|
||||
it.getBlob(SCANS_RAW),
|
||||
it.getString(SCANS_FORMAT),
|
||||
it.getString(SCANS_ERROR_CORRECTION_LEVEL),
|
||||
it.getInt(SCANS_VERSION_NUMBER),
|
||||
it.getString(SCANS_VERSION),
|
||||
it.getInt(SCANS_SEQUENCE_SIZE),
|
||||
it.getInt(SCANS_SEQUENCE_INDEX),
|
||||
it.getString(SCANS_SEQUENCE_ID),
|
||||
@@ -117,18 +117,15 @@ class Database {
|
||||
null,
|
||||
ContentValues().apply {
|
||||
put(SCANS_DATETIME, scan.dateTime)
|
||||
val isRaw = scan.raw != null
|
||||
if (isRaw) {
|
||||
put(SCANS_CONTENT, "")
|
||||
put(SCANS_CONTENT, scan.content)
|
||||
if (scan.raw != null) {
|
||||
put(SCANS_RAW, scan.raw)
|
||||
} else {
|
||||
put(SCANS_CONTENT, scan.content)
|
||||
}
|
||||
put(SCANS_FORMAT, scan.format)
|
||||
scan.errorCorrectionLevel?.let {
|
||||
put(SCANS_ERROR_CORRECTION_LEVEL, it)
|
||||
}
|
||||
put(SCANS_VERSION_NUMBER, scan.versionNumber)
|
||||
put(SCANS_VERSION, scan.version)
|
||||
put(SCANS_SEQUENCE_SIZE, scan.sequenceSize)
|
||||
put(SCANS_SEQUENCE_INDEX, scan.sequenceIndex)
|
||||
put(SCANS_SEQUENCE_ID, scan.sequenceId)
|
||||
@@ -139,7 +136,7 @@ class Database {
|
||||
if (prefs.ignoreConsecutiveDuplicates) {
|
||||
val id = getIdOfLastScan(
|
||||
get(SCANS_CONTENT) as String,
|
||||
if (isRaw) get(SCANS_RAW) as ByteArray else null,
|
||||
get(SCANS_RAW) as ByteArray?,
|
||||
scan.format
|
||||
)
|
||||
if (id > 0L) {
|
||||
@@ -192,9 +189,9 @@ class Database {
|
||||
}
|
||||
|
||||
private class OpenHelper(context: Context) :
|
||||
SQLiteOpenHelper(context, FILE_NAME, null, 5) {
|
||||
SQLiteOpenHelper(context, FILE_NAME, null, 6) {
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
createScans(db)
|
||||
db.createScans()
|
||||
}
|
||||
|
||||
override fun onUpgrade(
|
||||
@@ -203,16 +200,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) {
|
||||
migrateToZxingCpp(db)
|
||||
db.migrateToZxingCpp()
|
||||
}
|
||||
if (oldVersion < 6) {
|
||||
db.migrateToVersionString()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,6 +228,7 @@ class Database {
|
||||
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"
|
||||
@@ -243,9 +244,9 @@ class Database {
|
||||
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,
|
||||
@@ -254,7 +255,7 @@ class Database {
|
||||
$SCANS_RAW BLOB,
|
||||
$SCANS_FORMAT TEXT NOT NULL,
|
||||
$SCANS_ERROR_CORRECTION_LEVEL TEXT,
|
||||
$SCANS_VERSION_NUMBER INTEGER,
|
||||
$SCANS_VERSION TEXT,
|
||||
$SCANS_SEQUENCE_SIZE INTEGER,
|
||||
$SCANS_SEQUENCE_INDEX INTEGER,
|
||||
$SCANS_SEQUENCE_ID TEXT,
|
||||
@@ -266,44 +267,45 @@ class Database {
|
||||
)
|
||||
}
|
||||
|
||||
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 migrateToZxingCpp(db: SQLiteDatabase) {
|
||||
db.apply {
|
||||
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.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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ fun Cursor.exportJson(): String? {
|
||||
Database.SCANS_FORMAT,
|
||||
Database.SCANS_CONTENT,
|
||||
Database.SCANS_ERROR_CORRECTION_LEVEL,
|
||||
Database.SCANS_VERSION_NUMBER,
|
||||
Database.SCANS_VERSION,
|
||||
Database.SCANS_SEQUENCE_SIZE,
|
||||
Database.SCANS_SEQUENCE_INDEX,
|
||||
Database.SCANS_SEQUENCE_ID,
|
||||
|
||||
@@ -15,7 +15,7 @@ data class Scan(
|
||||
val raw: ByteArray?,
|
||||
val format: String,
|
||||
val errorCorrectionLevel: String? = null,
|
||||
val versionNumber: Int = 0,
|
||||
val version: String? = null,
|
||||
val sequenceSize: Int = -1,
|
||||
val sequenceIndex: Int = -1,
|
||||
val sequenceId: String = "",
|
||||
@@ -45,7 +45,7 @@ data class Scan(
|
||||
(raw != null && other.raw != null && raw.contentEquals(other.raw))) &&
|
||||
format == other.format &&
|
||||
errorCorrectionLevel == other.errorCorrectionLevel &&
|
||||
versionNumber == other.versionNumber &&
|
||||
version == other.version &&
|
||||
sequenceSize == other.sequenceSize &&
|
||||
sequenceIndex == other.sequenceIndex &&
|
||||
sequenceId == other.sequenceId &&
|
||||
@@ -64,7 +64,7 @@ data class Scan(
|
||||
result = 31 * result + (raw?.contentHashCode() ?: 0)
|
||||
result = 31 * result + format.hashCode()
|
||||
result = 31 * result + (errorCorrectionLevel?.hashCode() ?: 0)
|
||||
result = 31 * result + versionNumber
|
||||
result = 31 * result + version.hashCode()
|
||||
result = 31 * result + sequenceSize
|
||||
result = 31 * result + sequenceIndex
|
||||
result = 31 * result + sequenceId.hashCode()
|
||||
@@ -80,7 +80,7 @@ data class Scan(
|
||||
raw = parcel.readSizedByteArray(),
|
||||
format = parcel.readString() ?: "",
|
||||
errorCorrectionLevel = parcel.readString(),
|
||||
versionNumber = parcel.readInt(),
|
||||
version = parcel.readString(),
|
||||
sequenceSize = parcel.readInt(),
|
||||
sequenceIndex = parcel.readInt(),
|
||||
sequenceId = parcel.readString() ?: "",
|
||||
@@ -98,7 +98,7 @@ data class Scan(
|
||||
writeSizedByteArray(raw)
|
||||
writeString(format)
|
||||
writeString(errorCorrectionLevel)
|
||||
writeInt(versionNumber)
|
||||
writeString(version)
|
||||
writeInt(sequenceSize)
|
||||
writeInt(sequenceIndex)
|
||||
writeString(sequenceId)
|
||||
@@ -123,26 +123,18 @@ data class Scan(
|
||||
}
|
||||
|
||||
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,
|
||||
when (contentType) {
|
||||
ContentType.GS1,
|
||||
ContentType.ISO15434,
|
||||
ContentType.TEXT -> text
|
||||
|
||||
else -> ""
|
||||
},
|
||||
rawBytes,
|
||||
format,
|
||||
ecLevel,
|
||||
versionNumber,
|
||||
version,
|
||||
sequenceSize,
|
||||
sequenceIndex,
|
||||
sequenceId,
|
||||
@@ -159,7 +151,7 @@ data class Recreation(
|
||||
val size: Int,
|
||||
val margin: Int
|
||||
) {
|
||||
fun encode(content: String): Bitmap? = try {
|
||||
fun <T> encode(content: T): Bitmap? = try {
|
||||
ZxingCpp.encodeAsBitmap(
|
||||
content, format, size, size, margin, ecLevel
|
||||
)
|
||||
@@ -171,22 +163,18 @@ data class Recreation(
|
||||
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
|
||||
)
|
||||
}
|
||||
) = Recreation(
|
||||
Format.valueOf(format),
|
||||
when (errorCorrectionLevel) {
|
||||
"L" -> 0
|
||||
"M" -> 4
|
||||
"Q" -> 6
|
||||
"H" -> 8
|
||||
else -> -1
|
||||
},
|
||||
size,
|
||||
margin
|
||||
)
|
||||
|
||||
private fun getDateTime(
|
||||
time: Long = System.currentTimeMillis()
|
||||
|
||||
@@ -31,6 +31,7 @@ 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 {
|
||||
@@ -40,7 +41,7 @@ class BarcodeFragment : Fragment() {
|
||||
private val parentJob = Job()
|
||||
private val scope = CoroutineScope(Dispatchers.IO + parentJob)
|
||||
|
||||
private lateinit var barcode: Barcode
|
||||
private lateinit var barcode: Barcode<*>
|
||||
|
||||
override fun onCreate(state: Bundle?) {
|
||||
super.onCreate(state)
|
||||
@@ -70,7 +71,7 @@ class BarcodeFragment : Fragment() {
|
||||
bitmap = barcode.bitmap()
|
||||
} catch (e: Exception) {
|
||||
var message = e.message
|
||||
if (message == null || message.isEmpty()) {
|
||||
if (message.isNullOrEmpty()) {
|
||||
message = getString(R.string.error_encoding_barcode)
|
||||
}
|
||||
message?.let {
|
||||
@@ -86,7 +87,10 @@ class BarcodeFragment : Fragment() {
|
||||
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 {
|
||||
@@ -106,7 +110,7 @@ class BarcodeFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun Bundle.toBarcode() = Barcode(
|
||||
getString(CONTENT) ?: throw IllegalArgumentException(
|
||||
getString(CONTENT_TEXT) ?: getByteArray(CONTENT_RAW) ?: throw IllegalArgumentException(
|
||||
"content cannot be null"
|
||||
),
|
||||
Format.valueOf(
|
||||
@@ -115,6 +119,7 @@ class BarcodeFragment : Fragment() {
|
||||
)
|
||||
),
|
||||
getInt(SIZE),
|
||||
getInt(MARGIN),
|
||||
getInt(EC_LEVEL),
|
||||
Colors.values()[getInt(COLORS)]
|
||||
)
|
||||
@@ -137,12 +142,14 @@ class BarcodeFragment : Fragment() {
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
R.id.export_to_file -> {
|
||||
context.pickFileType(R.string.export_as) {
|
||||
askForFileNameAndSave(it)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
@@ -186,12 +193,14 @@ class BarcodeFragment : Fragment() {
|
||||
) {
|
||||
barcode.bitmap().saveAsPng(it)
|
||||
}
|
||||
|
||||
FileType.SVG -> saveAs(
|
||||
addSuffixIfNotGiven(fileName, ".svg"),
|
||||
MIME_SVG
|
||||
) { outputStream ->
|
||||
outputStream.write(barcode.svg().toByteArray())
|
||||
}
|
||||
|
||||
FileType.TXT -> saveAs(
|
||||
addSuffixIfNotGiven(fileName, ".txt"),
|
||||
MIME_TXT
|
||||
@@ -252,26 +261,44 @@ class BarcodeFragment : Fragment() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CONTENT = "content"
|
||||
private const val CONTENT_TEXT = "content_text"
|
||||
private const val CONTENT_RAW = "content_raw"
|
||||
private const val FORMAT = "format"
|
||||
private const val SIZE = "size"
|
||||
private const val MARGIN = "margin"
|
||||
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,
|
||||
fun <T> newInstance(
|
||||
content: T,
|
||||
format: Format,
|
||||
size: Int,
|
||||
margin: Int,
|
||||
ecLevel: Int = -1,
|
||||
colors: Int = 0
|
||||
): Fragment {
|
||||
val args = Bundle()
|
||||
args.putString(CONTENT, content)
|
||||
when (content) {
|
||||
is String -> {
|
||||
args.putString(CONTENT_TEXT, content)
|
||||
}
|
||||
|
||||
is ByteArray -> {
|
||||
args.putByteArray(CONTENT_RAW, content)
|
||||
}
|
||||
|
||||
else -> {
|
||||
throw IllegalArgumentException(
|
||||
"content must be a String of a ByteArray"
|
||||
)
|
||||
}
|
||||
}
|
||||
args.putString(FORMAT, format.name)
|
||||
args.putInt(SIZE, size)
|
||||
args.putInt(MARGIN, margin)
|
||||
args.putInt(EC_LEVEL, ecLevel)
|
||||
args.putInt(COLORS, colors)
|
||||
val fragment = BarcodeFragment()
|
||||
@@ -281,17 +308,18 @@ class BarcodeFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private data class Barcode(
|
||||
val content: String,
|
||||
private data class Barcode<T>(
|
||||
val content: T,
|
||||
val format: Format,
|
||||
val size: Int,
|
||||
val margin: 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,
|
||||
content, format, size, size, margin, ecLevel,
|
||||
setColor = colors.foregroundColor(),
|
||||
unsetColor = colors.backgroundColor()
|
||||
)
|
||||
@@ -302,7 +330,7 @@ private data class Barcode(
|
||||
private var _svg: String? = null
|
||||
fun svg(): String {
|
||||
val s = _svg ?: ZxingCpp.encodeAsSvg(
|
||||
content, format, -1, ecLevel
|
||||
content, format, margin, ecLevel
|
||||
)
|
||||
_svg = s
|
||||
return s
|
||||
@@ -311,7 +339,7 @@ private data class Barcode(
|
||||
private var _text: String? = null
|
||||
fun text(): String {
|
||||
val t = _text ?: ZxingCpp.encodeAsText(
|
||||
content, format, -1, ecLevel,
|
||||
content, format, margin, ecLevel,
|
||||
inverted = colors == Colors.BLACK_ON_WHITE
|
||||
)
|
||||
_text = t
|
||||
@@ -328,6 +356,7 @@ private enum class Colors {
|
||||
fun foregroundColor(): Int = when (this) {
|
||||
BLACK_ON_WHITE,
|
||||
BLACK_ON_TRANSPARENT -> COLOR_BLACK
|
||||
|
||||
WHITE_ON_BLACK,
|
||||
WHITE_ON_TRANSPARENT -> COLOR_WHITE
|
||||
}
|
||||
|
||||
@@ -19,8 +19,10 @@ import de.markusfisch.android.binaryeye.activity.MainActivity
|
||||
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.shareAsFile
|
||||
import de.markusfisch.android.binaryeye.content.shareText
|
||||
import de.markusfisch.android.binaryeye.content.toHexString
|
||||
import de.markusfisch.android.binaryeye.content.wipeShareFile
|
||||
import de.markusfisch.android.binaryeye.database.Recreation
|
||||
import de.markusfisch.android.binaryeye.database.Scan
|
||||
import de.markusfisch.android.binaryeye.database.toRecreation
|
||||
@@ -86,7 +88,7 @@ class DecodeFragment : Fragment() {
|
||||
} ?: throw IllegalArgumentException("DecodeFragment needs a Scan")
|
||||
|
||||
val originalContent = scan.content
|
||||
isBinary = scan.raw != null
|
||||
isBinary = scan.content.isEmpty()
|
||||
originalBytes = scan.raw ?: originalContent.toByteArray()
|
||||
format = scan.format
|
||||
id = scan.id
|
||||
@@ -124,6 +126,7 @@ class DecodeFragment : Fragment() {
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
parentJob.cancel()
|
||||
activity?.wipeShareFile()
|
||||
}
|
||||
|
||||
private fun initContentAndFab(originalContent: String) {
|
||||
@@ -204,11 +207,12 @@ class DecodeFragment : Fragment() {
|
||||
}
|
||||
recreationView.showIf(prefs.showRecreation) { v ->
|
||||
val r = recreation ?: return@showIf
|
||||
v.setImageBitmap(r.encode(text))
|
||||
val content = if (isBinary) bytes else text
|
||||
v.setImageBitmap(r.encode(content))
|
||||
v.setOnClickListener {
|
||||
fragmentManager?.addFragment(
|
||||
BarcodeFragment.newInstance(
|
||||
text,
|
||||
content,
|
||||
r.format,
|
||||
r.size,
|
||||
r.ecLevel
|
||||
@@ -253,15 +257,15 @@ class DecodeFragment : Fragment() {
|
||||
R.string.gtin_price to scan.price,
|
||||
R.string.gtin_issue_number to scan.issueNumber,
|
||||
)
|
||||
if (scan.versionNumber > 0) {
|
||||
if (!scan.version.isNullOrBlank()) {
|
||||
val versionString = if (scan.format == "QR_CODE") {
|
||||
getString(
|
||||
R.string.qr_version_and_modules,
|
||||
scan.versionNumber,
|
||||
scan.versionNumber * 4 + 17
|
||||
scan.version,
|
||||
(scan.version.toIntOrNull() ?: 0) * 4 + 17
|
||||
)
|
||||
} else {
|
||||
scan.versionNumber.toString()
|
||||
scan.version
|
||||
}
|
||||
items.putAll(
|
||||
linkedMapOf(
|
||||
@@ -299,10 +303,6 @@ class DecodeFragment : Fragment() {
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.fragment_decode, menu)
|
||||
if (isBinary) {
|
||||
menu.findItem(R.id.copy_to_clipboard).isVisible = false
|
||||
menu.findItem(R.id.create).isVisible = false
|
||||
}
|
||||
if (id > 0L) {
|
||||
menu.findItem(R.id.remove).isVisible = true
|
||||
}
|
||||
@@ -318,11 +318,13 @@ class DecodeFragment : Fragment() {
|
||||
maybeBackOrFinish()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.copy_to_clipboard -> {
|
||||
copyToClipboard(textOrHex())
|
||||
maybeBackOrFinish()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.share -> {
|
||||
context?.apply {
|
||||
shareText(textOrHex())
|
||||
@@ -330,17 +332,31 @@ class DecodeFragment : Fragment() {
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
R.id.share_file -> {
|
||||
context?.apply {
|
||||
shareAsFile(if (isBinary) originalBytes else content)
|
||||
maybeBackOrFinish()
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
R.id.create -> {
|
||||
fragmentManager?.addFragment(
|
||||
EncodeFragment.newInstance(content, format)
|
||||
EncodeFragment.newInstance(
|
||||
if (isBinary) originalBytes else content,
|
||||
format
|
||||
)
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.remove -> {
|
||||
db.removeScan(id)
|
||||
backOrFinish()
|
||||
true
|
||||
}
|
||||
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
package de.markusfisch.android.binaryeye.fragment
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.CheckBox
|
||||
import android.widget.EditText
|
||||
import android.widget.SeekBar
|
||||
import android.widget.Spinner
|
||||
import android.widget.TextView
|
||||
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.text.unescape
|
||||
import de.markusfisch.android.binaryeye.view.hideSoftKeyboard
|
||||
import de.markusfisch.android.binaryeye.view.setPaddingFromWindowInsets
|
||||
import de.markusfisch.android.binaryeye.widget.toast
|
||||
import de.markusfisch.android.zxingcpp.ZxingCpp.Format
|
||||
import java.io.InputStream
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class EncodeFragment : Fragment() {
|
||||
private lateinit var formatView: Spinner
|
||||
@@ -24,9 +40,13 @@ class EncodeFragment : Fragment() {
|
||||
private lateinit var colorsSpinner: Spinner
|
||||
private lateinit var sizeView: TextView
|
||||
private lateinit var sizeBarView: SeekBar
|
||||
private lateinit var marginLayout: View
|
||||
private lateinit var marginView: TextView
|
||||
private lateinit var marginBarView: SeekBar
|
||||
private lateinit var contentView: EditText
|
||||
private lateinit var unescapeCheckBox: CheckBox
|
||||
|
||||
private val writers = arrayListOf(
|
||||
private val formats = arrayListOf(
|
||||
Format.AZTEC,
|
||||
Format.CODABAR,
|
||||
Format.CODE_39,
|
||||
@@ -40,6 +60,37 @@ class EncodeFragment : Fragment() {
|
||||
Format.UPC_A
|
||||
)
|
||||
|
||||
private var minMargin = 0
|
||||
private var bytes: ByteArray? = null
|
||||
|
||||
override fun onActivityResult(
|
||||
requestCode: Int,
|
||||
resultCode: Int,
|
||||
resultData: Intent?
|
||||
) {
|
||||
when (requestCode) {
|
||||
PICK_FILE_RESULT_CODE -> {
|
||||
if (resultCode == Activity.RESULT_OK &&
|
||||
resultData != null &&
|
||||
resultData.data != null
|
||||
) {
|
||||
val ac = activity ?: return
|
||||
ac.hideSoftKeyboard(contentView)
|
||||
val uri = resultData.data ?: return
|
||||
bytes = ac.contentResolver?.openInputStream(uri)?.use {
|
||||
it.readBytesMax(4096)
|
||||
} ?: return
|
||||
setEncodeByteArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(state: Bundle?) {
|
||||
super.onCreate(state)
|
||||
setHasOptionsMenu(true)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@@ -58,7 +109,7 @@ class EncodeFragment : Fragment() {
|
||||
val formatAdapter = ArrayAdapter(
|
||||
ac,
|
||||
android.R.layout.simple_spinner_item,
|
||||
writers.map { prettifyFormatName(it.name) }
|
||||
formats.map { prettifyFormatName(it.name) }
|
||||
)
|
||||
formatAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item
|
||||
@@ -71,16 +122,35 @@ class EncodeFragment : Fragment() {
|
||||
position: Int,
|
||||
id: Long
|
||||
) {
|
||||
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
|
||||
val format = formats[position]
|
||||
val arrayId = when (format) {
|
||||
Format.AZTEC -> R.array.aztec_error_correction_levels
|
||||
Format.QR_CODE -> R.array.qr_error_correction_levels
|
||||
Format.PDF_417 -> R.array.pdf417_error_correction_levels
|
||||
else -> 0
|
||||
}
|
||||
if (arrayId > 0) {
|
||||
ecSpinner.setEntries(arrayId)
|
||||
val idx = format.unpackEcLevel(
|
||||
prefs.indexOfLastSelectedEcLevel
|
||||
)
|
||||
if (idx < ecSpinner.adapter.count) {
|
||||
ecSpinner.setSelection(idx)
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}.setVisibilityFor(ecLabel, ecSpinner)
|
||||
format.canBeInverted().setVisibilityFor(
|
||||
colorsLabel, colorsSpinner
|
||||
)
|
||||
when (format) {
|
||||
Format.AZTEC -> setMarginBar(4, 4)
|
||||
Format.DATA_MATRIX -> setMarginBar(1, 1)
|
||||
Format.QR_CODE -> setMarginBar(4, 4)
|
||||
Format.PDF_417 -> setMarginBar(0, 30)
|
||||
else -> false
|
||||
}.setVisibilityFor(marginLayout)
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parentView: AdapterView<*>?) {}
|
||||
@@ -88,6 +158,22 @@ class EncodeFragment : Fragment() {
|
||||
|
||||
ecLabel = view.findViewById(R.id.error_correction_label)
|
||||
ecSpinner = view.findViewById(R.id.error_correction_level)
|
||||
ecSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(
|
||||
parentView: AdapterView<*>?,
|
||||
selectedItemView: View?,
|
||||
position: Int,
|
||||
id: Long
|
||||
) {
|
||||
val format = formats[formatView.selectedItemPosition]
|
||||
prefs.indexOfLastSelectedEcLevel = format.packEcLevel(
|
||||
prefs.indexOfLastSelectedEcLevel,
|
||||
position
|
||||
)
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parentView: AdapterView<*>?) {}
|
||||
}
|
||||
|
||||
colorsLabel = view.findViewById(R.id.colors_label)
|
||||
colorsSpinner = view.findViewById(R.id.colors)
|
||||
@@ -96,17 +182,28 @@ class EncodeFragment : Fragment() {
|
||||
sizeBarView = view.findViewById(R.id.size_bar)
|
||||
initSizeBar()
|
||||
|
||||
marginLayout = view.findViewById(R.id.margin)
|
||||
marginView = view.findViewById(R.id.margin_display)
|
||||
marginBarView = view.findViewById(R.id.margin_bar)
|
||||
initMarginBar()
|
||||
|
||||
contentView = view.findViewById(R.id.content)
|
||||
unescapeCheckBox = view.findViewById(R.id.unescape)
|
||||
unescapeCheckBox.isChecked = prefs.expandEscapeSequences
|
||||
|
||||
val args = arguments
|
||||
args?.getString(CONTENT)?.let {
|
||||
args?.getString(CONTENT_TEXT)?.let {
|
||||
contentView.setText(it)
|
||||
}
|
||||
args?.getByteArray(CONTENT_RAW)?.let {
|
||||
bytes = it
|
||||
setEncodeByteArray()
|
||||
}
|
||||
|
||||
val barcodeFormat = args?.getString(FORMAT)
|
||||
if (barcodeFormat != null) {
|
||||
formatView.setSelection(
|
||||
writers.indexOf(barcodeFormat.toFormat())
|
||||
formats.indexOf(barcodeFormat.toFormat())
|
||||
)
|
||||
} else if (state == null) {
|
||||
formatView.post {
|
||||
@@ -124,26 +221,72 @@ class EncodeFragment : Fragment() {
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.fragment_encode, menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.pick_file -> {
|
||||
startActivityForResult(
|
||||
Intent.createChooser(
|
||||
Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||
type = "*/*"
|
||||
},
|
||||
getString(R.string.pick_file)
|
||||
),
|
||||
PICK_FILE_RESULT_CODE
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
prefs.indexOfLastSelectedFormat = formatView.selectedItemPosition
|
||||
prefs.expandEscapeSequences = unescapeCheckBox.isChecked
|
||||
prefs.lastMargin = marginBarView.progress
|
||||
}
|
||||
|
||||
private fun Context.encode() {
|
||||
val content = contentView.text.toString()
|
||||
if (content.isEmpty()) {
|
||||
toast(R.string.error_no_content)
|
||||
return
|
||||
}
|
||||
hideSoftKeyboard(contentView)
|
||||
val writer = writers[formatView.selectedItemPosition]
|
||||
val content = if (bytes != null) {
|
||||
bytes
|
||||
} else {
|
||||
var text = contentView.text.toString()
|
||||
if (unescapeCheckBox.isChecked) {
|
||||
try {
|
||||
text = text.unescape()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
toast(e.message ?: "Invalid escape sequence")
|
||||
return
|
||||
}
|
||||
}
|
||||
if (text.isEmpty()) {
|
||||
toast(R.string.error_no_content)
|
||||
return
|
||||
}
|
||||
text
|
||||
}
|
||||
val format = formats[formatView.selectedItemPosition]
|
||||
fragmentManager?.addFragment(
|
||||
BarcodeFragment.newInstance(
|
||||
content,
|
||||
writer,
|
||||
format,
|
||||
getSize(sizeBarView.progress),
|
||||
ecSpinner.selectedItemPosition,
|
||||
if (writer.canBeInverted()) {
|
||||
when (format) {
|
||||
Format.AZTEC,
|
||||
Format.DATA_MATRIX,
|
||||
Format.QR_CODE,
|
||||
Format.PDF_417 -> marginBarView.progress
|
||||
|
||||
else -> -1
|
||||
},
|
||||
format.getErrorCorrectionLevel(ecSpinner.selectedItemPosition),
|
||||
if (format.canBeInverted()) {
|
||||
colorsSpinner.selectedItemPosition
|
||||
} else 0
|
||||
)
|
||||
@@ -170,21 +313,77 @@ class EncodeFragment : Fragment() {
|
||||
|
||||
private fun updateSize(power: Int) {
|
||||
val size = getSize(power)
|
||||
sizeView.text = getString(R.string.width_by_height, size, size)
|
||||
sizeView.text = getString(R.string.size_width_by_height, size, size)
|
||||
}
|
||||
|
||||
private fun getSize(power: Int) = 128 * (power + 1)
|
||||
private fun initMarginBar() {
|
||||
updateMargin(marginBarView.progress)
|
||||
marginBarView.setOnSeekBarChangeListener(
|
||||
object : SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(
|
||||
seekBar: SeekBar,
|
||||
progressValue: Int,
|
||||
fromUser: Boolean
|
||||
) {
|
||||
if (progressValue >= minMargin) {
|
||||
updateMargin(progressValue)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar) {}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {}
|
||||
})
|
||||
}
|
||||
|
||||
private fun updateMargin(margin: Int) {
|
||||
marginView.text = getString(R.string.margin_size, margin)
|
||||
}
|
||||
|
||||
private fun setMarginBar(minimum: Int, value: Int): Boolean {
|
||||
minMargin = minimum
|
||||
marginBarView.apply {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
min = minimum
|
||||
}
|
||||
progress = max(
|
||||
minimum, if (prefs.lastMargin > -1) {
|
||||
prefs.lastMargin
|
||||
} else {
|
||||
value
|
||||
}
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun setEncodeByteArray() {
|
||||
contentView.text = null
|
||||
contentView.hint = getString(R.string.binary_data)
|
||||
contentView.isEnabled = false
|
||||
unescapeCheckBox.isEnabled = false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CONTENT = "content"
|
||||
private const val CONTENT_TEXT = "content_text"
|
||||
private const val CONTENT_RAW = "content_raw"
|
||||
private const val FORMAT = "format"
|
||||
private const val PICK_FILE_RESULT_CODE = 1
|
||||
|
||||
fun newInstance(
|
||||
content: String? = null,
|
||||
fun <T> newInstance(
|
||||
content: T? = null,
|
||||
format: String? = null
|
||||
): Fragment {
|
||||
val args = Bundle()
|
||||
content?.let { args.putString(CONTENT, content) }
|
||||
content?.let {
|
||||
when (content) {
|
||||
is String -> args.putString(CONTENT_TEXT, content)
|
||||
is ByteArray -> args.putByteArray(CONTENT_RAW, content)
|
||||
else -> throw IllegalArgumentException(
|
||||
"content must be a String or a ByteArray"
|
||||
)
|
||||
}
|
||||
}
|
||||
format?.let { args.putString(FORMAT, it) }
|
||||
val fragment = EncodeFragment()
|
||||
fragment.arguments = args
|
||||
@@ -193,10 +392,33 @@ class EncodeFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun Boolean.setVisibilityFor(vararg views: View) {
|
||||
val visibility = if (this) View.VISIBLE else View.GONE
|
||||
for (view in views) {
|
||||
view.visibility = visibility
|
||||
}
|
||||
}
|
||||
|
||||
private fun Format.packEcLevel(packed: Int, level: Int): Int {
|
||||
val s = ecLevelShift()
|
||||
return (level shl s) or (packed and (15 shl s).inv())
|
||||
}
|
||||
|
||||
private fun Format.unpackEcLevel(packed: Int) =
|
||||
(packed shr ecLevelShift()) and 15
|
||||
|
||||
private fun Format.ecLevelShift() = when (this) {
|
||||
Format.AZTEC -> 0
|
||||
Format.QR_CODE -> 4
|
||||
Format.PDF_417 -> 8
|
||||
else -> throw IllegalArgumentException("$this does not have error levels")
|
||||
}
|
||||
|
||||
private fun Format.canBeInverted() = when (this) {
|
||||
Format.AZTEC,
|
||||
Format.DATA_MATRIX,
|
||||
Format.QR_CODE -> true
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
@@ -205,3 +427,38 @@ private fun String.toFormat(default: Format = Format.QR_CODE): Format = try {
|
||||
} catch (_: IllegalArgumentException) {
|
||||
default
|
||||
}
|
||||
|
||||
private fun Format.getErrorCorrectionLevel(position: Int) = when (this) {
|
||||
Format.AZTEC -> position
|
||||
Format.QR_CODE -> (position + 1) * 2
|
||||
Format.PDF_417 -> position
|
||||
else -> 0
|
||||
}.coerceIn(0, 8)
|
||||
|
||||
private fun Spinner.setEntries(resId: Int) = ArrayAdapter.createFromResource(
|
||||
this.context,
|
||||
resId,
|
||||
android.R.layout.simple_spinner_item
|
||||
).also { aa ->
|
||||
aa.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item
|
||||
)
|
||||
adapter = aa
|
||||
}
|
||||
|
||||
private fun getSize(power: Int) = 128 * (power + 1)
|
||||
|
||||
private fun InputStream.readBytesMax(max: Int): ByteArray {
|
||||
var offset = 0
|
||||
var remaining = min(available(), max)
|
||||
val result = ByteArray(remaining)
|
||||
while (remaining > 0) {
|
||||
val read = read(result, offset, remaining)
|
||||
if (read < 0) {
|
||||
break
|
||||
}
|
||||
remaining -= read
|
||||
offset += read
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -79,6 +79,7 @@ class HistoryFragment : Fragment() {
|
||||
closeActionMode()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.edit_scan -> {
|
||||
scansAdapter?.forSelection { id, position ->
|
||||
ac.askForName(
|
||||
@@ -90,6 +91,7 @@ class HistoryFragment : Fragment() {
|
||||
closeActionMode()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.remove_scan -> {
|
||||
scansAdapter?.getSelectedIds()?.let {
|
||||
if (it.isNotEmpty()) {
|
||||
@@ -99,6 +101,7 @@ class HistoryFragment : Fragment() {
|
||||
closeActionMode()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@@ -221,10 +224,12 @@ class HistoryFragment : Fragment() {
|
||||
context.askToRemoveScans()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.export_history -> {
|
||||
askToExportToFile()
|
||||
true
|
||||
}
|
||||
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -16,9 +16,12 @@ 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.hasBluetoothPermission
|
||||
import de.markusfisch.android.binaryeye.app.prefs
|
||||
import de.markusfisch.android.binaryeye.bluetooth.setBluetoothHosts
|
||||
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
|
||||
@@ -27,33 +30,70 @@ import de.markusfisch.android.binaryeye.widget.toast
|
||||
class PreferencesFragment : PreferenceFragmentCompat() {
|
||||
private val changeListener = object : OnSharedPreferenceChangeListener {
|
||||
override fun onSharedPreferenceChanged(
|
||||
sharedPreferences: SharedPreferences,
|
||||
key: String
|
||||
sharedPreferences: SharedPreferences?,
|
||||
key: String?
|
||||
) {
|
||||
key ?: return
|
||||
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)
|
||||
}
|
||||
|
||||
"send_scan_bluetooth" -> {
|
||||
if (prefs.sendScanBluetooth &&
|
||||
activity?.hasBluetoothPermission() == false
|
||||
) {
|
||||
prefs.sendScanBluetooth = false
|
||||
}
|
||||
setSummary(preference)
|
||||
}
|
||||
|
||||
else -> setSummary(preference)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(state: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.preferences)
|
||||
activity?.setTitle(R.string.preferences)
|
||||
setBluetoothResources()
|
||||
wireClearNetworkPreferences()
|
||||
}
|
||||
|
||||
private fun setBluetoothResources() {
|
||||
if (prefs.sendScanBluetooth &&
|
||||
activity?.hasBluetoothPermission() == true
|
||||
) {
|
||||
setBluetoothHosts(
|
||||
findPreference("send_scan_bluetooth_host") as ListPreference
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
context.askToClearNetworkSuggestions()
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,8 +112,8 @@ class PreferencesFragment : PreferenceFragmentCompat() {
|
||||
@RequiresApi(Build.VERSION_CODES.Q)
|
||||
private fun Context.clearNetworkSuggestions() {
|
||||
toast(
|
||||
if (
|
||||
removeNetworkSuggestions(this) == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS
|
||||
if (removeAllNetworkSuggestions() ==
|
||||
WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS
|
||||
) {
|
||||
R.string.clear_network_suggestions_success
|
||||
} else {
|
||||
@@ -84,6 +124,7 @@ class PreferencesFragment : PreferenceFragmentCompat() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
activity?.setTitle(R.string.preferences)
|
||||
listView.setPaddingFromWindowInsets()
|
||||
listView.removeOnScrollListener(systemBarRecyclerViewScrollListener)
|
||||
listView.addOnScrollListener(systemBarRecyclerViewScrollListener)
|
||||
@@ -105,6 +146,12 @@ class PreferencesFragment : PreferenceFragmentCompat() {
|
||||
setTargetFragment(this@PreferencesFragment, 0)
|
||||
show(fm, null)
|
||||
}
|
||||
} else if (preference.key == "send_scan_bluetooth_host") {
|
||||
val ac = activity ?: return
|
||||
if (ac.hasBluetoothPermission()) {
|
||||
setBluetoothHosts(preference as ListPreference)
|
||||
}
|
||||
super.onDisplayPreferenceDialog(preference)
|
||||
} else {
|
||||
super.onDisplayPreferenceDialog(preference)
|
||||
}
|
||||
@@ -122,9 +169,11 @@ class PreferencesFragment : PreferenceFragmentCompat() {
|
||||
is UrlPreference -> {
|
||||
preference.setSummary(preference.getUrl())
|
||||
}
|
||||
|
||||
is ListPreference -> {
|
||||
preference.setSummary(preference.entry)
|
||||
}
|
||||
|
||||
is MultiSelectListPreference -> {
|
||||
preference.setSummary(
|
||||
preference.values.joinToString(", ") {
|
||||
@@ -132,6 +181,7 @@ class PreferencesFragment : PreferenceFragmentCompat() {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
is PreferenceGroup -> {
|
||||
setSummaries(preference)
|
||||
}
|
||||
@@ -152,3 +202,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())
|
||||
|
||||
@@ -19,10 +19,10 @@ fun Rect.setFrameRoi(
|
||||
) {
|
||||
Matrix().apply {
|
||||
// Map ROI from view coordinates to frame coordinates.
|
||||
setScale(1f / viewRect.width(), 1f / viewRect.height())
|
||||
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())
|
||||
postTranslate(-viewRect.left.toFloat(), -viewRect.top.toFloat())
|
||||
val frameRoiF = RectF()
|
||||
val viewRoiF = RectF(
|
||||
viewRoi.left.toFloat(),
|
||||
@@ -54,6 +54,7 @@ fun Matrix.setFrameToView(
|
||||
uprightWidth = frameMetrics.height
|
||||
uprightHeight = frameMetrics.width
|
||||
}
|
||||
|
||||
else -> {
|
||||
uprightWidth = frameMetrics.width
|
||||
uprightHeight = frameMetrics.height
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -33,6 +33,7 @@ private fun Scan.send(url: String, type: String): Response {
|
||||
"1" -> request(
|
||||
url + "?" + asUrlArguments()
|
||||
)
|
||||
|
||||
"2" -> request(url) { con ->
|
||||
con.requestMethod = "POST"
|
||||
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
|
||||
@@ -41,6 +42,7 @@ private fun Scan.send(url: String, type: String): Response {
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
"3" -> request(url) { con ->
|
||||
con.requestMethod = "POST"
|
||||
con.setRequestProperty("Content-Type", "application/json")
|
||||
@@ -49,6 +51,7 @@ private fun Scan.send(url: String, type: String): Response {
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
else -> request(
|
||||
url + content.urlEncode()
|
||||
)
|
||||
@@ -68,7 +71,7 @@ private fun Scan.getMap(): Map<String, String> = mapOf(
|
||||
"raw" to raw?.toHexString(),
|
||||
"format" to format,
|
||||
"errorCorrectionLevel" to errorCorrectionLevel,
|
||||
"versionNumber" to versionNumber.toString(),
|
||||
"version" to version,
|
||||
"sequenceSize" to sequenceSize.toString(),
|
||||
"sequenceIndex" to sequenceIndex.toString(),
|
||||
"sequenceId" to sequenceId,
|
||||
|
||||
@@ -4,9 +4,8 @@ import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
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(
|
||||
@@ -38,9 +37,7 @@ fun Context.getVibrator(): Vibrator = getSystemService(
|
||||
) as Vibrator
|
||||
|
||||
fun Vibrator.vibrate() {
|
||||
if (!prefs.vibrate) {
|
||||
return
|
||||
} else if (beforeO) {
|
||||
if (beforeO) {
|
||||
@Suppress("DEPRECATION")
|
||||
vibrate(DURATION_IN_MS)
|
||||
} else {
|
||||
@@ -54,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,6 +2,7 @@ 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
|
||||
@@ -61,37 +62,27 @@ class Preferences {
|
||||
}
|
||||
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
|
||||
@@ -99,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)
|
||||
@@ -164,9 +165,21 @@ class Preferences {
|
||||
apply(SEND_SCAN_TYPE, value)
|
||||
field = value
|
||||
}
|
||||
var sendScanBluetooth = false
|
||||
set(value) {
|
||||
apply(SEND_SCAN_BLUETOOTH, value)
|
||||
field = value
|
||||
}
|
||||
var sendScanBluetoothHost: String = ""
|
||||
set(value) {
|
||||
apply(SEND_SCAN_BLUETOOTH_HOST, value)
|
||||
field = value
|
||||
}
|
||||
var customLocale: String = ""
|
||||
set(value) {
|
||||
apply(CUSTOM_LOCALE, value)
|
||||
// Make sure this setting is written immediately because
|
||||
// the app is about to restart.
|
||||
commit(CUSTOM_LOCALE, value)
|
||||
field = value
|
||||
}
|
||||
var indexOfLastSelectedFormat: Int = 0
|
||||
@@ -174,11 +187,26 @@ class Preferences {
|
||||
apply(INDEX_OF_LAST_SELECTED_FORMAT, value)
|
||||
field = value
|
||||
}
|
||||
var indexOfLastSelectedEcLevel: Int = 0
|
||||
set(value) {
|
||||
apply(INDEX_OF_LAST_SELECTED_EC_LEVEL, value)
|
||||
field = value
|
||||
}
|
||||
var lastMargin: Int = -1
|
||||
set(value) {
|
||||
apply(LAST_MARGIN, value)
|
||||
field = value
|
||||
}
|
||||
var freeRotation = true
|
||||
set(value) {
|
||||
apply(FREE_ROTATION, value)
|
||||
field = value
|
||||
}
|
||||
var expandEscapeSequences = true
|
||||
set(value) {
|
||||
apply(EXPAND_ESCAPE_SEQUENCES, value)
|
||||
field = value
|
||||
}
|
||||
|
||||
fun init(context: Context) {
|
||||
preferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
@@ -214,6 +242,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,
|
||||
@@ -250,6 +282,16 @@ class Preferences {
|
||||
preferences.getString(SEND_SCAN_TYPE, sendScanType)?.also {
|
||||
sendScanType = it
|
||||
}
|
||||
sendScanBluetooth = preferences.getBoolean(
|
||||
SEND_SCAN_BLUETOOTH,
|
||||
sendScanBluetooth
|
||||
)
|
||||
preferences.getString(
|
||||
SEND_SCAN_BLUETOOTH_HOST,
|
||||
sendScanBluetoothHost
|
||||
)?.also {
|
||||
sendScanBluetoothHost = it
|
||||
}
|
||||
preferences.getString(CUSTOM_LOCALE, customLocale)?.also {
|
||||
customLocale = it
|
||||
}
|
||||
@@ -257,7 +299,28 @@ class Preferences {
|
||||
INDEX_OF_LAST_SELECTED_FORMAT,
|
||||
indexOfLastSelectedFormat
|
||||
)
|
||||
indexOfLastSelectedEcLevel = preferences.getInt(
|
||||
INDEX_OF_LAST_SELECTED_EC_LEVEL,
|
||||
indexOfLastSelectedEcLevel
|
||||
)
|
||||
lastMargin = preferences.getInt(
|
||||
LAST_MARGIN,
|
||||
lastMargin
|
||||
)
|
||||
freeRotation = preferences.getBoolean(FREE_ROTATION, freeRotation)
|
||||
expandEscapeSequences = preferences.getBoolean(
|
||||
EXPAND_ESCAPE_SEQUENCES,
|
||||
expandEscapeSequences
|
||||
)
|
||||
}
|
||||
|
||||
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) =
|
||||
@@ -266,14 +329,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()
|
||||
}
|
||||
@@ -286,6 +341,10 @@ class Preferences {
|
||||
preferences.edit().putInt(label, value).apply()
|
||||
}
|
||||
|
||||
private fun commit(label: String, value: String) {
|
||||
preferences.edit().putString(label, value).commit()
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
private fun apply(label: String, value: Set<String>) {
|
||||
preferences.edit().putStringSet(label, value).apply()
|
||||
@@ -304,6 +363,8 @@ 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"
|
||||
@@ -317,8 +378,13 @@ class Preferences {
|
||||
private const val SEND_SCAN_ACTIVE = "send_scan_active"
|
||||
private const val SEND_SCAN_URL = "send_scan_url"
|
||||
private const val SEND_SCAN_TYPE = "send_scan_type"
|
||||
private const val SEND_SCAN_BLUETOOTH = "send_scan_bluetooth"
|
||||
private const val SEND_SCAN_BLUETOOTH_HOST = "send_scan_bluetooth_host"
|
||||
private const val CUSTOM_LOCALE = "custom_locale"
|
||||
private const val INDEX_OF_LAST_SELECTED_FORMAT = "index_of_last_selected_format"
|
||||
private const val INDEX_OF_LAST_SELECTED_EC_LEVEL = "index_of_last_selected_ec_level"
|
||||
private const val LAST_MARGIN = "last_margin"
|
||||
private const val FREE_ROTATION = "free_rotation"
|
||||
private const val EXPAND_ESCAPE_SEQUENCES = "expand_escape_sequences"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.markusfisch.android.binaryeye.service
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.service.quicksettings.TileService
|
||||
@@ -12,6 +13,17 @@ class ScanTileService : TileService() {
|
||||
super.onClick()
|
||||
val intent = Intent(applicationContext, CameraActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
startActivityAndCollapse(intent)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
@Suppress("DEPRECATION")
|
||||
startActivityAndCollapse(intent)
|
||||
} else {
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
this,
|
||||
0,
|
||||
intent,
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
startActivityAndCollapse(pendingIntent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package de.markusfisch.android.binaryeye.text
|
||||
|
||||
/**
|
||||
* Copyright (c) 2000, Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// This code is based on Google's own implementation:
|
||||
// http://www.java2s.com/example/android-utility-method/string-escape/javascriptunescape-string-s-dc359.html
|
||||
fun String.unescape(): String {
|
||||
val len = length
|
||||
var i = 0
|
||||
fun String.expand() = when (val ec = get(i++)) {
|
||||
'n' -> '\n'
|
||||
'r' -> '\r'
|
||||
't' -> '\t'
|
||||
'b' -> '\b'
|
||||
'\\', '\"', '\'', '<', '>', '|' -> ec
|
||||
'0', '1', '2', '3', '4', '5', '6', '7' -> {
|
||||
val limit = if (ec < '4') 3 else 2
|
||||
var l = 1
|
||||
--i // Back to index of first digit.
|
||||
while (l < limit &&
|
||||
i + l < len &&
|
||||
get(i + l) in '0'..'7'
|
||||
) {
|
||||
++l
|
||||
}
|
||||
val from = i
|
||||
i += l
|
||||
substring(from, i).toInt(8).toChar()
|
||||
}
|
||||
|
||||
'x', 'u' -> {
|
||||
val l = if (ec == 'u') 4 else 2
|
||||
val hexCode = try {
|
||||
substring(i, i + l)
|
||||
} catch (_: IndexOutOfBoundsException) {
|
||||
throw IllegalArgumentException(
|
||||
"Invalid unicode sequence [${substring(i)}] at index $i"
|
||||
)
|
||||
}
|
||||
val unicodeValue = try {
|
||||
hexCode.toInt(16)
|
||||
} catch (_: NumberFormatException) {
|
||||
throw IllegalArgumentException(
|
||||
"Invalid unicode sequence [$hexCode] at index $i"
|
||||
)
|
||||
}
|
||||
i += l
|
||||
unicodeValue.toChar()
|
||||
}
|
||||
|
||||
else -> throw IllegalArgumentException(
|
||||
"Unknown escape code [$ec] at index $i"
|
||||
)
|
||||
}
|
||||
|
||||
val sb = StringBuilder()
|
||||
while (i < len) {
|
||||
val ch = get(i++)
|
||||
sb.append(if (ch == '\\' && i < len) expand() else ch)
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
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 (prefs.beep && !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
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,7 @@ class DetectorView : View {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
if (handleGrabbed) {
|
||||
handlePos.set(x, y)
|
||||
@@ -176,6 +177,7 @@ class DetectorView : View {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_CANCEL -> {
|
||||
if (handleGrabbed) {
|
||||
snap(x, y)
|
||||
@@ -183,6 +185,7 @@ class DetectorView : View {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_UP -> {
|
||||
if (handleGrabbed) {
|
||||
if (!handleActive) {
|
||||
@@ -199,6 +202,7 @@ class DetectorView : View {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
else -> super.onTouchEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 731 B |
|
Before Width: | Height: | Size: 899 B After Width: | Height: | Size: 583 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 755 B |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 899 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 698 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 16 KiB |
@@ -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="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"/>
|
||||
<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>
|
||||
|
||||
@@ -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="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"/>
|
||||
<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,4 @@
|
||||
<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:fillColor="#FF000000" android:pathData="M58.262 45c0 7.324-5.938 13.262-13.262 13.262-7.324 0-13.262-5.938-13.262-13.262 0-7.324 5.938-13.262 13.262-13.262 7.324 0 13.262 5.938 13.262 13.262zM45 27c-9.941 0-18 8.059-18 18s8.059 18 18 18 18-8.059 18-18-8.059-18-18-18z" android:strokeWidth="4"/>
|
||||
<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>
|
||||
|
||||
@@ -17,11 +17,32 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/format"/>
|
||||
<Spinner
|
||||
android:id="@+id/format"
|
||||
android:text="@string/content"/>
|
||||
<EditText
|
||||
tools:targetApi="o"
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start|top"
|
||||
android:typeface="monospace"
|
||||
android:imeOptions="flagNoExtractUi"
|
||||
android:inputType="textMultiLine"
|
||||
android:hint="@string/input_content_here"
|
||||
android:importantForAutofill="no"/>
|
||||
<CheckBox
|
||||
android:id="@+id/unescape"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/unescape"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/format"/>
|
||||
<Spinner
|
||||
style="@style/Spinner"
|
||||
android:id="@+id/format"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
<TextView
|
||||
android:id="@+id/error_correction_label"
|
||||
@@ -30,11 +51,9 @@
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/error_correction_level"/>
|
||||
<Spinner
|
||||
style="@style/Spinner"
|
||||
android:id="@+id/error_correction_level"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:entries="@array/error_correction_levels"/>
|
||||
android:layout_marginBottom="16dp"/>
|
||||
<TextView
|
||||
android:id="@+id/colors_label"
|
||||
android:layout_width="match_parent"
|
||||
@@ -42,47 +61,46 @@
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/colors"/>
|
||||
<Spinner
|
||||
style="@style/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"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/size"/>
|
||||
<TextView
|
||||
android:id="@+id/size_display"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:gravity="center"/>
|
||||
android:layout_marginBottom="8dp"/>
|
||||
<SeekBar
|
||||
style="@style/Widget.AppCompat.SeekBar.Discrete"
|
||||
android:id="@+id/size_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:progress="4"
|
||||
android:max="7"/>
|
||||
<TextView
|
||||
<LinearLayout
|
||||
android:id="@+id/margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/content"/>
|
||||
<EditText
|
||||
tools:targetApi="o"
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="start|top"
|
||||
android:typeface="monospace"
|
||||
android:imeOptions="flagNoExtractUi"
|
||||
android:inputType="textMultiLine"
|
||||
android:hint="@string/input_content_here"
|
||||
android:importantForAutofill="no"/>
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:id="@+id/margin_display"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
<SeekBar
|
||||
style="@style/Widget.AppCompat.SeekBar.Discrete"
|
||||
android:id="@+id/margin_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:max="32"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</de.markusfisch.android.binaryeye.widget.ConfinedScrollView>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
|
||||
@@ -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>
|
||||
@@ -13,7 +13,7 @@
|
||||
material:showAsAction="ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/pick_file"
|
||||
android:title="@string/pick_file"
|
||||
android:title="@string/pick_image_file"
|
||||
android:icon="@drawable/ic_action_pick_file"
|
||||
material:showAsAction="ifRoom"/>
|
||||
<item
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
android:title="@string/share"
|
||||
android:icon="@drawable/ic_action_share"
|
||||
material:showAsAction="ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/share_file"
|
||||
android:title="@string/share_file"
|
||||
android:icon="@drawable/ic_action_share"
|
||||
material:showAsAction="ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/create"
|
||||
android:title="@string/compose_barcode"
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:material="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/pick_file"
|
||||
android:title="@string/pick_file"
|
||||
android:icon="@drawable/ic_action_pick_file"
|
||||
material:showAsAction="ifRoom"/>
|
||||
</menu>
|
||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 6.9 KiB |
@@ -0,0 +1,197 @@
|
||||
<resources>
|
||||
<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">Ниско (~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 модули)</string>
|
||||
<string name="toggle_flash">Превключване на светкавицата</string>
|
||||
<string name="error_flash">Грешка при превключването на светкавицата</string>
|
||||
<string name="share">Сподели</string>
|
||||
<string name="share_file">Share as file</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">Отворете URL(Линк)</string>
|
||||
<string name="cannot_resolve_action">Няма приложение което може да отвори това</string>
|
||||
<string name="pick_search_engine">Изберете търсачка</string>
|
||||
<string name="format">Формат</string>
|
||||
<string name="size_width_by_height">Размер в пиксели: %1$d×%2$d</string>
|
||||
<string name="margin_size">Марж в пиксели: %1$d</string>
|
||||
<string name="input_content_here">Въведете съдържание тук</string>
|
||||
<string name="unescape">Разширете последователности за извеждане</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">Разпознаване на вертикални 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">Показване на данни в непрекъснат режим</string>
|
||||
<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 потвърждение</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>
|
||||
<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">Показване на пресъздаден баркод</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="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">Включване на препращането на сканиранията към даден 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">Отваряне във външен браузър</string>
|
||||
<string name="test_url">Тествайте URL(Линка)</string>
|
||||
<string name="send_scan_bluetooth">Препращане на сканиранията с Bluetooth</string>
|
||||
<string name="send_scan_bluetooth_summary">Активиране на препращане на сканирания към даден Bluetooth хост.</string>
|
||||
<string name="send_scan_bluetooth_host">Хост</string>
|
||||
<string name="no_bluetooth_hosts_paired">Няма сдвоени хостове</string>
|
||||
<string name="bluetooth_connect_fail">Неуспешно свързване с Bluetooth устройство.</string>
|
||||
<string name="bluetooth_send_fail">Неуспешно изпращане до Bluetooth устройство.</string>
|
||||
<string name="bluetooth_send_success">Успешно Bluetooth изпращане.</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">Свържи се към Wi-Fi</string>
|
||||
<string name="wifi_config_failed">Неуспешно конфигуриране на Wi-Fi</string>
|
||||
<string name="wifi_added">Wi-Fi успешно добавен</string>
|
||||
<string name="sms_send">Изпрати SMS</string>
|
||||
<string name="sms_error">Неуспешно изпращане на SMS</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">Превключване на свободното въртене</string>
|
||||
<string name="pick_file">Изберете файл</string>
|
||||
<string name="pick_image_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">Wi-Fi мрежа</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">Фаза 2 метод</string>
|
||||
<string name="network_suggestions">Предложения за интернет мрежа</string>
|
||||
<string name="remove_suggestion">Премахване на предложението</string>
|
||||
</resources>
|
||||
@@ -1,5 +1,4 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">এই অ্যাপ ক্যামেরা অনুমতি ছাড়া কোনো কাজের না। বিদায়।</string>
|
||||
<string name="camera_error">ক্যামেরা পাওয়া যাচ্ছে না, পরে চেষ্টা করো</string>
|
||||
<string name="scan_code">সংকেতের পাঠোদ্ধার</string>
|
||||
<string name="compose_barcode">বারকোড বানাও</string>
|
||||
@@ -28,10 +27,11 @@
|
||||
<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$d (%2$d modules)</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_file">Share as file</string>
|
||||
<string name="share_as">ভাগ করার মাধ্যম</string>
|
||||
<string name="copy_to_clipboard">ক্লিপবোর্ডে অনুলিপি</string>
|
||||
<string name="copied_to_clipboard">ক্লিপবোর্ডে অনুলিপিত</string>
|
||||
@@ -41,9 +41,10 @@
|
||||
<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="size_width_by_height">পিক্সেলে আকা:%1$d×%2$d</string>
|
||||
<string name="margin_size">Margin in pixels: %1$d</string>
|
||||
<string name="input_content_here">এখানে তথ্য দাও</string>
|
||||
<string name="unescape">Expand escape sequences</string>
|
||||
<string name="encode">সংকেতকরণ</string>
|
||||
<string name="error_no_content">তথ্য নেই</string>
|
||||
<string name="error_encoding_barcode">বারকোড বানানো যায়নি</string>
|
||||
@@ -81,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>
|
||||
@@ -116,6 +126,13 @@
|
||||
<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">পরীক্ষার জন্য ইউআরএল</string>
|
||||
<string name="send_scan_bluetooth">Forward scans with Bluetooth</string>
|
||||
<string name="send_scan_bluetooth_summary">Enable to forwards scans to a given Bluetooth host.</string>
|
||||
<string name="send_scan_bluetooth_host">Host</string>
|
||||
<string name="no_bluetooth_hosts_paired">No Hosts Paired</string>
|
||||
<string name="bluetooth_connect_fail">Could not connect to bluetooth device.</string>
|
||||
<string name="bluetooth_send_fail">Could not send to bluetooth device.</string>
|
||||
<string name="bluetooth_send_success">Successful bluetooth send.</string>
|
||||
<string name="really_remove_scan">আসলেই এটা মুছবে?</string>
|
||||
<string name="really_remove_all_scans">আসলেই সব মুছবে?</string>
|
||||
<string name="really_remove_selected_scans">আসলেই নির্বাচিত সব মুছবে?</string>
|
||||
@@ -158,7 +175,8 @@
|
||||
<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_file">Pick a file</string>
|
||||
<string name="pick_image_file">ছবি নাও</string>
|
||||
<string name="pick_code_to_scan">খুঁজার জন্য কোড নাও</string>
|
||||
<string name="shortcut_decode">বারকোড খুজো</string>
|
||||
<string name="shortcut_encode">বারকোড বানাও</string>
|
||||
@@ -174,4 +192,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>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">Bez oprávnění k fotoaparátu tato aplikace nemá smysl. Na viděnou.</string>
|
||||
<string name="camera_error">Nepodařilo se otevřít fotoaparát, prosím zkuste to znovu</string>
|
||||
<string name="scan_code">Naskenovat kód</string>
|
||||
<string name="compose_barcode">Vytvořit čárový kód</string>
|
||||
@@ -17,23 +16,24 @@
|
||||
<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="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="colors">Popředí a pozadí</string>
|
||||
<string name="colors_black_on_white">Černá na bílé</string>
|
||||
<string name="colors_white_on_black">Bílá na černé</string>
|
||||
<string name="colors_black_on_transparent">Černá na průhledné</string>
|
||||
<string name="colors_white_on_transparent">Bílá na průhledné</string>
|
||||
<string name="sequence_size">Velikost sekvence</string>
|
||||
<string name="sequence_index">Index sekvence</string>
|
||||
<string name="sequence_id">ID sekvence</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$d (%2$d modules)</string>
|
||||
<string name="toggle_flash">Zap/vyp blesk</string>
|
||||
<string name="barcode_version_number">Verze</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modulů)</string>
|
||||
<string name="toggle_flash">Přepnout blesk</string>
|
||||
<string name="error_flash">Zapnutí/vypnutí blesku selhalo</string>
|
||||
<string name="share">Sdílet</string>
|
||||
<string name="share_file">Sdílet jako soubor</string>
|
||||
<string name="share_as">Sdílet jako</string>
|
||||
<string name="copy_to_clipboard">Zkopírovat do schránky</string>
|
||||
<string name="copied_to_clipboard">Zkopírováno do schránky</string>
|
||||
@@ -43,14 +43,15 @@
|
||||
<string name="cannot_resolve_action">Nemáte aplikaci, která by toto uměla otevřít</string>
|
||||
<string name="pick_search_engine">Zvolte vyhledávač</string>
|
||||
<string name="format">Formát</string>
|
||||
<string name="size">Velikost v pixelech</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="size_width_by_height">Velikost v pixelech: %1$d×%2$d</string>
|
||||
<string name="margin_size">Okraje v pixelech: %1$d</string>
|
||||
<string name="input_content_here">Sem vložte obsah</string>
|
||||
<string name="unescape">Rozšířit escape sekvence</string>
|
||||
<string name="encode">ZAKÓDOVAT</string>
|
||||
<string name="error_no_content">Chybí obsah</string>
|
||||
<string name="error_encoding_barcode">Nepodařilo se vygenerovat čárový kód</string>
|
||||
<string name="view_barcode">Zobrazit čárový kód</string>
|
||||
<string name="info">Info</string>
|
||||
<string name="info">Informace</string>
|
||||
<string name="switch_camera">Přepnout kameru</string>
|
||||
<string name="bulk_mode">Skenovat nepřetržitě</string>
|
||||
<string name="bulk_mode_summary">Vždy začít v módu nepřetržitého skenování.</string>
|
||||
@@ -83,6 +84,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">Pípnout při rozpoznání</string>
|
||||
<string name="beep_summary">Povolte, pokud chcete pípnutí při rozpoznání kódu.</string>
|
||||
<string name="beep_tone">Tón pípnutí</string>
|
||||
<string name="tone_cdma_confirm">Potvrzení CDMA</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">Kladné potvrzení příjmu</string>
|
||||
<string name="tone_prop_beep">Obecné pípnutí</string>
|
||||
<string name="tone_prop_beep2">Dvojité obecné pípnutí</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>
|
||||
@@ -95,8 +105,8 @@
|
||||
<string name="show_meta_data_summary">Zobrazí další data o naskenovaném čárovém kódu.</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="show_recreation">Zobrazit zrekonstruovaný kód</string>
|
||||
<string name="show_recreation_summary">Zrekonstruovat a zobrazit čárový kód z přečteného obrazu, pokud je to možné.</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>
|
||||
@@ -106,18 +116,25 @@
|
||||
<string name="clear_network_suggestions_summary">Smazat všechny sítě, které byly navrženy touto aplikací.</string>
|
||||
<string name="really_remove_all_networks">Opravdu smazat všechny sítě?</string>
|
||||
<string name="clear_network_suggestions_success">Navrhované sítě smazány</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Nic k smazání</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Nic ke smazání</string>
|
||||
<string name="send_category">Předávání</string>
|
||||
<string name="send_scan_active">Předávat skeny</string>
|
||||
<string name="send_scan_active_summary">Zapnout předávání skenů na danou URL</string>
|
||||
<string name="send_scan_url">Posílat každý sken na URL</string>
|
||||
<string name="send_scan_type">Typ requestu pro každý sken</string>
|
||||
<string name="send_scan_type">Typ požadavku pro každý sken</string>
|
||||
<string name="send_type_get_add_content">GET a 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">Otevřít v prohlížeči</string>
|
||||
<string name="test_url">Otestovat URL</string>
|
||||
<string name="send_scan_bluetooth">Přesměrovat skeny přes Bluetooth</string>
|
||||
<string name="send_scan_bluetooth_summary">Skeny se přesměrují na daného hostitele Bluetooth.</string>
|
||||
<string name="send_scan_bluetooth_host">Hostitel</string>
|
||||
<string name="no_bluetooth_hosts_paired">Není spárován žádný hostitel</string>
|
||||
<string name="bluetooth_connect_fail">Nelze se připojit k zařízení Bluetooth.</string>
|
||||
<string name="bluetooth_send_fail">Nelze odesílat na zařízení Bluetooth.</string>
|
||||
<string name="bluetooth_send_success">Odesílání přes Bluetooth se zdařilo.</string>
|
||||
<string name="really_remove_scan">Opravdu odstranit sken?</string>
|
||||
<string name="really_remove_all_scans">Opravdu odstranit všechny skeny?</string>
|
||||
<string name="really_remove_selected_scans">Opravdu odstranit zvolené skeny?</string>
|
||||
@@ -135,9 +152,9 @@
|
||||
<string name="file_name">Název souboru</string>
|
||||
<string name="error_saving_file">Soubor se nepodařilo uložit</string>
|
||||
<string name="error_file_exists">Soubor již existuje</string>
|
||||
<string name="connect_to_wifi">Připojit k WiFi</string>
|
||||
<string name="wifi_config_failed">Nepodařilo se nastavit WiFi</string>
|
||||
<string name="wifi_added">WiFi přidána</string>
|
||||
<string name="connect_to_wifi">Připojit k Wi-Fi</string>
|
||||
<string name="wifi_config_failed">Nepodařilo se nastavit Wi-Fi</string>
|
||||
<string name="wifi_added">Wi-Fi přidána</string>
|
||||
<string name="sms_send">Poslat SMS</string>
|
||||
<string name="sms_error">Nepodařilo se poslat SMS</string>
|
||||
<string name="tel_dial">Vytočit číslo</string>
|
||||
@@ -159,8 +176,9 @@
|
||||
<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="toggle_free_rotation">Přepnout zámek natočení</string>
|
||||
<string name="pick_file">Vybrat soubor</string>
|
||||
<string name="pick_image_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>
|
||||
<string name="shortcut_encode">Vytvořit čárový kód</string>
|
||||
@@ -176,4 +194,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">Návrhy sítí</string>
|
||||
<string name="remove_suggestion">Odebrat návrh</string>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
<resources>
|
||||
<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_file">Share as file</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_width_by_height">Størrelse i pixels: %1$d×%2$d</string>
|
||||
<string name="margin_size">Margin in pixels: %1$d</string>
|
||||
<string name="input_content_here">Indtast indhold her</string>
|
||||
<string name="unescape">Expand escape sequences</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="send_scan_bluetooth">Forward scans with Bluetooth</string>
|
||||
<string name="send_scan_bluetooth_summary">Enable to forwards scans to a given Bluetooth host.</string>
|
||||
<string name="send_scan_bluetooth_host">Host</string>
|
||||
<string name="no_bluetooth_hosts_paired">No Hosts Paired</string>
|
||||
<string name="bluetooth_connect_fail">Could not connect to bluetooth device.</string>
|
||||
<string name="bluetooth_send_fail">Could not send to bluetooth device.</string>
|
||||
<string name="bluetooth_send_success">Successful bluetooth send.</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">Pick a file</string>
|
||||
<string name="pick_image_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>
|
||||
@@ -1,5 +1,4 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">Diese App kann ohne Kamerazugriff nicht funktionieren. Tschüss!</string>
|
||||
<string name="camera_error">Auf die Kamera kann nicht zugegriffen werden, bitte versuche es nochmal</string>
|
||||
<string name="scan_code">Code scannen</string>
|
||||
<string name="compose_barcode">Barcode erstellen</string>
|
||||
@@ -16,10 +15,10 @@
|
||||
<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="colors">Vor und Hintergrund</string>
|
||||
<string name="colors_black_on_white">Schwarz auf Weiss</string>
|
||||
<string name="colors_white_on_black">Weiss auf Schwarz</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">Weiss 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>
|
||||
@@ -28,10 +27,11 @@
|
||||
<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$d (%2$d Module)</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>
|
||||
<string name="share_file">Als Datei teilen</string>
|
||||
<string name="share_as">Teilen als?</string>
|
||||
<string name="copy_to_clipboard">In die Zwischenablage kopieren</string>
|
||||
<string name="copied_to_clipboard">Inhalt wurde in die Zwischenablage kopiert</string>
|
||||
@@ -41,9 +41,10 @@
|
||||
<string name="cannot_resolve_action">Keine App kann das öffnen</string>
|
||||
<string name="pick_search_engine">Suchmaschine auswählen</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="size">Größe in Pixel</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="size_width_by_height">Größe in Pixel: %1$d×%2$d</string>
|
||||
<string name="margin_size">Randgröße in Pixel: %1$d</string>
|
||||
<string name="input_content_here">Gib den Inhalt hier ein</string>
|
||||
<string name="unescape">Escape-Sequenzen interpretieren</string>
|
||||
<string name="encode">KODIEREN</string>
|
||||
<string name="error_no_content">Fehlender Inhalt</string>
|
||||
<string name="error_encoding_barcode">Barcode kann nicht generiert werden</string>
|
||||
@@ -79,8 +80,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>
|
||||
@@ -101,7 +111,7 @@
|
||||
<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>
|
||||
@@ -116,6 +126,13 @@
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">In externem Browser öffnen</string>
|
||||
<string name="test_url">Test URL</string>
|
||||
<string name="send_scan_bluetooth">Scans per Bluetooth weiterleiten</string>
|
||||
<string name="send_scan_bluetooth_summary">Aktivieren Sie diese Option, um Scans an das angegebene Bluetooth-Gerät weiterzuleiten.</string>
|
||||
<string name="send_scan_bluetooth_host">Gerät</string>
|
||||
<string name="no_bluetooth_hosts_paired">Keine Geräte verbunden</string>
|
||||
<string name="bluetooth_connect_fail">Es kann leider keine Verbindung zum Bluetooth-Gerät hergestellt werden</string>
|
||||
<string name="bluetooth_send_fail">Senden zum Bluetooth-Gerät fehlgeschlagen</string>
|
||||
<string name="bluetooth_send_success">Erfolgreich zum Bluetooth-Gerät gesendet</string>
|
||||
<string name="really_remove_scan">Code wirklich entfernen?</string>
|
||||
<string name="really_remove_all_scans">Alle Codes entfernen?</string>
|
||||
<string name="really_remove_selected_scans">Alle ausgewählten Codes entfernen?</string>
|
||||
@@ -158,7 +175,8 @@
|
||||
<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_file">Datei auswählen</string>
|
||||
<string name="pick_image_file">Bilddatei auswählen</string>
|
||||
<string name="pick_code_to_scan">Code im Bild auswählen</string>
|
||||
<string name="shortcut_decode">Barcode lesen</string>
|
||||
<string name="shortcut_encode">Barcode erstellen</string>
|
||||
@@ -174,4 +192,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,4 @@
|
||||
<resources>
|
||||
<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>
|
||||
@@ -28,10 +27,11 @@
|
||||
<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$d (%2$d modules)</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_file">Share as file</string>
|
||||
<string name="share_as">¿Compartir como?</string>
|
||||
<string name="copy_to_clipboard">Copiar al portapapeles</string>
|
||||
<string name="copied_to_clipboard">Copiado al portapapeles</string>
|
||||
@@ -41,9 +41,10 @@
|
||||
<string name="cannot_resolve_action">Ninguna aplicación puede abrir eso</string>
|
||||
<string name="pick_search_engine">Elija un motor de búsqueda</string>
|
||||
<string name="format">Formato</string>
|
||||
<string name="size">Tamaño en píxeles</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="size_width_by_height">Tamaño en píxeles: %1$d×%2$d</string>
|
||||
<string name="margin_size">Margin in pixels: %1$d</string>
|
||||
<string name="input_content_here">Introduzca el contenido aquí</string>
|
||||
<string name="unescape">Expand escape sequences</string>
|
||||
<string name="encode">CODIFICAR</string>
|
||||
<string name="error_no_content">Contenido no disponible</string>
|
||||
<string name="error_encoding_barcode">No se pudo generar el código de barras</string>
|
||||
@@ -81,6 +82,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>
|
||||
@@ -116,6 +126,13 @@
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Abrir en el navegador</string>
|
||||
<string name="test_url">URL de prueba</string>
|
||||
<string name="send_scan_bluetooth">Forward scans with Bluetooth</string>
|
||||
<string name="send_scan_bluetooth_summary">Enable to forwards scans to a given Bluetooth host.</string>
|
||||
<string name="send_scan_bluetooth_host">Host</string>
|
||||
<string name="no_bluetooth_hosts_paired">No Hosts Paired</string>
|
||||
<string name="bluetooth_connect_fail">Could not connect to bluetooth device.</string>
|
||||
<string name="bluetooth_send_fail">Could not send to bluetooth device.</string>
|
||||
<string name="bluetooth_send_success">Successful bluetooth send.</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>
|
||||
<string name="really_remove_selected_scans">¿Realmente desea borrar los escaneos seleccionados?</string>
|
||||
@@ -158,7 +175,8 @@
|
||||
<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_file">Pick a file</string>
|
||||
<string name="pick_image_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>
|
||||
<string name="shortcut_encode">Crear un código</string>
|
||||
@@ -174,4 +192,6 @@
|
||||
<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>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">این برنامه بدون دسترسی به دوربین هیچ کارایی ندارد. خدانگهدار.</string>
|
||||
<string name="camera_error">نمیتوان به دوربین دسترسی داشت، لطفاً دوباره تلاش کنید</string>
|
||||
<string name="scan_code">پویش کد</string>
|
||||
<string name="compose_barcode">ایجاد بارکد</string>
|
||||
@@ -28,10 +27,11 @@
|
||||
<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$d (%2$d modules)</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_file">Share as file</string>
|
||||
<string name="share_as">همرسانی به عنوان؟</string>
|
||||
<string name="copy_to_clipboard">رونوشت به تخهگیره</string>
|
||||
<string name="copied_to_clipboard">به تختهگیره رونوشت شد</string>
|
||||
@@ -41,9 +41,10 @@
|
||||
<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="size_width_by_height">اندازه به پیکسل: %1$d×%2$d</string>
|
||||
<string name="margin_size">Margin in pixels: %1$d</string>
|
||||
<string name="input_content_here">محتویات ورودی را اینجا بنویسید</string>
|
||||
<string name="unescape">Expand escape sequences</string>
|
||||
<string name="encode">رمزگذاری</string>
|
||||
<string name="error_no_content">محتویاتی نیست</string>
|
||||
<string name="error_encoding_barcode">بارکد نمیتواند ایجاد شود</string>
|
||||
@@ -81,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>
|
||||
@@ -116,6 +126,13 @@
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">گشودن در مرورگر خارجی</string>
|
||||
<string name="test_url">آزمودن نشانی</string>
|
||||
<string name="send_scan_bluetooth">Forward scans with Bluetooth</string>
|
||||
<string name="send_scan_bluetooth_summary">Enable to forwards scans to a given Bluetooth host.</string>
|
||||
<string name="send_scan_bluetooth_host">Host</string>
|
||||
<string name="no_bluetooth_hosts_paired">No Hosts Paired</string>
|
||||
<string name="bluetooth_connect_fail">Could not connect to bluetooth device.</string>
|
||||
<string name="bluetooth_send_fail">Could not send to bluetooth device.</string>
|
||||
<string name="bluetooth_send_success">Successful bluetooth send.</string>
|
||||
<string name="really_remove_scan">برای برداشتن پویش مطمئنید؟</string>
|
||||
<string name="really_remove_all_scans">برای برداشتن همهٔ پویشها مطمئنید؟</string>
|
||||
<string name="really_remove_selected_scans">برای برداشتن پویشهای برگزیده شده مطمئنید؟</string>
|
||||
@@ -158,7 +175,8 @@
|
||||
<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_file">Pick a file</string>
|
||||
<string name="pick_image_file">پروندهٔ تصویری را برگزینید</string>
|
||||
<string name="pick_code_to_scan">کدی را برای پویش برگزینید</string>
|
||||
<string name="shortcut_decode">پویش یک بارکد</string>
|
||||
<string name="shortcut_encode">ایجاد یک بارکد</string>
|
||||
@@ -174,4 +192,6 @@
|
||||
<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>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">Cette application ne peut pas fonctionner sans accès à la caméra. Au revoir.</string>
|
||||
<string name="camera_error">Impossible d\'accéder à la caméra, veuillez réessayer</string>
|
||||
<string name="scan_code">Scanner le code</string>
|
||||
<string name="scan_code">Scanner un code</string>
|
||||
<string name="compose_barcode">Créer un code-barres</string>
|
||||
<string name="decode_barcode">Décoder le code-barres</string>
|
||||
<string name="content">Contenu</string>
|
||||
@@ -16,43 +15,45 @@
|
||||
<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="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="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$d (%2$d modules)</string>
|
||||
<string name="toggle_flash">Activer le flash</string>
|
||||
<string name="error_flash">Erreur de basculement du flash</string>
|
||||
<string name="qr_version_and_modules">%1$s (%2$d modules)</string>
|
||||
<string name="toggle_flash">Activer/Désactiver le flash</string>
|
||||
<string name="error_flash">Erreur de changement d\'état du flash</string>
|
||||
<string name="share">Partager</string>
|
||||
<string name="share_as">Partager comme ?</string>
|
||||
<string name="share_file">Partager en tant que fichier</string>
|
||||
<string name="share_as">Partager en tant que ?</string>
|
||||
<string name="copy_to_clipboard">Copier dans le presse-papiers</string>
|
||||
<string name="copied_to_clipboard">Copié dans le presse-papiers</string>
|
||||
<string name="copy_password">Copier le mot de passe dans le presse-papiers</string>
|
||||
<string name="copied_password_to_clipboard">Mot de passe copié dans le presse-papiers</string>
|
||||
<string name="open_url">Ouvrir l\'url</string>
|
||||
<string name="open_url">Ouvrir l\'URL</string>
|
||||
<string name="cannot_resolve_action">Aucune application ne peut ouvrir cela</string>
|
||||
<string name="pick_search_engine">Choisir un moteur de recherche</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="size">Taille en pixels</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="input_content_here">Votre contenu ici</string>
|
||||
<string name="size_width_by_height">Taille en pixels : %1$d×%2$d</string>
|
||||
<string name="margin_size">Marge en pixels : %1$d</string>
|
||||
<string name="input_content_here">Insérer le contenu ici</string>
|
||||
<string name="unescape">Étendre les caractères d\'échappement</string>
|
||||
<string name="encode">ENCODER</string>
|
||||
<string name="error_no_content">Contenu manquant</string>
|
||||
<string name="error_encoding_barcode">Le code-barres ne peut pas être généré</string>
|
||||
<string name="view_barcode">Voir le code barre</string>
|
||||
<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">Démarre toujours en scan continu.</string>
|
||||
<string name="view_barcode">Voir le code-barres</string>
|
||||
<string name="info">Informations</string>
|
||||
<string name="switch_camera">Changer de caméra</string>
|
||||
<string name="bulk_mode">Scanner en continu</string>
|
||||
<string name="bulk_mode_summary">Toujours démarrer avec le scan en continu.</string>
|
||||
<string name="bulk_mode_delay">Délai entre les scans continus</string>
|
||||
<string name="restrict_format">Restreindre le format</string>
|
||||
<string name="remove_restriction">Supprimer la restriction</string>
|
||||
@@ -69,46 +70,55 @@
|
||||
<string name="locale_category">Langue</string>
|
||||
<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">Restreint le scan à une région personnalisée.</string>
|
||||
<string name="show_crop_handle">Afficher le contrôle du cadrage</string>
|
||||
<string name="show_crop_handle_summary">Restreindre le scan à une zone 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="zoom_by_swiping_summary">Balayer vers le haut ou vers le bas de l’écran pour contrôler le niveau de zoom de la caméra.</string>
|
||||
<string name="auto_rotate">Reconnaître les codes-barres 1D verticaux</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="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="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="try_harder_summary">Activer cette option pour les codes très difficiles à lire. Les performances seront affectées.</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">Fait vibrer l\'appareil lorsqu\'un code est reconnu.</string>
|
||||
<string name="vibrate_summary">Faire vibrer l\'appareil lorsqu\'un code est détecté.</string>
|
||||
<string name="beep">Biper à la détection</string>
|
||||
<string name="beep_summary">Émettre un son lorsqu\'un code est détecté.</string>
|
||||
<string name="beep_tone">Tonalité du signal sonore</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">Sauvegarde les codes reconnus sur votre appareil.</string>
|
||||
<string name="use_history_summary">Sauvegarder les codes reconnus sur votre appareil.</string>
|
||||
<string name="ignore_consecutive_duplicates">Ignorer les doublons</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">Ne sauvegarde pas les doublons dans l\'historique des scans.</string>
|
||||
<string name="ignore_consecutive_duplicates_summary">Ne pas sauvegarder les doublons dans l\'historique des scans.</string>
|
||||
<string name="open_immediately">Ouvrir immédiatement</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">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">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 le dump hexadécimal du contenu scanné.</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="open_immediately_summary">Ignorer l\'inspection et ouvrir le contenu immédiatement. Si cette option est activée, cela peut ouvrir un contenu nocif.</string>
|
||||
<string name="copy_immediately">Copier dans le presse-papiers</string>
|
||||
<string name="copy_immediately_summary">Copier automatiquement les contenus scannés dans le presse-papiers. Veuillez noter que d\'autres applications peuvent lire dans votre presse-papiers en arrière-plan.</string>
|
||||
<string name="show_meta_data">Afficher les métadonnées</string>
|
||||
<string name="show_meta_data_summary">Afficher des informations supplémentaires sur le code-barres scanné.</string>
|
||||
<string name="show_hex_dump">Afficher le dump hexadécimal</string>
|
||||
<string name="show_hex_dump_summary">Afficher le dump hexadécimal du contenu scanné.</string>
|
||||
<string name="show_recreation">Afficher le code-barres recréé</string>
|
||||
<string name="show_recreation_summary">Recréer et afficher, si possible, le code-barres à partir du contenu scanné.</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="close_automatically_summary">Revenir automatiquement sur l\'écran de scan après avoir copié ou partagé le contenu scanné.</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="open_with_url">Ouvrir les 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">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_summary">Supprimer toutes les suggestions de réseau précédemment fournies par cette application.</string>
|
||||
<string name="really_remove_all_networks">Vraiment supprimer tous les réseaux ?</string>
|
||||
<string name="clear_network_suggestions_success">Suggestion(s) de réseau(x) supprimée(s)</string>
|
||||
<string name="clear_network_suggestions_nothing_to_remove">Rien à supprimer</string>
|
||||
<string name="send_category">Transfert</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_active_summary">Transférer 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>
|
||||
@@ -117,12 +127,19 @@
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Ouvrir dans un navigateur externe</string>
|
||||
<string name="test_url">Tester l\'URL</string>
|
||||
<string name="send_scan_bluetooth">Partager les scans par Bluetooth</string>
|
||||
<string name="send_scan_bluetooth_summary">Partager les scans à un hôte Bluetooth donné.</string>
|
||||
<string name="send_scan_bluetooth_host">Hôte</string>
|
||||
<string name="no_bluetooth_hosts_paired">Aucun hôte appairé</string>
|
||||
<string name="bluetooth_connect_fail">Impossible de se connecter à l\'appareil Bluetooth.</string>
|
||||
<string name="bluetooth_send_fail">Impossible d\'envoyer à l\'appareil Bluetooth.</string>
|
||||
<string name="bluetooth_send_success">Envoi Bluetooth réussi.</string>
|
||||
<string name="really_remove_scan">Supprimer le scan ?</string>
|
||||
<string name="really_remove_all_scans">Supprimer tous les scans ?</string>
|
||||
<string name="really_remove_selected_scans">Supprimer les scans sélectionnés ?</string>
|
||||
<string name="clear_history">Effacer l\'historique</string>
|
||||
<string name="clear_history">Supprimer l\'historique</string>
|
||||
<string name="copy_scan">Copier le scan</string>
|
||||
<string name="edit_scan">Éditer l\'étiquette</string>
|
||||
<string name="edit_scan">Modifier l\'étiquette</string>
|
||||
<string name="remove_scan">Supprimer le scan</string>
|
||||
<string name="enter_name">Saisir un nom décrivant le scan</string>
|
||||
<string name="enter_name_hint">Nom du scan</string>
|
||||
@@ -134,9 +151,9 @@
|
||||
<string name="file_name">Nom du fichier</string>
|
||||
<string name="error_saving_file">Impossible de sauvegarder le fichier</string>
|
||||
<string name="error_file_exists">Fichier déjà existant</string>
|
||||
<string name="connect_to_wifi">Connecter au WiFi</string>
|
||||
<string name="wifi_config_failed">Impossible de configurer le WiFi</string>
|
||||
<string name="wifi_added">WiFi ajouté</string>
|
||||
<string name="connect_to_wifi">Connecter au Wi-Fi</string>
|
||||
<string name="wifi_config_failed">Impossible de configurer le Wi-Fi</string>
|
||||
<string name="wifi_added">Wi-Fi ajouté</string>
|
||||
<string name="sms_send">Envoyer SMS</string>
|
||||
<string name="sms_error">Impossible d\'envoyer le SMS</string>
|
||||
<string name="tel_dial">Numéro de téléphone</string>
|
||||
@@ -147,20 +164,21 @@
|
||||
<string name="vcard_failed">Impossible d\'ajouter aux contacts</string>
|
||||
<string name="vevent_add">Ajouter à l\'agenda</string>
|
||||
<string name="vevent_failed">Impossible d\'ajouter à l\'agenda</string>
|
||||
<string name="otpauth_add">Ajouter 2FA</string>
|
||||
<string name="otpauth_add">Ajouter l\'authentification à deux facteurs</string>
|
||||
<string name="search_web">Rechercher sur internet</string>
|
||||
<string name="search_scan">Rechercher un scan</string>
|
||||
<string name="export_to_file">Exporter comme fichier</string>
|
||||
<string name="export_as">Exporter comme ?</string>
|
||||
<string name="export_to_file">Exporter en tant que fichier</string>
|
||||
<string name="export_as">Exporter en tant que ?</string>
|
||||
<string name="export_csv_comma">CSV avec virgules</string>
|
||||
<string name="export_csv_semicolon">CSV avec points-virgules</string>
|
||||
<string name="export_json">Exporter comme JSON</string>
|
||||
<string name="export_json">Exporter en tant que JSON</string>
|
||||
<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">Toggle free rotation</string>
|
||||
<string name="pick_file">Choisir un fichier image</string>
|
||||
<string name="pick_code_to_scan">Choisissez le code à scanner</string>
|
||||
<string name="toggle_free_rotation">Activer la rotation libre</string>
|
||||
<string name="pick_file">Choisir un fichier</string>
|
||||
<string name="pick_image_file">Choisir un fichier image</string>
|
||||
<string name="pick_code_to_scan">Choisir le code à scanner</string>
|
||||
<string name="shortcut_decode">Scanner un code-barres</string>
|
||||
<string name="shortcut_encode">Créer un code-barres</string>
|
||||
<string name="shortcut_preferences">Réglages</string>
|
||||
@@ -175,4 +193,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">Suggestions de réseaux</string>
|
||||
<string name="remove_suggestion">Supprimer les suggestions</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">Ennek az alkalmazásnak nincs semmi értelme kamera-hozzáférés nélkül. Viszlát!</string>
|
||||
<string name="camera_error">Nem lehet hozzáférni a kamerához, próbálja meg újra</string>
|
||||
<string name="scan_code">Kód beolvasása</string>
|
||||
<string name="compose_barcode">Vonalkód létrehozása</string>
|
||||
@@ -28,10 +27,11 @@
|
||||
<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$d (%2$d modules)</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>
|
||||
<string name="share_file">Share as file</string>
|
||||
<string name="share_as">Megosztja másként?</string>
|
||||
<string name="copy_to_clipboard">Másolás a vágólapra</string>
|
||||
<string name="copied_to_clipboard">Vágólapra helyezés</string>
|
||||
@@ -41,9 +41,10 @@
|
||||
<string name="cannot_resolve_action">Nincs alkalmazás, amely meg tudná nyitni azt</string>
|
||||
<string name="pick_search_engine">Válasszon keresőmotort</string>
|
||||
<string name="format">Formátum</string>
|
||||
<string name="size">Méret képpontban</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="size_width_by_height">Méret képpontban: %1$d×%2$d</string>
|
||||
<string name="margin_size">Margin in pixels: %1$d</string>
|
||||
<string name="input_content_here">Itt adja meg a tartalmat</string>
|
||||
<string name="unescape">Expand escape sequences</string>
|
||||
<string name="encode">KÓDOLÁS</string>
|
||||
<string name="error_no_content">Hiányzó tartalom</string>
|
||||
<string name="error_encoding_barcode">A vonalkódot nem lehet előállítani</string>
|
||||
@@ -81,6 +82,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>
|
||||
@@ -116,6 +126,13 @@
|
||||
<string name="send_type_post_json">POST application/json</string>
|
||||
<string name="send_type_external_browser">Megnyitás külső böngészőben</string>
|
||||
<string name="test_url">Teszt URL</string>
|
||||
<string name="send_scan_bluetooth">Forward scans with Bluetooth</string>
|
||||
<string name="send_scan_bluetooth_summary">Enable to forwards scans to a given Bluetooth host.</string>
|
||||
<string name="send_scan_bluetooth_host">Host</string>
|
||||
<string name="no_bluetooth_hosts_paired">No Hosts Paired</string>
|
||||
<string name="bluetooth_connect_fail">Could not connect to bluetooth device.</string>
|
||||
<string name="bluetooth_send_fail">Could not send to bluetooth device.</string>
|
||||
<string name="bluetooth_send_success">Successful bluetooth send.</string>
|
||||
<string name="really_remove_scan">Valóban eltávolítja a beolvasást?</string>
|
||||
<string name="really_remove_all_scans">Valóban eltávolítja az összes beolvasását?</string>
|
||||
<string name="really_remove_selected_scans">Valóban eltávolítja a kijelölt beolvasásokat?</string>
|
||||
@@ -158,7 +175,8 @@
|
||||
<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_file">Pick a file</string>
|
||||
<string name="pick_image_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>
|
||||
<string name="shortcut_encode">Vonalkód létrehozása</string>
|
||||
@@ -174,4 +192,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>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<resources>
|
||||
<string name="no_camera_no_fun">Aplikasi tidak akan bisa bekerja tanpa akses kamera. Selamat tinggal.</string>
|
||||
<string name="camera_error">Tidak bisa mengakses kamera, silakan coba lagi</string>
|
||||
<string name="scan_code">Pindai kode</string>
|
||||
<string name="compose_barcode">Buat barcode</string>
|
||||
@@ -14,23 +13,24 @@
|
||||
<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="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="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">Version</string>
|
||||
<string name="qr_version_and_modules">%1$d (%2$d modules)</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_file">Share as file</string>
|
||||
<string name="share_as">Bagikan sebagai?</string>
|
||||
<string name="copy_to_clipboard">Salin ke clipboard</string>
|
||||
<string name="copied_to_clipboard">Disalin ke clipboard</string>
|
||||
@@ -40,9 +40,10 @@
|
||||
<string name="cannot_resolve_action">Tidak ada aplikasi yang bisa membukanya</string>
|
||||
<string name="pick_search_engine">Pilih mesin pencari</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="size">Ukuran dalam piksel</string>
|
||||
<string name="width_by_height">%1$d×%2$d</string>
|
||||
<string name="size_width_by_height">Ukuran dalam piksel: %1$d×%2$d</string>
|
||||
<string name="margin_size">Margin in pixels: %1$d</string>
|
||||
<string name="input_content_here">Masukkan konten di sini</string>
|
||||
<string name="unescape">Expand escape sequences</string>
|
||||
<string name="encode">ENKODE</string>
|
||||
<string name="error_no_content">Tidak ada konten</string>
|
||||
<string name="error_encoding_barcode">Barcode tidak bisa dibuat</string>
|
||||
@@ -50,16 +51,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>
|
||||
@@ -69,17 +70,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>
|
||||
@@ -92,29 +102,36 @@
|
||||
<string name="show_meta_data_summary">Tampilkan data tambahan tentang barcode yang dipindai.</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="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="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="send_scan_bluetooth">Forward scans with Bluetooth</string>
|
||||
<string name="send_scan_bluetooth_summary">Enable to forwards scans to a given Bluetooth host.</string>
|
||||
<string name="send_scan_bluetooth_host">Host</string>
|
||||
<string name="no_bluetooth_hosts_paired">No Hosts Paired</string>
|
||||
<string name="bluetooth_connect_fail">Could not connect to bluetooth device.</string>
|
||||
<string name="bluetooth_send_fail">Could not send to bluetooth device.</string>
|
||||
<string name="bluetooth_send_success">Successful bluetooth send.</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>
|
||||
@@ -156,21 +173,24 @@
|
||||
<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">Toggle free rotation</string>
|
||||
<string name="pick_file">Pilih berkas gambar</string>
|
||||
<string name="toggle_free_rotation">Nyala/matikan rotasi bebas</string>
|
||||
<string name="pick_file">Pick a file</string>
|
||||
<string name="pick_image_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,5 @@
|
||||
<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,40 +9,42 @@
|
||||
<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 degli 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">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">Dimensione della sequenza</string>
|
||||
<string name="sequence_index">Indice della sequenza</string>
|
||||
<string name="sequence_id">ID della sequenza</string>
|
||||
<string name="gtin_issue_number">Numero di edizione</string>
|
||||
<string name="gtin_country">Probabile Paese di fabbricazione</string>
|
||||
<string name="error_correction_level">Livello correzione errori</string>
|
||||
<string name="error_correction_level_l" formatted="false">Basso (correzione ~7%)</string>
|
||||
<string name="error_correction_level_m" formatted="false">Medio (correzione ~15%)</string>
|
||||
<string name="error_correction_level_q" formatted="false">Quartile (correzione ~25%)</string>
|
||||
<string name="error_correction_level_h" formatted="false">Alto (correzione ~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$d (%2$d moduli)</string>
|
||||
<string name="toggle_flash">Attiva/Disattiva flash</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_file">Share as file</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="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="width_by_height">%1$d×%2$d</string>
|
||||
<string name="input_content_here">Inserisci il contenuto qui</string>
|
||||
<string name="size_width_by_height">Dimensioni (pixel): %1$d×%2$d</string>
|
||||
<string name="margin_size">Margin in pixels: %1$d</string>
|
||||
<string name="input_content_here">Inserisci qui il contenuto</string>
|
||||
<string name="unescape">Espandi sequenze escape</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>
|
||||
@@ -67,42 +68,51 @@
|
||||
<string name="content_category">Contenuto</string>
|
||||
<string name="locale_category">Lingua</string>
|
||||
<string name="custom_locale">Lingua personalizzata</string>
|
||||
<string name="follow_system_settings">Segui le impostazioni di sistema</string>
|
||||
<string name="show_crop_handle">Mostra riquadro di limite</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">Formati di codici a barre</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="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">Mostra i dati in modalità continua</string>
|
||||
<string name="show_toast_in_bulk_mode_summary">Mostra brevemente i dati scansionati durante la scansione continua.</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 visualizza 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="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">Mostra metadati</string>
|
||||
<string name="show_meta_data_summary">Mostra dati aggiuntivi sul codice a barre scansionato.</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="show_recreation">Mostra il codice a barre ricreato</string>
|
||||
<string name="show_recreation_summary">Ricrea e mostra il codice a barre dal contenuto letto, se possibile.</string>
|
||||
<string name="close_automatically">Vai indietro dopo la Copia/Condivisione</string>
|
||||
<string name="close_automatically_summary">Ritorna automaticamente alla schermata di scansione dopo aver copiato o condiviso i contenuti letti.</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">Cancella suggerimenti di rete</string>
|
||||
<string name="clear_network_suggestions_summary">Rimuovi tutti i suggerimenti di rete precedentemente forniti da questa app.</string>
|
||||
<string name="really_remove_all_networks">Rimuovere davvero tutte le reti?</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>
|
||||
@@ -110,27 +120,34 @@
|
||||
<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">GET e aggiungi il contenuto</string>
|
||||
<string name="send_type_get_query_string">GET con stringa completa della 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">Apri nel browser esterno</string>
|
||||
<string name="test_url">Prova 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_scan_bluetooth">Inoltra scansioni con Bluetooth</string>
|
||||
<string name="send_scan_bluetooth_summary">Abilita per inoltrare le scansioni ad un determinato host Bluetooth.</string>
|
||||
<string name="send_scan_bluetooth_host">Host</string>
|
||||
<string name="no_bluetooth_hosts_paired">Nessun host accoppiato</string>
|
||||
<string name="bluetooth_connect_fail">Impossibile connettersi al dispositivo Bluetooth.</string>
|
||||
<string name="bluetooth_send_fail">Impossibile inviare al dispositivo Bluetooth.</string>
|
||||
<string name="bluetooth_send_success">Invio via Bluetooth riuscito.</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 nei Download?</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>
|
||||
@@ -150,22 +167,23 @@
|
||||
<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">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">Toggle free rotation</string>
|
||||
<string name="pick_file">Scegli file immagine</string>
|
||||
<string name="toggle_free_rotation">Abilita/disabilita rotazione libera</string>
|
||||
<string name="pick_file">Pick a file</string>
|
||||
<string name="pick_image_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">Tipo</string>
|
||||
<string name="wifi_network">Rete Wi-Fi</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>
|
||||
@@ -173,5 +191,7 @@
|
||||
<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 di fase 2</string>
|
||||
<string name="wifi_phase2">Metodo fase 2</string>
|
||||
<string name="network_suggestions">Suggerimenti rete</string>
|
||||
<string name="remove_suggestion">Elimina suggerimento</string>
|
||||
</resources>
|
||||
|
||||