]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/commitdiff
Initial commit
authorMichal Horn <hornmich@fel.cvut.cz>
Fri, 6 Feb 2015 16:07:12 +0000 (17:07 +0100)
committerMichal Horn <hornmich@fel.cvut.cz>
Fri, 6 Feb 2015 16:07:12 +0000 (17:07 +0100)
Add project BarCodeScanner for scaning 1D and 2D codes on Cell phones and Google Glass.
Add project QRScanner for invoking code scanning and later user interaction and PDF viewing.
Add documents provided by Skoda Auto. Those documents will be shown by the QR Demo.

246 files changed:
BarCodeScanner/.gitignore [new file with mode: 0644]
BarCodeScanner/.idea/.name [new file with mode: 0644]
BarCodeScanner/.idea/compiler.xml [new file with mode: 0644]
BarCodeScanner/.idea/copyright/profiles_settings.xml [new file with mode: 0644]
BarCodeScanner/.idea/encodings.xml [new file with mode: 0644]
BarCodeScanner/.idea/gradle.xml [new file with mode: 0644]
BarCodeScanner/.idea/misc.xml [new file with mode: 0644]
BarCodeScanner/.idea/modules.xml [new file with mode: 0644]
BarCodeScanner/.idea/scopes/scope_settings.xml [new file with mode: 0644]
BarCodeScanner/.idea/vcs.xml [new file with mode: 0644]
BarCodeScanner/BarCodeScanner.iml [new file with mode: 0644]
BarCodeScanner/build.gradle [new file with mode: 0644]
BarCodeScanner/glass/.gitignore [new file with mode: 0644]
BarCodeScanner/glass/build.gradle [new file with mode: 0644]
BarCodeScanner/glass/glass.iml [new file with mode: 0644]
BarCodeScanner/glass/libs/android-core-3.1.1-SNAPSHOT.jar [new file with mode: 0644]
BarCodeScanner/glass/libs/core-3.1.1-SNAPSHOT.jar [new file with mode: 0644]
BarCodeScanner/glass/proguard-rules.pro [new file with mode: 0644]
BarCodeScanner/glass/src/androidTest/java/cz/cvut/fel/dce/barcodescanner/ApplicationTest.java [new file with mode: 0644]
BarCodeScanner/glass/src/main/AndroidManifest.xml [new file with mode: 0644]
BarCodeScanner/glass/src/main/java/cz/cvut/fel/dce/barcodescanner/CameraConfigurationManager.java [new file with mode: 0644]
BarCodeScanner/glass/src/main/java/cz/cvut/fel/dce/barcodescanner/CaptureActivity.java [new file with mode: 0644]
BarCodeScanner/glass/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeRunnable.java [new file with mode: 0644]
BarCodeScanner/glass/src/main/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
BarCodeScanner/glass/src/main/res/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
BarCodeScanner/glass/src/main/res/drawable-xhdpi/ic_launcher.png [new file with mode: 0644]
BarCodeScanner/glass/src/main/res/drawable-xxhdpi/ic_launcher.png [new file with mode: 0644]
BarCodeScanner/glass/src/main/res/layout/capture.xml [new file with mode: 0644]
BarCodeScanner/glass/src/main/res/values/colors.xml [new file with mode: 0644]
BarCodeScanner/glass/src/main/res/values/ids.xml [new file with mode: 0644]
BarCodeScanner/glass/src/main/res/values/strings.xml [new file with mode: 0644]
BarCodeScanner/glass/src/main/res/values/styles.xml [new file with mode: 0644]
BarCodeScanner/glass/src/main/res/xml/barcode_scanner_show.xml [new file with mode: 0644]
BarCodeScanner/gradle.properties [new file with mode: 0644]
BarCodeScanner/gradle/wrapper/gradle-wrapper.jar [new file with mode: 0644]
BarCodeScanner/gradle/wrapper/gradle-wrapper.properties [new file with mode: 0644]
BarCodeScanner/gradlew [new file with mode: 0755]
BarCodeScanner/gradlew.bat [new file with mode: 0644]
BarCodeScanner/mobile/.gitignore [new file with mode: 0644]
BarCodeScanner/mobile/build.gradle [new file with mode: 0644]
BarCodeScanner/mobile/libs/android-core-3.1.1-SNAPSHOT.jar [new file with mode: 0644]
BarCodeScanner/mobile/libs/core-3.1.1-SNAPSHOT.jar [new file with mode: 0644]
BarCodeScanner/mobile/mobile.iml [new file with mode: 0644]
BarCodeScanner/mobile/proguard-rules.pro [new file with mode: 0644]
BarCodeScanner/mobile/src/androidTest/java/cz/cvut/fel/dce/barcodescanner/ApplicationTest.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/AndroidManifest.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/AmbientLightManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/BeepManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/CaptureActivity.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/CaptureActivityHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/Contents.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeFormatManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeHintManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeThread.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/FinishListener.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/HelpActivity.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/HttpHelper.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/InactivityTimer.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/IntentSource.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/Intents.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/LocaleManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/PreferencesActivity.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/PreferencesFragment.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/ScanFromWebPageManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/ViewfinderResultPointCallback.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/ViewfinderView.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/BrowseBookListener.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsActivity.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsAdapter.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsListItem.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsResult.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/AutoFocusManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/CameraConfigurationManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/CameraManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/FrontLightMode.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/PreviewCallback.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/open/OpenCameraInterface.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/clipboard/ClipboardInterface.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/ContactEncoder.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/EncodeActivity.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/Formatter.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/MECARDContactEncoder.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/QRCodeEncoder.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/VCardContactEncoder.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/VCardFieldFormatter.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/VCardTelDisplayFormatter.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/DBHelper.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryActivity.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryItem.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryItemAdapter.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/AddressBookResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/CalendarResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/EmailAddressResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/GeoResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ISBNResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ProductResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ResultButtonListener.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ResultHandlerFactory.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/SMSResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/TelResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/TextResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/URIResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/WifiResultHandler.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/BookResultInfoRetriever.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/ProductResultInfoRetriever.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/SupplementalInfoRetriever.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/TitleRetriever.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/URIResultInfoRetriever.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/AppInfo.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/AppPickerActivity.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/BookmarkAdapter.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/BookmarkPickerActivity.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/LoadPackagesAsyncTask.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/ShareActivity.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/wifi/NetworkType.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/wifi/WifiConfigManager.java [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/drawable-hdpi/launcher_icon.png [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/drawable-xhdpi/launcher_icon.png [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/drawable-xxhdpi/launcher_icon.png [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/drawable/launcher_icon.png [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/drawable/share_via_barcode.png [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout-land/encode.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout-land/share.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout-ldpi/capture.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout/app_picker_list_item.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout/bookmark_picker_list_item.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout/capture.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout/encode.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout/help.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout/history_list_item.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout/search_book_contents.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout/search_book_contents_header.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout/search_book_contents_list_item.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/layout/share.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/menu/capture.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/menu/encode.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/menu/history.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/raw/beep.ogg [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-ar/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-bg/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-ca/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-cs/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-da/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-de/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-el/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-es/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-eu/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-fi/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-fr/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-he/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-hi/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-hu/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-id/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-it/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-iw/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-ja/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-ko/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-nl/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-pl/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-pt/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-ro/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-ru/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-sk/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-sl/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-sv/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-th/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-tr/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-uk/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-zh-rCN/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-zh-rHK/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values-zh-rTW/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values/arrays.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values/colors.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values/dimens.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values/ids.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values/strings.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values/styles.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/values/themes.xml [new file with mode: 0644]
BarCodeScanner/mobile/src/main/res/xml/preferences.xml [new file with mode: 0644]
BarCodeScanner/settings.gradle [new file with mode: 0644]
QRScanner/.gitignore [new file with mode: 0644]
QRScanner/.idea/.name [new file with mode: 0644]
QRScanner/.idea/compiler.xml [new file with mode: 0644]
QRScanner/.idea/copyright/profiles_settings.xml [new file with mode: 0644]
QRScanner/.idea/encodings.xml [new file with mode: 0644]
QRScanner/.idea/gradle.xml [new file with mode: 0644]
QRScanner/.idea/misc.xml [new file with mode: 0644]
QRScanner/.idea/modules.xml [new file with mode: 0644]
QRScanner/.idea/scopes/scope_settings.xml [new file with mode: 0644]
QRScanner/.idea/vcs.xml [new file with mode: 0644]
QRScanner/QRScanner.iml [new file with mode: 0644]
QRScanner/build.gradle [new file with mode: 0644]
QRScanner/glass/.gitignore [new file with mode: 0644]
QRScanner/glass/build.gradle [new file with mode: 0644]
QRScanner/glass/glass.iml [new file with mode: 0644]
QRScanner/glass/proguard-rules.pro [new file with mode: 0644]
QRScanner/glass/src/androidTest/java/cz/cvut/fel/dce/qrscanner/ApplicationTest.java [new file with mode: 0644]
QRScanner/glass/src/main/AndroidManifest.xml [new file with mode: 0644]
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/MainActivity.java [new file with mode: 0644]
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentIntegrator.java [new file with mode: 0644]
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentResult.java [new file with mode: 0644]
QRScanner/glass/src/main/res/drawable-hdpi/ic_glass_logo.png [new file with mode: 0644]
QRScanner/glass/src/main/res/drawable-hdpi/ic_stop.png [new file with mode: 0644]
QRScanner/glass/src/main/res/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
QRScanner/glass/src/main/res/drawable-xhdpi/ic_launcher.png [new file with mode: 0644]
QRScanner/glass/src/main/res/drawable-xxhdpi/ic_launcher.png [new file with mode: 0644]
QRScanner/glass/src/main/res/values/strings.xml [new file with mode: 0644]
QRScanner/glass/src/main/res/values/styles.xml [new file with mode: 0644]
QRScanner/glass/src/main/res/xml/voice_trigger.xml [new file with mode: 0644]
QRScanner/gradle.properties [new file with mode: 0644]
QRScanner/gradle/wrapper/gradle-wrapper.jar [new file with mode: 0644]
QRScanner/gradle/wrapper/gradle-wrapper.properties [new file with mode: 0644]
QRScanner/gradlew [new file with mode: 0755]
QRScanner/gradlew.bat [new file with mode: 0644]
QRScanner/mobile/.gitignore [new file with mode: 0644]
QRScanner/mobile/build.gradle [new file with mode: 0644]
QRScanner/mobile/mobile.iml [new file with mode: 0644]
QRScanner/mobile/proguard-rules.pro [new file with mode: 0644]
QRScanner/mobile/src/androidTest/java/cz/cvut/fel/dce/qrscanner/ApplicationTest.java [new file with mode: 0644]
QRScanner/mobile/src/main/AndroidManifest.xml [new file with mode: 0644]
QRScanner/mobile/src/main/java/cz/cvut/fel/dce/qrscanner/MainActivity.java [new file with mode: 0644]
QRScanner/mobile/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentIntegrator.java [new file with mode: 0644]
QRScanner/mobile/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentResult.java [new file with mode: 0644]
QRScanner/mobile/src/main/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
QRScanner/mobile/src/main/res/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
QRScanner/mobile/src/main/res/drawable-xhdpi/ic_launcher.png [new file with mode: 0644]
QRScanner/mobile/src/main/res/drawable-xxhdpi/ic_launcher.png [new file with mode: 0644]
QRScanner/mobile/src/main/res/layout/activity_main.xml [new file with mode: 0644]
QRScanner/mobile/src/main/res/menu/menu_main.xml [new file with mode: 0644]
QRScanner/mobile/src/main/res/values-w820dp/dimens.xml [new file with mode: 0644]
QRScanner/mobile/src/main/res/values/dimens.xml [new file with mode: 0644]
QRScanner/mobile/src/main/res/values/strings.xml [new file with mode: 0644]
QRScanner/mobile/src/main/res/values/styles.xml [new file with mode: 0644]
QRScanner/settings.gradle [new file with mode: 0644]
documents/1K0947105N_Abbildung.pdf [new file with mode: 0644]
documents/1K0947105N_Angaben.pdf [new file with mode: 0644]
documents/3T0947105M_Abbildung.pdf [new file with mode: 0644]
documents/3T0947105M_Angaben.pdf [new file with mode: 0644]
documents/5E0947105E_Abbildung.pdf [new file with mode: 0644]
documents/5E0947105E_Angaben.pdf [new file with mode: 0644]
documents/Arbeitseinleitung.pdf [new file with mode: 0644]
documents/Bild_Arbeitseinleitung.pdf [new file with mode: 0644]
documents/Werkstatt_Einleitung.pdf [new file with mode: 0644]

diff --git a/BarCodeScanner/.gitignore b/BarCodeScanner/.gitignore
new file mode 100644 (file)
index 0000000..afbdab3
--- /dev/null
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/BarCodeScanner/.idea/.name b/BarCodeScanner/.idea/.name
new file mode 100644 (file)
index 0000000..9910b01
--- /dev/null
@@ -0,0 +1 @@
+BarCodeScanner
\ No newline at end of file
diff --git a/BarCodeScanner/.idea/compiler.xml b/BarCodeScanner/.idea/compiler.xml
new file mode 100644 (file)
index 0000000..217af47
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <resourceExtensions />
+    <wildcardResourcePatterns>
+      <entry name="!?*.java" />
+      <entry name="!?*.form" />
+      <entry name="!?*.class" />
+      <entry name="!?*.groovy" />
+      <entry name="!?*.scala" />
+      <entry name="!?*.flex" />
+      <entry name="!?*.kt" />
+      <entry name="!?*.clj" />
+    </wildcardResourcePatterns>
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="false">
+        <processorPath useClasspath="true" />
+      </profile>
+    </annotationProcessing>
+  </component>
+</project>
+
diff --git a/BarCodeScanner/.idea/copyright/profiles_settings.xml b/BarCodeScanner/.idea/copyright/profiles_settings.xml
new file mode 100644 (file)
index 0000000..e7bedf3
--- /dev/null
@@ -0,0 +1,3 @@
+<component name="CopyrightManager">
+  <settings default="" />
+</component>
\ No newline at end of file
diff --git a/BarCodeScanner/.idea/encodings.xml b/BarCodeScanner/.idea/encodings.xml
new file mode 100644 (file)
index 0000000..e206d70
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+</project>
+
diff --git a/BarCodeScanner/.idea/gradle.xml b/BarCodeScanner/.idea/gradle.xml
new file mode 100644 (file)
index 0000000..a577ae6
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/glass" />
+            <option value="$PROJECT_DIR$/mobile" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>
+
diff --git a/BarCodeScanner/.idea/misc.xml b/BarCodeScanner/.idea/misc.xml
new file mode 100644 (file)
index 0000000..a362c64
--- /dev/null
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="DaemonCodeAnalyzer">
+    <disable_hints />
+  </component>
+  <component name="EntryPointsManager">
+    <entry_points version="2.0" />
+  </component>
+  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+    <OptionsSetting value="true" id="Add" />
+    <OptionsSetting value="true" id="Remove" />
+    <OptionsSetting value="true" id="Checkout" />
+    <OptionsSetting value="true" id="Update" />
+    <OptionsSetting value="true" id="Status" />
+    <OptionsSetting value="true" id="Edit" />
+    <ConfirmationsSetting value="0" id="Add" />
+    <ConfirmationsSetting value="0" id="Remove" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="RunManager">
+    <configuration default="true" type="Remote" factoryName="Remote">
+      <option name="USE_SOCKET_TRANSPORT" value="true" />
+      <option name="SERVER_MODE" value="false" />
+      <option name="SHMEM_ADDRESS" value="javadebug" />
+      <option name="HOST" value="localhost" />
+      <option name="PORT" value="5005" />
+      <method />
+    </configuration>
+    <configuration default="true" type="TestNG" factoryName="TestNG">
+      <module name="" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="SUITE_NAME" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="GROUP_NAME" />
+      <option name="TEST_OBJECT" value="CLASS" />
+      <option name="VM_PARAMETERS" value="-ea" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="OUTPUT_DIRECTORY" />
+      <option name="ANNOTATION_TYPE" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="moduleWithDependencies" />
+      </option>
+      <option name="USE_DEFAULT_REPORTERS" value="false" />
+      <option name="PROPERTIES_FILE" />
+      <envs />
+      <properties />
+      <listeners />
+      <method />
+    </configuration>
+    <configuration default="true" type="Application" factoryName="Application">
+      <option name="MAIN_CLASS_NAME" />
+      <option name="VM_PARAMETERS" />
+      <option name="PROGRAM_PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="ENABLE_SWING_INSPECTOR" value="false" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <module name="" />
+      <envs />
+      <method />
+    </configuration>
+    <configuration default="true" type="JUnit" factoryName="JUnit">
+      <module name="" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="TEST_OBJECT" value="class" />
+      <option name="VM_PARAMETERS" value="-ea" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="moduleWithDependencies" />
+      </option>
+      <envs />
+      <patterns />
+      <method />
+    </configuration>
+    <list size="0" />
+    <configuration name="&lt;template&gt;" type="Applet" default="true" selected="false">
+      <option name="MAIN_CLASS_NAME" />
+      <option name="HTML_FILE_NAME" />
+      <option name="HTML_USED" value="false" />
+      <option name="WIDTH" value="400" />
+      <option name="HEIGHT" value="300" />
+      <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
+      <option name="VM_PARAMETERS" />
+    </configuration>
+    <configuration name="&lt;template&gt;" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" default="true" selected="false">
+      <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
+    </configuration>
+    <configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
+      <Host>localhost</Host>
+      <Port>5050</Port>
+    </configuration>
+  </component>
+  <component name="masterDetails">
+    <states>
+      <state key="ProjectJDKs.UI">
+        <settings>
+          <last-edited>1.8</last-edited>
+          <splitter-proportions>
+            <option name="proportions">
+              <list>
+                <option value="0.2" />
+              </list>
+            </option>
+          </splitter-proportions>
+        </settings>
+      </state>
+    </states>
+  </component>
+</project>
+
diff --git a/BarCodeScanner/.idea/modules.xml b/BarCodeScanner/.idea/modules.xml
new file mode 100644 (file)
index 0000000..85d3e28
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/BarCodeScanner.iml" filepath="$PROJECT_DIR$/BarCodeScanner.iml" />
+      <module fileurl="file://$PROJECT_DIR$/glass/glass.iml" filepath="$PROJECT_DIR$/glass/glass.iml" />
+      <module fileurl="file://$PROJECT_DIR$/mobile/mobile.iml" filepath="$PROJECT_DIR$/mobile/mobile.iml" />
+    </modules>
+  </component>
+</project>
+
diff --git a/BarCodeScanner/.idea/scopes/scope_settings.xml b/BarCodeScanner/.idea/scopes/scope_settings.xml
new file mode 100644 (file)
index 0000000..922003b
--- /dev/null
@@ -0,0 +1,5 @@
+<component name="DependencyValidationManager">
+  <state>
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+  </state>
+</component>
\ No newline at end of file
diff --git a/BarCodeScanner/.idea/vcs.xml b/BarCodeScanner/.idea/vcs.xml
new file mode 100644 (file)
index 0000000..def6a6a
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="" />
+  </component>
+</project>
+
diff --git a/BarCodeScanner/BarCodeScanner.iml b/BarCodeScanner/BarCodeScanner.iml
new file mode 100644 (file)
index 0000000..42f4ed5
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <output url="file://$MODULE_DIR$/build/classes/main" />
+    <output-test url="file://$MODULE_DIR$/build/classes/test" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/BarCodeScanner/build.gradle b/BarCodeScanner/build.gradle
new file mode 100644 (file)
index 0000000..6356aab
--- /dev/null
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.0.0'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
diff --git a/BarCodeScanner/glass/.gitignore b/BarCodeScanner/glass/.gitignore
new file mode 100644 (file)
index 0000000..796b96d
--- /dev/null
@@ -0,0 +1 @@
+/build
diff --git a/BarCodeScanner/glass/build.gradle b/BarCodeScanner/glass/build.gradle
new file mode 100644 (file)
index 0000000..a8f70af
--- /dev/null
@@ -0,0 +1,38 @@
+apply plugin: 'com.android.application'
+
+repositories {
+    jcenter()
+    flatDir {
+        dirs 'prebuilt-libs'
+    }
+}
+
+android {
+    compileSdkVersion 'Google Inc.:Glass Development Kit Preview:19'
+    buildToolsVersion "21.1.2"
+
+    defaultConfig {
+        applicationId "cz.cvut.fel.dce.barcodescanner"
+        minSdkVersion 19
+        targetSdkVersion 21
+        versionCode 1
+        versionName "1.0"
+    }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile files('libs/android-core-3.1.1-SNAPSHOT.jar')
+    compile files('libs/core-3.1.1-SNAPSHOT.jar')
+}
diff --git a/BarCodeScanner/glass/glass.iml b/BarCodeScanner/glass/glass.iml
new file mode 100644 (file)
index 0000000..5a7a36a
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="BarCodeScanner" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":glass" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android 4.4.2 Glass Development Kit Preview" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" exported="" name="core-3.1.1-SNAPSHOT" level="project" />
+    <orderEntry type="library" exported="" name="android-core-3.1.1-SNAPSHOT" level="project" />
+  </component>
+</module>
+
diff --git a/BarCodeScanner/glass/libs/android-core-3.1.1-SNAPSHOT.jar b/BarCodeScanner/glass/libs/android-core-3.1.1-SNAPSHOT.jar
new file mode 100644 (file)
index 0000000..abd760f
Binary files /dev/null and b/BarCodeScanner/glass/libs/android-core-3.1.1-SNAPSHOT.jar differ
diff --git a/BarCodeScanner/glass/libs/core-3.1.1-SNAPSHOT.jar b/BarCodeScanner/glass/libs/core-3.1.1-SNAPSHOT.jar
new file mode 100644 (file)
index 0000000..5b1a8c4
Binary files /dev/null and b/BarCodeScanner/glass/libs/core-3.1.1-SNAPSHOT.jar differ
diff --git a/BarCodeScanner/glass/proguard-rules.pro b/BarCodeScanner/glass/proguard-rules.pro
new file mode 100644 (file)
index 0000000..1a1fc0a
--- /dev/null
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/michal/adt-bundle-linux-x86_64-20140702/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/BarCodeScanner/glass/src/androidTest/java/cz/cvut/fel/dce/barcodescanner/ApplicationTest.java b/BarCodeScanner/glass/src/androidTest/java/cz/cvut/fel/dce/barcodescanner/ApplicationTest.java
new file mode 100644 (file)
index 0000000..2de9064
--- /dev/null
@@ -0,0 +1,13 @@
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
+ */
+public class ApplicationTest extends ApplicationTestCase<Application> {
+       public ApplicationTest() {
+               super(Application.class);
+       }
+}
\ No newline at end of file
diff --git a/BarCodeScanner/glass/src/main/AndroidManifest.xml b/BarCodeScanner/glass/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..0441572
--- /dev/null
@@ -0,0 +1,34 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="cz.cvut.fel.dce.barcodescanner"
+          android:versionCode="4"
+          android:versionName="0.2.2">
+
+    <uses-permission android:name="android.permission.CAMERA"/>
+    <uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
+
+    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19"/>
+
+    <uses-feature android:name="android.hardware.camera" />
+
+    <application android:allowBackup="true"
+                 android:label="@string/app_name"
+                 android:icon="@drawable/ic_launcher">
+
+        <activity android:name=".CaptureActivity">
+            <intent-filter>
+                <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
+            </intent-filter>
+
+            <intent-filter>
+                <action android:name="cz.cvut.fel.dce.barcodescanner.SCAN"/>
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+
+            <meta-data android:name="com.google.android.glass.VoiceTrigger"
+                       android:resource="@xml/barcode_scanner_show" />
+        </activity>
+
+
+    </application>
+
+</manifest>
diff --git a/BarCodeScanner/glass/src/main/java/cz/cvut/fel/dce/barcodescanner/CameraConfigurationManager.java b/BarCodeScanner/glass/src/main/java/cz/cvut/fel/dce/barcodescanner/CameraConfigurationManager.java
new file mode 100644 (file)
index 0000000..da190a4
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.hardware.Camera;
+import android.util.Log;
+
+import com.google.zxing.client.android.camera.CameraConfigurationUtils;
+
+/**
+ * @author Sean Owen
+ */
+final class CameraConfigurationManager {
+
+  private static final String TAG = "CameraConfiguration";
+
+  static final int ZOOM = 2;
+
+  private CameraConfigurationManager() {
+  }
+
+  static void configure(Camera camera) {
+    Camera.Parameters parameters = camera.getParameters();
+    parameters.setPreviewSize(1280, 720);
+    //parameters.setPreviewSize(1920, 1080);
+    configureAdvanced(parameters);
+    camera.setParameters(parameters);
+    //logAllParameters(parameters);
+  }
+
+  private static void configureAdvanced(Camera.Parameters parameters) {
+    CameraConfigurationUtils.setBestPreviewFPS(parameters);
+    CameraConfigurationUtils.setBarcodeSceneMode(parameters);
+    CameraConfigurationUtils.setVideoStabilization(parameters);
+    CameraConfigurationUtils.setMetering(parameters);
+    CameraConfigurationUtils.setZoom(parameters, ZOOM);
+  }
+
+  private static void logAllParameters(Camera.Parameters parameters) {
+    if (Log.isLoggable(TAG, Log.INFO)) {
+      for (String line : CameraConfigurationUtils.collectStats(parameters).split("\n")) {
+        Log.i(TAG, line);
+      }
+    }
+  }
+
+}
diff --git a/BarCodeScanner/glass/src/main/java/cz/cvut/fel/dce/barcodescanner/CaptureActivity.java b/BarCodeScanner/glass/src/main/java/cz/cvut/fel/dce/barcodescanner/CaptureActivity.java
new file mode 100644 (file)
index 0000000..d3df50c
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2014 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.hardware.Camera;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.KeyEvent;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import com.google.zxing.Result;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.ParsedResultType;
+import com.google.zxing.client.result.ResultParser;
+import com.google.zxing.client.result.TextParsedResult;
+import com.google.zxing.client.result.URIParsedResult;
+
+import java.io.IOException;
+
+/**
+ * @author Sean Owen
+ */
+public final class CaptureActivity extends Activity implements SurfaceHolder.Callback {
+
+  private static final String TAG = CaptureActivity.class.getSimpleName();
+  private static final String SCAN_ACTION = "cz.cvut.fel.dce.barcodescanner.SCAN";
+
+  private boolean hasSurface;
+  private boolean returnResult;
+  private SurfaceHolder holderWithCallback;
+  private Camera camera;
+  private DecodeRunnable decodeRunnable;
+  private Result result;
+
+  @Override
+  public void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+
+    // returnResult should be true if activity was started using 
+    // startActivityForResult() with SCAN_ACTION intent
+    Intent intent = getIntent();
+    returnResult = intent != null && SCAN_ACTION.equals(intent.getAction());
+
+    Window window = getWindow();
+    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    setContentView(R.layout.capture);
+  }
+
+  @Override
+  public synchronized void onResume() {
+    super.onResume();
+    SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
+    SurfaceHolder surfaceHolder = surfaceView.getHolder();
+    if (surfaceHolder == null) {
+      throw new IllegalStateException("No SurfaceHolder?");
+    }
+    if (hasSurface) {
+      initCamera(surfaceHolder);
+    } else {
+      surfaceHolder.addCallback(this);
+      holderWithCallback = surfaceHolder;
+    }
+  }
+
+  @Override
+  public synchronized void onPause() {
+    result = null;
+    if (decodeRunnable != null) {
+      decodeRunnable.stop();
+      decodeRunnable = null;
+    }
+    if (camera != null) {
+      camera.stopPreview();
+      camera.release();
+      camera = null;
+    }
+    if (holderWithCallback != null) {
+      holderWithCallback.removeCallback(this);
+      holderWithCallback = null;
+    }
+    super.onPause();
+  }
+
+  @Override
+  public synchronized void surfaceCreated(SurfaceHolder holder) {
+    Log.i(TAG, "Surface created");
+    holderWithCallback = null;
+    if (!hasSurface) {
+      hasSurface = true;
+      initCamera(holder);
+    }
+  }
+
+  @Override
+  public synchronized void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+    // do nothing
+  }
+
+  @Override
+  public synchronized void surfaceDestroyed(SurfaceHolder holder) {
+    Log.i(TAG, "Surface destroyed");
+    holderWithCallback = null;
+    hasSurface = false;
+  }
+
+  @Override
+  public boolean onKeyDown(int keyCode, KeyEvent event) {
+    if (result != null) {
+      switch (keyCode) {
+        case KeyEvent.KEYCODE_DPAD_CENTER:
+          handleResult(result);
+          return true;
+        case KeyEvent.KEYCODE_BACK:
+          reset();
+          return true;
+      }
+    }
+    return super.onKeyDown(keyCode, event);
+  }
+
+  private void initCamera(SurfaceHolder holder) {
+    if (camera != null) {
+      throw new IllegalStateException("Camera not null on initialization");
+    }
+    camera = Camera.open();
+    if (camera == null) {
+      throw new IllegalStateException("Camera is null");
+    }
+
+    CameraConfigurationManager.configure(camera);
+
+    try {
+      camera.setPreviewDisplay(holder);
+      camera.startPreview();
+    } catch (IOException e) {
+      Log.e(TAG, "Cannot start preview", e);
+    }
+
+    decodeRunnable = new DecodeRunnable(this, camera);
+    new Thread(decodeRunnable).start();
+    reset();
+  }
+
+  void setResult(Result result) {
+    if (returnResult) {
+      Intent scanResult = new Intent(SCAN_ACTION);
+      scanResult.putExtra("SCAN_RESULT", result.getText());
+      setResult(RESULT_OK, scanResult);
+      finish();
+    } else {
+      TextView statusView = (TextView) findViewById(R.id.status_view);
+      String text = result.getText();
+      statusView.setText(text);
+      statusView.setTextSize(TypedValue.COMPLEX_UNIT_SP, Math.max(14, 56 - text.length() / 4));
+      statusView.setVisibility(View.VISIBLE);
+      this.result = result;
+    }
+  }
+
+  private void handleResult(Result result) {
+    ParsedResult parsed = ResultParser.parseResult(result);
+    Intent intent;
+    if (parsed.getType() == ParsedResultType.URI) {
+      intent = new Intent(Intent.ACTION_VIEW, Uri.parse(((URIParsedResult) parsed).getURI()));
+    } else {
+      intent = new Intent(Intent.ACTION_WEB_SEARCH);
+      intent.putExtra("query", ((TextParsedResult) parsed).getText());
+    }
+    startActivity(intent);
+  }
+
+  private synchronized void reset() {
+    TextView statusView = (TextView) findViewById(R.id.status_view);
+    statusView.setVisibility(View.GONE);
+    result = null;
+    decodeRunnable.startScanning();
+  }
+
+}
diff --git a/BarCodeScanner/glass/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeRunnable.java b/BarCodeScanner/glass/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeRunnable.java
new file mode 100644 (file)
index 0000000..33577ff
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2014 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.hardware.Camera;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.PlanarYUVLuminanceSource;
+import com.google.zxing.ReaderException;
+import com.google.zxing.Result;
+import com.google.zxing.common.HybridBinarizer;
+
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * @author Sean Owen
+ */
+final class DecodeRunnable implements Runnable, Camera.PreviewCallback {
+
+  private static final String TAG = DecodeRunnable.class.getSimpleName();
+
+  private final CaptureActivity activity;
+  private final Camera camera;
+  private final int height;
+  private final int width;
+  private final byte[] previewBuffer;
+  private boolean running;
+  private Handler handler;
+  private final CountDownLatch handlerInitLatch;
+
+  DecodeRunnable(CaptureActivity activity, Camera camera) {
+    this.activity = activity;
+    this.camera = camera;
+    Camera.Parameters parameters = camera.getParameters();
+    Camera.Size previewSize = parameters.getPreviewSize();
+    height = previewSize.height;
+    width = previewSize.width;
+    previewBuffer = new byte[(height * width * 3) / 2];
+    running = true;
+    handlerInitLatch = new CountDownLatch(1);
+  }
+
+  private Handler getHandler() {
+    try {
+      handlerInitLatch.await();
+    } catch (InterruptedException ie) {
+      // continue?
+    }
+    return handler;
+  }
+
+
+  @Override
+  public void run() {
+    Looper.prepare();
+    handler = new DecodeHandler();
+    handlerInitLatch.countDown();
+    Looper.loop();
+  }
+
+  void startScanning() {
+    getHandler().obtainMessage(R.id.decode_start).sendToTarget();
+  }
+
+  void stop() {
+    getHandler().obtainMessage(R.id.quit).sendToTarget();
+  }
+
+  @Override
+  public void onPreviewFrame(byte[] data, Camera camera) {
+    if (running) {
+      getHandler().obtainMessage(R.id.decode, data).sendToTarget();
+    }
+  }
+
+  private final class DecodeHandler extends Handler {
+
+    private final Map<DecodeHintType,Object> hints;
+
+    DecodeHandler() {
+      hints = new EnumMap<>(DecodeHintType.class);
+      hints.put(DecodeHintType.POSSIBLE_FORMATS,
+          Arrays.asList(BarcodeFormat.AZTEC, BarcodeFormat.QR_CODE, BarcodeFormat.DATA_MATRIX));
+    }
+
+    @Override
+    public void handleMessage(Message message) {
+      if (!running) {
+        return;
+      }
+      switch (message.what) {
+        case R.id.decode_start:
+          camera.setPreviewCallbackWithBuffer(DecodeRunnable.this);
+          camera.addCallbackBuffer(previewBuffer);
+          break;
+        case R.id.decode:
+          decode((byte[]) message.obj);
+          break;
+        case R.id.decode_succeeded:
+          final Result result = (Result) message.obj;
+          activity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+              activity.setResult(result);
+            }
+          });
+          break;
+        case R.id.decode_failed:
+          camera.addCallbackBuffer(previewBuffer);
+          break;
+        case R.id.quit:
+          running = false;
+          Looper.myLooper().quit();
+          break;
+      }
+    }
+
+    private void decode(byte[] data) {
+      Result rawResult = null;
+
+      int subtendedWidth = width / CameraConfigurationManager.ZOOM;
+      int subtendedHeight = height / CameraConfigurationManager.ZOOM;
+      int excessWidth = width - subtendedWidth;
+      int excessHeight = height - subtendedHeight;
+
+      //long start = System.currentTimeMillis();
+      PlanarYUVLuminanceSource source =
+          new PlanarYUVLuminanceSource(data,
+                                       width, height,
+                                       excessWidth / 2, excessHeight / 2,
+                                       subtendedWidth, subtendedHeight,
+                                       false);
+      BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+      try {
+        rawResult = new MultiFormatReader().decode(bitmap, hints);
+      } catch (ReaderException re) {
+        // continue
+      }
+
+      //long end = System.currentTimeMillis();
+      //Log.i(TAG, "Decode in " + (end - start));
+      Handler handler = getHandler();
+      Message message;
+      if (rawResult == null) {
+        message = handler.obtainMessage(R.id.decode_failed);
+      } else {
+        Log.i(TAG, "Decode succeeded: " + rawResult.getText());
+        message = handler.obtainMessage(R.id.decode_succeeded, rawResult);
+      }
+      message.sendToTarget();
+    }
+
+  }
+
+}
diff --git a/BarCodeScanner/glass/src/main/res/drawable-hdpi/ic_launcher.png b/BarCodeScanner/glass/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..96a442e
Binary files /dev/null and b/BarCodeScanner/glass/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/BarCodeScanner/glass/src/main/res/drawable-mdpi/ic_launcher.png b/BarCodeScanner/glass/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..359047d
Binary files /dev/null and b/BarCodeScanner/glass/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/BarCodeScanner/glass/src/main/res/drawable-xhdpi/ic_launcher.png b/BarCodeScanner/glass/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..71c6d76
Binary files /dev/null and b/BarCodeScanner/glass/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/BarCodeScanner/glass/src/main/res/drawable-xxhdpi/ic_launcher.png b/BarCodeScanner/glass/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..4df1894
Binary files /dev/null and b/BarCodeScanner/glass/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/BarCodeScanner/glass/src/main/res/layout/capture.xml b/BarCodeScanner/glass/src/main/res/layout/capture.xml
new file mode 100644 (file)
index 0000000..a0ca595
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+  <SurfaceView android:id="@+id/preview_view"
+               android:layout_width="fill_parent"
+               android:layout_height="fill_parent"/>
+
+  <TextView android:id="@+id/status_view"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:layout_gravity="bottom|center_horizontal"
+            android:background="@color/result_view"
+            android:textSize="54sp"
+            android:padding="10dip"
+            android:textColor="@color/result_text"
+            android:visibility="gone"/>
+
+</merge>
+
diff --git a/BarCodeScanner/glass/src/main/res/values/colors.xml b/BarCodeScanner/glass/src/main/res/values/colors.xml
new file mode 100644 (file)
index 0000000..c50e0d5
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <color name="result_text">#ffffffff</color>
+  <color name="result_view">#b0000000</color>
+</resources>
diff --git a/BarCodeScanner/glass/src/main/res/values/ids.xml b/BarCodeScanner/glass/src/main/res/values/ids.xml
new file mode 100644 (file)
index 0000000..eb81fbe
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <item type="id" name="decode_start"/>
+  <item type="id" name="decode"/>
+  <item type="id" name="decode_failed"/>
+  <item type="id" name="decode_succeeded"/>
+  <item type="id" name="quit"/>
+</resources>
diff --git a/BarCodeScanner/glass/src/main/res/values/strings.xml b/BarCodeScanner/glass/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..b008da7
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2014 ZXing authors
+
+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.
+-->
+<resources>
+  <string name="app_name">Barcode Scanner for Glass</string>
+</resources>
diff --git a/BarCodeScanner/glass/src/main/res/values/styles.xml b/BarCodeScanner/glass/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..65a325d
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="AppTheme" parent="android:Theme.Holo.Light">
+    </style>
+</resources>
diff --git a/BarCodeScanner/glass/src/main/res/xml/barcode_scanner_show.xml b/BarCodeScanner/glass/src/main/res/xml/barcode_scanner_show.xml
new file mode 100644 (file)
index 0000000..174aae5
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<trigger keyword="Barcode scanner">
+  <constraints camera="true" />
+</trigger>
\ No newline at end of file
diff --git a/BarCodeScanner/gradle.properties b/BarCodeScanner/gradle.properties
new file mode 100644 (file)
index 0000000..1d3591c
--- /dev/null
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/BarCodeScanner/gradle/wrapper/gradle-wrapper.jar b/BarCodeScanner/gradle/wrapper/gradle-wrapper.jar
new file mode 100644 (file)
index 0000000..8c0fb64
Binary files /dev/null and b/BarCodeScanner/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/BarCodeScanner/gradle/wrapper/gradle-wrapper.properties b/BarCodeScanner/gradle/wrapper/gradle-wrapper.properties
new file mode 100644 (file)
index 0000000..0c71e76
--- /dev/null
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/BarCodeScanner/gradlew b/BarCodeScanner/gradlew
new file mode 100755 (executable)
index 0000000..91a7e26
--- /dev/null
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/BarCodeScanner/gradlew.bat b/BarCodeScanner/gradlew.bat
new file mode 100644 (file)
index 0000000..aec9973
--- /dev/null
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem  Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS=\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%" == "" set DIRNAME=.\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if "%ERRORLEVEL%" == "0" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:init\r
+@rem Get command-line arguments, handling Windowz variants\r
+\r
+if not "%OS%" == "Windows_NT" goto win9xME_args\r
+if "%@eval[2+2]" == "4" goto 4NT_args\r
+\r
+:win9xME_args\r
+@rem Slurp the command line arguments.\r
+set CMD_LINE_ARGS=\r
+set _SKIP=2\r
+\r
+:win9xME_args_slurp\r
+if "x%~1" == "x" goto execute\r
+\r
+set CMD_LINE_ARGS=%*\r
+goto execute\r
+\r
+:4NT_args\r
+@rem Get arguments from the 4NT Shell from JP Software\r
+set CMD_LINE_ARGS=%$\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+@rem Execute Gradle\r
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if "%ERRORLEVEL%"=="0" goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
+exit /b 1\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
diff --git a/BarCodeScanner/mobile/.gitignore b/BarCodeScanner/mobile/.gitignore
new file mode 100644 (file)
index 0000000..796b96d
--- /dev/null
@@ -0,0 +1 @@
+/build
diff --git a/BarCodeScanner/mobile/build.gradle b/BarCodeScanner/mobile/build.gradle
new file mode 100644 (file)
index 0000000..28ffa87
--- /dev/null
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 21
+    buildToolsVersion "21.1.2"
+
+    defaultConfig {
+        applicationId "cz.cvut.fel.dce.barcodescanner"
+        minSdkVersion 16
+        targetSdkVersion 21
+        versionCode 1
+        versionName "1.0"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git a/BarCodeScanner/mobile/libs/android-core-3.1.1-SNAPSHOT.jar b/BarCodeScanner/mobile/libs/android-core-3.1.1-SNAPSHOT.jar
new file mode 100644 (file)
index 0000000..abd760f
Binary files /dev/null and b/BarCodeScanner/mobile/libs/android-core-3.1.1-SNAPSHOT.jar differ
diff --git a/BarCodeScanner/mobile/libs/core-3.1.1-SNAPSHOT.jar b/BarCodeScanner/mobile/libs/core-3.1.1-SNAPSHOT.jar
new file mode 100644 (file)
index 0000000..5b1a8c4
Binary files /dev/null and b/BarCodeScanner/mobile/libs/core-3.1.1-SNAPSHOT.jar differ
diff --git a/BarCodeScanner/mobile/mobile.iml b/BarCodeScanner/mobile/mobile.iml
new file mode 100644 (file)
index 0000000..fcde33c
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="BarCodeScanner" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":mobile" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" exported="" name="appcompat-v7-21.0.3" level="project" />
+    <orderEntry type="library" exported="" name="core-3.1.1-SNAPSHOT" level="project" />
+    <orderEntry type="library" exported="" name="android-core-3.1.1-SNAPSHOT" level="project" />
+    <orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" />
+    <orderEntry type="library" exported="" name="support-v4-21.0.3" level="project" />
+  </component>
+</module>
+
diff --git a/BarCodeScanner/mobile/proguard-rules.pro b/BarCodeScanner/mobile/proguard-rules.pro
new file mode 100644 (file)
index 0000000..1a1fc0a
--- /dev/null
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/michal/adt-bundle-linux-x86_64-20140702/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/BarCodeScanner/mobile/src/androidTest/java/cz/cvut/fel/dce/barcodescanner/ApplicationTest.java b/BarCodeScanner/mobile/src/androidTest/java/cz/cvut/fel/dce/barcodescanner/ApplicationTest.java
new file mode 100644 (file)
index 0000000..2de9064
--- /dev/null
@@ -0,0 +1,13 @@
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
+ */
+public class ApplicationTest extends ApplicationTestCase<Application> {
+       public ApplicationTest() {
+               super(Application.class);
+       }
+}
\ No newline at end of file
diff --git a/BarCodeScanner/mobile/src/main/AndroidManifest.xml b/BarCodeScanner/mobile/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..9c6e2da
--- /dev/null
@@ -0,0 +1,139 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="cz.cvut.fel.dce.barcodescanner"
+          android:versionName="4.7.1"
+          android:versionCode="101"
+          android:installLocation="auto">
+
+    <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.FLASHLIGHT"/>
+    <uses-permission android:name="android.permission.READ_CONTACTS"/>
+    <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+
+    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="21"/>
+
+    <!-- Don't require camera, as this requires a rear camera. This allows it to work on the Nexus 7 -->
+    <uses-feature android:name="android.hardware.camera" android:required="false"/>
+    <uses-feature android:name="android.hardware.camera.front" android:required="false"/>
+    <!-- TODO replace above two with next line after Android 4.2 -->
+    <!-- <uses-feature android:name="android.hardware.camera.any"/> -->
+    <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
+    <uses-feature android:name="android.hardware.camera.flash" android:required="false"/>
+    <uses-feature android:name="android.hardware.screen.landscape"/>
+    <uses-feature android:name="android.hardware.wifi" android:required="false"/>
+    <!-- This excludes Google TV, which is unfortunately included by virtue of not requiring a camera -->
+    <uses-feature android:name="android.hardware.touchscreen"/>
+    <!-- TODO make this not required again after android.hardware.camera.any is available -->
+
+    <supports-screens android:xlargeScreens="true"
+                      android:largeScreens="true"
+                      android:normalScreens="true"
+                      android:smallScreens="true"
+                      android:anyDensity="true"/>
+
+    <application android:icon="@drawable/launcher_icon"
+                 android:logo="@drawable/launcher_icon"
+                 android:label="@string/app_name"
+                 android:allowBackup="true">
+        <activity android:name=".CaptureActivity"
+                  android:screenOrientation="sensorLandscape"
+                  android:clearTaskOnLaunch="true"
+                  android:stateNotNeeded="true"
+                  android:theme="@style/CaptureTheme"
+                  android:windowSoftInputMode="stateAlwaysHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+            <intent-filter>
+                <action android:name="cz.cvut.fel.dce.barcodescanner.SCAN"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+            <!-- Allow web apps to launch Barcode Scanner by linking to http://zxing.appspot.com/scan. -->
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.BROWSABLE"/>
+                <data android:scheme="http" android:host="zxing.appspot.com" android:path="/scan"/>
+            </intent-filter>
+            <!-- We also support a Google Product Search URL. -->
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.BROWSABLE"/>
+                <data android:scheme="http" android:host="www.google.com" android:path="/m/products/scan"/>
+            </intent-filter>
+            <!-- And the UK version. -->
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.BROWSABLE"/>
+                <data android:scheme="http" android:host="www.google.co.uk" android:path="/m/products/scan"/>
+            </intent-filter>
+            <!-- Support zxing://scan/?... like iPhone app -->
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.BROWSABLE"/>
+                <data android:scheme="zxing" android:host="scan" android:path="/"/>
+            </intent-filter>
+        </activity>
+        <activity android:name=".PreferencesActivity"
+                  android:label="@string/preferences_name"
+                  android:stateNotNeeded="true"/>
+        <activity android:name=".encode.EncodeActivity"
+                  android:stateNotNeeded="true">
+            <intent-filter>
+                <action android:name="cz.cvut.fel.dce.barcodescanner.ENCODE"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+            <!-- This allows us to handle the Share button in Contacts. -->
+            <intent-filter>
+                <action android:name="android.intent.action.SEND"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <data android:mimeType="text/x-vcard"/>
+            </intent-filter>
+            <!-- This allows us to handle sharing any plain text . -->
+            <intent-filter>
+                <action android:name="android.intent.action.SEND"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <data android:mimeType="text/plain"/>
+            </intent-filter>
+        </activity>
+        <activity android:name=".book.SearchBookContentsActivity"
+                  android:label="@string/sbc_name"
+                  android:stateNotNeeded="true"
+                  android:screenOrientation="sensorLandscape">
+            <intent-filter>
+                <action android:name="cz.cvut.fel.dce.barcodescanner.SEARCH_BOOK_CONTENTS"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+        <activity android:name=".share.ShareActivity"
+                  android:stateNotNeeded="true"
+                  android:screenOrientation="user">
+            <intent-filter>
+                <action android:name="cz.cvut.fel.dce.barcodescanner.SHARE"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+        <activity android:name=".history.HistoryActivity"
+                  android:label="@string/history_title"
+                  android:stateNotNeeded="true"/>
+        <activity android:name=".share.BookmarkPickerActivity"
+                  android:label="@string/bookmark_picker_name"
+                  android:stateNotNeeded="true"/>
+        <activity android:name=".share.AppPickerActivity"
+                  android:label="@string/app_picker_name"
+                  android:stateNotNeeded="true"/>
+        <activity android:name=".HelpActivity"
+                  android:label="@string/menu_help"
+                  android:screenOrientation="user"
+                  android:stateNotNeeded="true"/>
+    </application>
+
+</manifest>
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/AmbientLightManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/AmbientLightManager.java
new file mode 100644 (file)
index 0000000..0ddf57c
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.preference.PreferenceManager;
+
+import cz.cvut.fel.dce.barcodescanner.camera.CameraManager;
+import cz.cvut.fel.dce.barcodescanner.camera.FrontLightMode;
+
+/**
+ * Detects ambient light and switches on the front light when very dark, and off again when sufficiently light.
+ *
+ * @author Sean Owen
+ * @author Nikolaus Huber
+ */
+final class AmbientLightManager implements SensorEventListener {
+
+  private static final float TOO_DARK_LUX = 45.0f;
+  private static final float BRIGHT_ENOUGH_LUX = 450.0f;
+
+  private final Context context;
+  private CameraManager cameraManager;
+  private Sensor lightSensor;
+
+  AmbientLightManager(Context context) {
+    this.context = context;
+  }
+
+  void start(CameraManager cameraManager) {
+    this.cameraManager = cameraManager;
+    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+    if (FrontLightMode.readPref(sharedPrefs) == FrontLightMode.AUTO) {
+      SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+      lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+      if (lightSensor != null) {
+        sensorManager.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
+      }
+    }
+  }
+
+  void stop() {
+    if (lightSensor != null) {
+      SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+      sensorManager.unregisterListener(this);
+      cameraManager = null;
+      lightSensor = null;
+    }
+  }
+
+  @Override
+  public void onSensorChanged(SensorEvent sensorEvent) {
+    float ambientLightLux = sensorEvent.values[0];
+    if (cameraManager != null) {
+      if (ambientLightLux <= TOO_DARK_LUX) {
+        cameraManager.setTorch(true);
+      } else if (ambientLightLux >= BRIGHT_ENOUGH_LUX) {
+        cameraManager.setTorch(false);
+      }
+    }
+  }
+
+  @Override
+  public void onAccuracyChanged(Sensor sensor, int accuracy) {
+    // do nothing
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/BeepManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/BeepManager.java
new file mode 100644 (file)
index 0000000..697af9e
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.AssetFileDescriptor;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.os.Vibrator;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * Manages beeps and vibrations for {@link CaptureActivity}.
+ */
+final class BeepManager implements
+    MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, Closeable {
+
+  private static final String TAG = BeepManager.class.getSimpleName();
+
+  private static final float BEEP_VOLUME = 0.10f;
+  private static final long VIBRATE_DURATION = 200L;
+
+  private final Activity activity;
+  private MediaPlayer mediaPlayer;
+  private boolean playBeep;
+  private boolean vibrate;
+
+  BeepManager(Activity activity) {
+    this.activity = activity;
+    this.mediaPlayer = null;
+    updatePrefs();
+  }
+
+  synchronized void updatePrefs() {
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+    playBeep = shouldBeep(prefs, activity);
+    vibrate = prefs.getBoolean(PreferencesActivity.KEY_VIBRATE, false);
+    if (playBeep && mediaPlayer == null) {
+      // The volume on STREAM_SYSTEM is not adjustable, and users found it too loud,
+      // so we now play on the music stream.
+      activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
+      mediaPlayer = buildMediaPlayer(activity);
+    }
+  }
+
+  synchronized void playBeepSoundAndVibrate() {
+    if (playBeep && mediaPlayer != null) {
+      mediaPlayer.start();
+    }
+    if (vibrate) {
+      Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
+      vibrator.vibrate(VIBRATE_DURATION);
+    }
+  }
+
+  private static boolean shouldBeep(SharedPreferences prefs, Context activity) {
+    boolean shouldPlayBeep = prefs.getBoolean(PreferencesActivity.KEY_PLAY_BEEP, true);
+    if (shouldPlayBeep) {
+      // See if sound settings overrides this
+      AudioManager audioService = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
+      if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
+        shouldPlayBeep = false;
+      }
+    }
+    return shouldPlayBeep;
+  }
+
+  private MediaPlayer buildMediaPlayer(Context activity) {
+    MediaPlayer mediaPlayer = new MediaPlayer();
+    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+    mediaPlayer.setOnCompletionListener(this);
+    mediaPlayer.setOnErrorListener(this);
+    try {
+      AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.beep);
+      try {
+        mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
+      } finally {
+        file.close();
+      }
+      mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
+      mediaPlayer.prepare();
+      return mediaPlayer;
+    } catch (IOException ioe) {
+      Log.w(TAG, ioe);
+      mediaPlayer.release();
+      return null;
+    }
+  }
+
+  @Override
+  public void onCompletion(MediaPlayer mp) {
+    // When the beep has finished playing, rewind to queue up another one.      
+    mp.seekTo(0);
+  }
+
+  @Override
+  public synchronized boolean onError(MediaPlayer mp, int what, int extra) {
+    if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
+      // we are finished, so put up an appropriate error toast if required and finish
+      activity.finish();
+    } else {
+      // possibly media player error, so release and recreate
+      mp.release();
+      mediaPlayer = null;
+      updatePrefs();
+    }
+    return true;
+  }
+
+  @Override
+  public synchronized void close() {
+    if (mediaPlayer != null) {
+      mediaPlayer.release();
+      mediaPlayer = null;
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/CaptureActivity.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/CaptureActivity.java
new file mode 100644 (file)
index 0000000..c861f91
--- /dev/null
@@ -0,0 +1,749 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.Result;
+import com.google.zxing.ResultMetadataType;
+import com.google.zxing.ResultPoint;
+import cz.cvut.fel.dce.barcodescanner.camera.CameraManager;
+import cz.cvut.fel.dce.barcodescanner.clipboard.ClipboardInterface;
+import cz.cvut.fel.dce.barcodescanner.history.HistoryActivity;
+import cz.cvut.fel.dce.barcodescanner.history.HistoryItem;
+import cz.cvut.fel.dce.barcodescanner.history.HistoryManager;
+import cz.cvut.fel.dce.barcodescanner.result.ResultButtonListener;
+import cz.cvut.fel.dce.barcodescanner.result.ResultHandler;
+import cz.cvut.fel.dce.barcodescanner.result.ResultHandlerFactory;
+import cz.cvut.fel.dce.barcodescanner.result.supplement.SupplementalInfoRetriever;
+import cz.cvut.fel.dce.barcodescanner.share.ShareActivity;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.Map;
+
+/**
+ * This activity opens the camera and does the actual scanning on a background thread. It draws a
+ * viewfinder to help the user place the barcode correctly, shows feedback as the image processing
+ * is happening, and then overlays the results when a scan is successful.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ * @author Sean Owen
+ */
+public final class CaptureActivity extends Activity implements SurfaceHolder.Callback {
+
+  private static final String TAG = CaptureActivity.class.getSimpleName();
+
+  private static final long DEFAULT_INTENT_RESULT_DURATION_MS = 1500L;
+  private static final long BULK_MODE_SCAN_DELAY_MS = 1000L;
+
+  private static final String[] ZXING_URLS = { "http://zxing.appspot.com/scan", "zxing://scan/" };
+
+  public static final int HISTORY_REQUEST_CODE = 0x0000bacc;
+
+  private static final Collection<ResultMetadataType> DISPLAYABLE_METADATA_TYPES =
+      EnumSet.of(ResultMetadataType.ISSUE_NUMBER,
+                 ResultMetadataType.SUGGESTED_PRICE,
+                 ResultMetadataType.ERROR_CORRECTION_LEVEL,
+                 ResultMetadataType.POSSIBLE_COUNTRY);
+
+  private CameraManager cameraManager;
+  private CaptureActivityHandler handler;
+  private Result savedResultToShow;
+  private ViewfinderView viewfinderView;
+  private TextView statusView;
+  private View resultView;
+  private Result lastResult;
+  private boolean hasSurface;
+  private boolean copyToClipboard;
+  private IntentSource source;
+  private String sourceUrl;
+  private ScanFromWebPageManager scanFromWebPageManager;
+  private Collection<BarcodeFormat> decodeFormats;
+  private Map<DecodeHintType,?> decodeHints;
+  private String characterSet;
+  private HistoryManager historyManager;
+  private InactivityTimer inactivityTimer;
+  private BeepManager beepManager;
+  private AmbientLightManager ambientLightManager;
+
+  ViewfinderView getViewfinderView() {
+    return viewfinderView;
+  }
+
+  public Handler getHandler() {
+    return handler;
+  }
+
+  CameraManager getCameraManager() {
+    return cameraManager;
+  }
+
+  @Override
+  public void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+
+    Window window = getWindow();
+    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    setContentView(R.layout.capture);
+
+    hasSurface = false;
+    inactivityTimer = new InactivityTimer(this);
+    beepManager = new BeepManager(this);
+    ambientLightManager = new AmbientLightManager(this);
+
+    PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
+  }
+
+  @Override
+  protected void onResume() {
+    super.onResume();
+    
+    // historyManager must be initialized here to update the history preference
+    historyManager = new HistoryManager(this);
+    historyManager.trimHistory();
+
+    // CameraManager must be initialized here, not in onCreate(). This is necessary because we don't
+    // want to open the camera driver and measure the screen size if we're going to show the help on
+    // first launch. That led to bugs where the scanning rectangle was the wrong size and partially
+    // off screen.
+    cameraManager = new CameraManager(getApplication());
+
+    viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
+    viewfinderView.setCameraManager(cameraManager);
+
+    resultView = findViewById(R.id.result_view);
+    statusView = (TextView) findViewById(R.id.status_view);
+
+    handler = null;
+    lastResult = null;
+
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+    if (prefs.getBoolean(PreferencesActivity.KEY_DISABLE_AUTO_ORIENTATION, true)) {
+      setRequestedOrientation(getCurrentOrientation());
+    } else {
+      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
+    }
+
+    resetStatusView();
+
+    SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
+    SurfaceHolder surfaceHolder = surfaceView.getHolder();
+    if (hasSurface) {
+      // The activity was paused but not stopped, so the surface still exists. Therefore
+      // surfaceCreated() won't be called, so init the camera here.
+      initCamera(surfaceHolder);
+    } else {
+      // Install the callback and wait for surfaceCreated() to init the camera.
+      surfaceHolder.addCallback(this);
+    }
+
+    beepManager.updatePrefs();
+    ambientLightManager.start(cameraManager);
+
+    inactivityTimer.onResume();
+
+    Intent intent = getIntent();
+
+    copyToClipboard = prefs.getBoolean(PreferencesActivity.KEY_COPY_TO_CLIPBOARD, true)
+        && (intent == null || intent.getBooleanExtra(Intents.Scan.SAVE_HISTORY, true));
+
+    source = IntentSource.NONE;
+    sourceUrl = null;
+    scanFromWebPageManager = null;
+    decodeFormats = null;
+    characterSet = null;
+
+    if (intent != null) {
+
+      String action = intent.getAction();
+      String dataString = intent.getDataString();
+
+      if (Intents.Scan.ACTION.equals(action)) {
+
+        // Scan the formats the intent requested, and return the result to the calling activity.
+        source = IntentSource.NATIVE_APP_INTENT;
+        decodeFormats = DecodeFormatManager.parseDecodeFormats(intent);
+        decodeHints = DecodeHintManager.parseDecodeHints(intent);
+
+        if (intent.hasExtra(Intents.Scan.WIDTH) && intent.hasExtra(Intents.Scan.HEIGHT)) {
+          int width = intent.getIntExtra(Intents.Scan.WIDTH, 0);
+          int height = intent.getIntExtra(Intents.Scan.HEIGHT, 0);
+          if (width > 0 && height > 0) {
+            cameraManager.setManualFramingRect(width, height);
+          }
+        }
+
+        if (intent.hasExtra(Intents.Scan.CAMERA_ID)) {
+          int cameraId = intent.getIntExtra(Intents.Scan.CAMERA_ID, -1);
+          if (cameraId >= 0) {
+            cameraManager.setManualCameraId(cameraId);
+          }
+        }
+        
+        String customPromptMessage = intent.getStringExtra(Intents.Scan.PROMPT_MESSAGE);
+        if (customPromptMessage != null) {
+          statusView.setText(customPromptMessage);
+        }
+
+      } else if (dataString != null &&
+                 dataString.contains("http://www.google") &&
+                 dataString.contains("/m/products/scan")) {
+
+        // Scan only products and send the result to mobile Product Search.
+        source = IntentSource.PRODUCT_SEARCH_LINK;
+        sourceUrl = dataString;
+        decodeFormats = DecodeFormatManager.PRODUCT_FORMATS;
+
+      } else if (isZXingURL(dataString)) {
+
+        // Scan formats requested in query string (all formats if none specified).
+        // If a return URL is specified, send the results there. Otherwise, handle it ourselves.
+        source = IntentSource.ZXING_LINK;
+        sourceUrl = dataString;
+        Uri inputUri = Uri.parse(dataString);
+        scanFromWebPageManager = new ScanFromWebPageManager(inputUri);
+        decodeFormats = DecodeFormatManager.parseDecodeFormats(inputUri);
+        // Allow a sub-set of the hints to be specified by the caller.
+        decodeHints = DecodeHintManager.parseDecodeHints(inputUri);
+
+      }
+
+      characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);
+
+    }
+  }
+
+  private int getCurrentOrientation() {
+    int rotation = getWindowManager().getDefaultDisplay().getRotation();
+    switch (rotation) {
+      case Surface.ROTATION_0:
+      case Surface.ROTATION_90:
+        return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+      default:
+        return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+    }
+  }
+  
+  private static boolean isZXingURL(String dataString) {
+    if (dataString == null) {
+      return false;
+    }
+    for (String url : ZXING_URLS) {
+      if (dataString.startsWith(url)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Override
+  protected void onPause() {
+    if (handler != null) {
+      handler.quitSynchronously();
+      handler = null;
+    }
+    inactivityTimer.onPause();
+    ambientLightManager.stop();
+    beepManager.close();
+    cameraManager.closeDriver();
+    historyManager = null;
+    if (!hasSurface) {
+      SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
+      SurfaceHolder surfaceHolder = surfaceView.getHolder();
+      surfaceHolder.removeCallback(this);
+    }
+    super.onPause();
+  }
+
+  @Override
+  protected void onDestroy() {
+    inactivityTimer.shutdown();
+    super.onDestroy();
+  }
+
+  @Override
+  public boolean onKeyDown(int keyCode, KeyEvent event) {
+    switch (keyCode) {
+      case KeyEvent.KEYCODE_BACK:
+        if (source == IntentSource.NATIVE_APP_INTENT) {
+          setResult(RESULT_CANCELED);
+          finish();
+          return true;
+        }
+        if ((source == IntentSource.NONE || source == IntentSource.ZXING_LINK) && lastResult != null) {
+          restartPreviewAfterDelay(0L);
+          return true;
+        }
+        break;
+      case KeyEvent.KEYCODE_FOCUS:
+      case KeyEvent.KEYCODE_CAMERA:
+        // Handle these events so they don't launch the Camera app
+        return true;
+      // Use volume up/down to turn on light
+      case KeyEvent.KEYCODE_VOLUME_DOWN:
+        cameraManager.setTorch(false);
+        return true;
+      case KeyEvent.KEYCODE_VOLUME_UP:
+        cameraManager.setTorch(true);
+        return true;
+    }
+    return super.onKeyDown(keyCode, event);
+  }
+
+  @Override
+  public boolean onCreateOptionsMenu(Menu menu) {
+    MenuInflater menuInflater = getMenuInflater();
+    menuInflater.inflate(R.menu.capture, menu);
+    return super.onCreateOptionsMenu(menu);
+  }
+
+  @Override
+  public boolean onOptionsItemSelected(MenuItem item) {
+    Intent intent = new Intent(Intent.ACTION_VIEW);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    switch (item.getItemId()) {
+      case R.id.menu_settings:
+        intent.setClassName(this, PreferencesActivity.class.getName());
+        startActivity(intent);
+        break;
+      case R.id.menu_help:
+        intent.setClassName(this, HelpActivity.class.getName());
+        startActivity(intent);
+        break;
+      default:
+        return super.onOptionsItemSelected(item);
+    }
+    return true;
+  }
+
+  @Override
+  public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+    if (resultCode == RESULT_OK) {
+      if (requestCode == HISTORY_REQUEST_CODE) {
+        int itemNumber = intent.getIntExtra(Intents.History.ITEM_NUMBER, -1);
+        if (itemNumber >= 0) {
+          HistoryItem historyItem = historyManager.buildHistoryItem(itemNumber);
+          decodeOrStoreSavedBitmap(null, historyItem.getResult());
+        }
+      }
+    }
+  }
+
+  private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
+    // Bitmap isn't used yet -- will be used soon
+    if (handler == null) {
+      savedResultToShow = result;
+    } else {
+      if (result != null) {
+        savedResultToShow = result;
+      }
+      if (savedResultToShow != null) {
+        Message message = Message.obtain(handler, R.id.decode_succeeded, savedResultToShow);
+        handler.sendMessage(message);
+      }
+      savedResultToShow = null;
+    }
+  }
+
+  @Override
+  public void surfaceCreated(SurfaceHolder holder) {
+    if (holder == null) {
+      Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
+    }
+    if (!hasSurface) {
+      hasSurface = true;
+      initCamera(holder);
+    }
+  }
+
+  @Override
+  public void surfaceDestroyed(SurfaceHolder holder) {
+    hasSurface = false;
+  }
+
+  @Override
+  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+
+  }
+
+  /**
+   * A valid barcode has been found, so give an indication of success and show the results.
+   *
+   * @param rawResult The contents of the barcode.
+   * @param scaleFactor amount by which thumbnail was scaled
+   * @param barcode   A greyscale bitmap of the camera data which was decoded.
+   */
+  public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
+    inactivityTimer.onActivity();
+    lastResult = rawResult;
+    ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);
+
+    boolean fromLiveScan = barcode != null;
+    if (fromLiveScan) {
+      historyManager.addHistoryItem(rawResult, resultHandler);
+      // Then not from history, so beep/vibrate and we have an image to draw on
+      beepManager.playBeepSoundAndVibrate();
+      drawResultPoints(barcode, scaleFactor, rawResult);
+    }
+
+    switch (source) {
+      case NATIVE_APP_INTENT:
+      case PRODUCT_SEARCH_LINK:
+        handleDecodeExternally(rawResult, resultHandler, barcode);
+        break;
+      case ZXING_LINK:
+        if (scanFromWebPageManager == null || !scanFromWebPageManager.isScanFromWebPage()) {
+          handleDecodeInternally(rawResult, resultHandler, barcode);
+        } else {
+          handleDecodeExternally(rawResult, resultHandler, barcode);
+        }
+        break;
+      case NONE:
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+        if (fromLiveScan && prefs.getBoolean(PreferencesActivity.KEY_BULK_MODE, false)) {
+          Toast.makeText(getApplicationContext(),
+                         getResources().getString(R.string.msg_bulk_mode_scanned) + " (" + rawResult.getText() + ')',
+                         Toast.LENGTH_SHORT).show();
+          // Wait a moment or else it will scan the same barcode continuously about 3 times
+          restartPreviewAfterDelay(BULK_MODE_SCAN_DELAY_MS);
+        } else {
+          handleDecodeInternally(rawResult, resultHandler, barcode);
+        }
+        break;
+    }
+  }
+
+  /**
+   * Superimpose a line for 1D or dots for 2D to highlight the key features of the barcode.
+   *
+   * @param barcode   A bitmap of the captured image.
+   * @param scaleFactor amount by which thumbnail was scaled
+   * @param rawResult The decoded results which contains the points to draw.
+   */
+  private void drawResultPoints(Bitmap barcode, float scaleFactor, Result rawResult) {
+    ResultPoint[] points = rawResult.getResultPoints();
+    if (points != null && points.length > 0) {
+      Canvas canvas = new Canvas(barcode);
+      Paint paint = new Paint();
+      paint.setColor(getResources().getColor(R.color.result_points));
+      if (points.length == 2) {
+        paint.setStrokeWidth(4.0f);
+        drawLine(canvas, paint, points[0], points[1], scaleFactor);
+      } else if (points.length == 4 &&
+                 (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A ||
+                  rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) {
+        // Hacky special case -- draw two lines, for the barcode and metadata
+        drawLine(canvas, paint, points[0], points[1], scaleFactor);
+        drawLine(canvas, paint, points[2], points[3], scaleFactor);
+      } else {
+        paint.setStrokeWidth(10.0f);
+        for (ResultPoint point : points) {
+          if (point != null) {
+            canvas.drawPoint(scaleFactor * point.getX(), scaleFactor * point.getY(), paint);
+          }
+        }
+      }
+    }
+  }
+
+  private static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b, float scaleFactor) {
+    if (a != null && b != null) {
+      canvas.drawLine(scaleFactor * a.getX(), 
+                      scaleFactor * a.getY(), 
+                      scaleFactor * b.getX(), 
+                      scaleFactor * b.getY(), 
+                      paint);
+    }
+  }
+
+  // Put up our own UI for how to handle the decoded contents.
+  private void handleDecodeInternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {
+
+    CharSequence displayContents = resultHandler.getDisplayContents();
+
+    if (copyToClipboard && !resultHandler.areContentsSecure()) {
+      ClipboardInterface.setText(displayContents, this);
+    }
+
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+    if (resultHandler.getDefaultButtonID() != null && prefs.getBoolean(PreferencesActivity.KEY_AUTO_OPEN_WEB, false)) {
+      resultHandler.handleButtonPress(resultHandler.getDefaultButtonID());
+      return;
+    }
+
+    statusView.setVisibility(View.GONE);
+    viewfinderView.setVisibility(View.GONE);
+    resultView.setVisibility(View.VISIBLE);
+
+    ImageView barcodeImageView = (ImageView) findViewById(R.id.barcode_image_view);
+    if (barcode == null) {
+      barcodeImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(),
+          R.drawable.launcher_icon));
+    } else {
+      barcodeImageView.setImageBitmap(barcode);
+    }
+
+    TextView formatTextView = (TextView) findViewById(R.id.format_text_view);
+    formatTextView.setText(rawResult.getBarcodeFormat().toString());
+
+    TextView typeTextView = (TextView) findViewById(R.id.type_text_view);
+    typeTextView.setText(resultHandler.getType().toString());
+
+    DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
+    TextView timeTextView = (TextView) findViewById(R.id.time_text_view);
+    timeTextView.setText(formatter.format(new Date(rawResult.getTimestamp())));
+
+
+    TextView metaTextView = (TextView) findViewById(R.id.meta_text_view);
+    View metaTextViewLabel = findViewById(R.id.meta_text_view_label);
+    metaTextView.setVisibility(View.GONE);
+    metaTextViewLabel.setVisibility(View.GONE);
+    Map<ResultMetadataType,Object> metadata = rawResult.getResultMetadata();
+    if (metadata != null) {
+      StringBuilder metadataText = new StringBuilder(20);
+      for (Map.Entry<ResultMetadataType,Object> entry : metadata.entrySet()) {
+        if (DISPLAYABLE_METADATA_TYPES.contains(entry.getKey())) {
+          metadataText.append(entry.getValue()).append('\n');
+        }
+      }
+      if (metadataText.length() > 0) {
+        metadataText.setLength(metadataText.length() - 1);
+        metaTextView.setText(metadataText);
+        metaTextView.setVisibility(View.VISIBLE);
+        metaTextViewLabel.setVisibility(View.VISIBLE);
+      }
+    }
+
+    TextView contentsTextView = (TextView) findViewById(R.id.contents_text_view);
+    contentsTextView.setText(displayContents);
+    int scaledSize = Math.max(22, 32 - displayContents.length() / 4);
+    contentsTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, scaledSize);
+
+    TextView supplementTextView = (TextView) findViewById(R.id.contents_supplement_text_view);
+    supplementTextView.setText("");
+    supplementTextView.setOnClickListener(null);
+    if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
+        PreferencesActivity.KEY_SUPPLEMENTAL, true)) {
+      SupplementalInfoRetriever.maybeInvokeRetrieval(supplementTextView,
+                                                     resultHandler.getResult(),
+                                                     historyManager,
+                                                     this);
+    }
+
+    int buttonCount = resultHandler.getButtonCount();
+    ViewGroup buttonView = (ViewGroup) findViewById(R.id.result_button_view);
+    buttonView.requestFocus();
+    for (int x = 0; x < ResultHandler.MAX_BUTTON_COUNT; x++) {
+      TextView button = (TextView) buttonView.getChildAt(x);
+      if (x < buttonCount) {
+        button.setVisibility(View.VISIBLE);
+        button.setText(resultHandler.getButtonText(x));
+        button.setOnClickListener(new ResultButtonListener(resultHandler, x));
+      } else {
+        button.setVisibility(View.GONE);
+      }
+    }
+
+  }
+
+  // Briefly show the contents of the barcode, then handle the result outside Barcode Scanner.
+  private void handleDecodeExternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {
+
+    if (barcode != null) {
+      viewfinderView.drawResultBitmap(barcode);
+    }
+
+    long resultDurationMS;
+    if (getIntent() == null) {
+      resultDurationMS = DEFAULT_INTENT_RESULT_DURATION_MS;
+    } else {
+      resultDurationMS = getIntent().getLongExtra(Intents.Scan.RESULT_DISPLAY_DURATION_MS,
+                                                  DEFAULT_INTENT_RESULT_DURATION_MS);
+    }
+
+    if (resultDurationMS > 0) {
+      String rawResultString = String.valueOf(rawResult);
+      if (rawResultString.length() > 32) {
+        rawResultString = rawResultString.substring(0, 32) + " ...";
+      }
+      statusView.setText(getString(resultHandler.getDisplayTitle()) + " : " + rawResultString);
+    }
+
+    if (copyToClipboard && !resultHandler.areContentsSecure()) {
+      CharSequence text = resultHandler.getDisplayContents();
+      ClipboardInterface.setText(text, this);
+    }
+
+    if (source == IntentSource.NATIVE_APP_INTENT) {
+      
+      // Hand back whatever action they requested - this can be changed to Intents.Scan.ACTION when
+      // the deprecated intent is retired.
+      Intent intent = new Intent(getIntent().getAction());
+      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+      intent.putExtra(Intents.Scan.RESULT, rawResult.toString());
+      intent.putExtra(Intents.Scan.RESULT_FORMAT, rawResult.getBarcodeFormat().toString());
+      byte[] rawBytes = rawResult.getRawBytes();
+      if (rawBytes != null && rawBytes.length > 0) {
+        intent.putExtra(Intents.Scan.RESULT_BYTES, rawBytes);
+      }
+      Map<ResultMetadataType,?> metadata = rawResult.getResultMetadata();
+      if (metadata != null) {
+        if (metadata.containsKey(ResultMetadataType.UPC_EAN_EXTENSION)) {
+          intent.putExtra(Intents.Scan.RESULT_UPC_EAN_EXTENSION,
+                          metadata.get(ResultMetadataType.UPC_EAN_EXTENSION).toString());
+        }
+        Number orientation = (Number) metadata.get(ResultMetadataType.ORIENTATION);
+        if (orientation != null) {
+          intent.putExtra(Intents.Scan.RESULT_ORIENTATION, orientation.intValue());
+        }
+        String ecLevel = (String) metadata.get(ResultMetadataType.ERROR_CORRECTION_LEVEL);
+        if (ecLevel != null) {
+          intent.putExtra(Intents.Scan.RESULT_ERROR_CORRECTION_LEVEL, ecLevel);
+        }
+        @SuppressWarnings("unchecked")
+        Iterable<byte[]> byteSegments = (Iterable<byte[]>) metadata.get(ResultMetadataType.BYTE_SEGMENTS);
+        if (byteSegments != null) {
+          int i = 0;
+          for (byte[] byteSegment : byteSegments) {
+            intent.putExtra(Intents.Scan.RESULT_BYTE_SEGMENTS_PREFIX + i, byteSegment);
+            i++;
+          }
+        }
+      }
+      sendReplyMessage(R.id.return_scan_result, intent, resultDurationMS);
+      
+    } else if (source == IntentSource.PRODUCT_SEARCH_LINK) {
+      
+      // Reformulate the URL which triggered us into a query, so that the request goes to the same
+      // TLD as the scan URL.
+      int end = sourceUrl.lastIndexOf("/scan");
+      String replyURL = sourceUrl.substring(0, end) + "?q=" + resultHandler.getDisplayContents() + "&source=zxing";      
+      sendReplyMessage(R.id.launch_product_query, replyURL, resultDurationMS);
+      
+    } else if (source == IntentSource.ZXING_LINK) {
+
+      if (scanFromWebPageManager != null && scanFromWebPageManager.isScanFromWebPage()) {
+        String replyURL = scanFromWebPageManager.buildReplyURL(rawResult, resultHandler);
+        scanFromWebPageManager = null;
+        sendReplyMessage(R.id.launch_product_query, replyURL, resultDurationMS);
+      }
+      
+    }
+  }
+  
+  private void sendReplyMessage(int id, Object arg, long delayMS) {
+    if (handler != null) {
+      Message message = Message.obtain(handler, id, arg);
+      if (delayMS > 0L) {
+        handler.sendMessageDelayed(message, delayMS);
+      } else {
+        handler.sendMessage(message);
+      }
+    }
+  }
+
+  private void initCamera(SurfaceHolder surfaceHolder) {
+    if (surfaceHolder == null) {
+      throw new IllegalStateException("No SurfaceHolder provided");
+    }
+    if (cameraManager.isOpen()) {
+      Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
+      return;
+    }
+    try {
+      cameraManager.openDriver(surfaceHolder);
+      // Creating the handler starts the preview, which can also throw a RuntimeException.
+      if (handler == null) {
+        handler = new CaptureActivityHandler(this, decodeFormats, decodeHints, characterSet, cameraManager);
+      }
+      decodeOrStoreSavedBitmap(null, null);
+    } catch (IOException ioe) {
+      Log.w(TAG, ioe);
+      displayFrameworkBugMessageAndExit();
+    } catch (RuntimeException e) {
+      // Barcode Scanner has seen crashes in the wild of this variety:
+      // java.?lang.?RuntimeException: Fail to connect to camera service
+      Log.w(TAG, "Unexpected error initializing camera", e);
+      displayFrameworkBugMessageAndExit();
+    }
+  }
+
+  private void displayFrameworkBugMessageAndExit() {
+    AlertDialog.Builder builder = new AlertDialog.Builder(this);
+    builder.setTitle(getString(R.string.app_name));
+    builder.setMessage(getString(R.string.msg_camera_framework_bug));
+    builder.setPositiveButton(R.string.button_ok, new FinishListener(this));
+    builder.setOnCancelListener(new FinishListener(this));
+    builder.show();
+  }
+
+  public void restartPreviewAfterDelay(long delayMS) {
+    if (handler != null) {
+      handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
+    }
+    resetStatusView();
+  }
+
+  private void resetStatusView() {
+    resultView.setVisibility(View.GONE);
+    statusView.setText(R.string.msg_default_status);
+    statusView.setVisibility(View.VISIBLE);
+    viewfinderView.setVisibility(View.VISIBLE);
+    lastResult = null;
+  }
+
+  public void drawViewfinder() {
+    viewfinderView.drawViewfinder();
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/CaptureActivityHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/CaptureActivityHandler.java
new file mode 100644 (file)
index 0000000..5bba41b
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.Browser;
+import android.util.Log;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.Result;
+import cz.cvut.fel.dce.barcodescanner.camera.CameraManager;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * This class handles all the messaging which comprises the state machine for capture.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class CaptureActivityHandler extends Handler {
+
+  private static final String TAG = CaptureActivityHandler.class.getSimpleName();
+
+  private final CaptureActivity activity;
+  private final DecodeThread decodeThread;
+  private State state;
+  private final CameraManager cameraManager;
+
+  private enum State {
+    PREVIEW,
+    SUCCESS,
+    DONE
+  }
+
+  CaptureActivityHandler(CaptureActivity activity,
+                         Collection<BarcodeFormat> decodeFormats,
+                         Map<DecodeHintType,?> baseHints,
+                         String characterSet,
+                         CameraManager cameraManager) {
+    this.activity = activity;
+    decodeThread = new DecodeThread(activity, decodeFormats, baseHints, characterSet,
+        new ViewfinderResultPointCallback(activity.getViewfinderView()));
+    decodeThread.start();
+    state = State.SUCCESS;
+
+    // Start ourselves capturing previews and decoding.
+    this.cameraManager = cameraManager;
+    cameraManager.startPreview();
+    restartPreviewAndDecode();
+  }
+
+  @Override
+  public void handleMessage(Message message) {
+    switch (message.what) {
+      case R.id.restart_preview:
+        restartPreviewAndDecode();
+        break;
+      case R.id.decode_succeeded:
+        state = State.SUCCESS;
+        Bundle bundle = message.getData();
+        Bitmap barcode = null;
+        float scaleFactor = 1.0f;
+        if (bundle != null) {
+          byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP);
+          if (compressedBitmap != null) {
+            barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);
+            // Mutable copy:
+            barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
+          }
+          scaleFactor = bundle.getFloat(DecodeThread.BARCODE_SCALED_FACTOR);          
+        }
+        activity.handleDecode((Result) message.obj, barcode, scaleFactor);
+        break;
+      case R.id.decode_failed:
+        // We're decoding as fast as possible, so when one decode fails, start another.
+        state = State.PREVIEW;
+        cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
+        break;
+      case R.id.return_scan_result:
+        activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
+        activity.finish();
+        break;
+      case R.id.launch_product_query:
+        String url = (String) message.obj;
+
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+        intent.setData(Uri.parse(url));
+
+        ResolveInfo resolveInfo =
+            activity.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        String browserPackageName = null;
+        if (resolveInfo != null && resolveInfo.activityInfo != null) {
+          browserPackageName = resolveInfo.activityInfo.packageName;
+          Log.d(TAG, "Using browser in package " + browserPackageName);
+        }
+
+        // Needed for default Android browser / Chrome only apparently
+        if ("com.android.browser".equals(browserPackageName) || "com.android.chrome".equals(browserPackageName)) {
+          intent.setPackage(browserPackageName);
+          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+          intent.putExtra(Browser.EXTRA_APPLICATION_ID, browserPackageName);
+        }
+
+        try {
+          activity.startActivity(intent);
+        } catch (ActivityNotFoundException ignored) {
+          Log.w(TAG, "Can't find anything to handle VIEW of URI " + url);
+        }
+        break;
+    }
+  }
+
+  public void quitSynchronously() {
+    state = State.DONE;
+    cameraManager.stopPreview();
+    Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
+    quit.sendToTarget();
+    try {
+      // Wait at most half a second; should be enough time, and onPause() will timeout quickly
+      decodeThread.join(500L);
+    } catch (InterruptedException e) {
+      // continue
+    }
+
+    // Be absolutely sure we don't send any queued up messages
+    removeMessages(R.id.decode_succeeded);
+    removeMessages(R.id.decode_failed);
+  }
+
+  private void restartPreviewAndDecode() {
+    if (state == State.SUCCESS) {
+      state = State.PREVIEW;
+      cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
+      activity.drawViewfinder();
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/Contents.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/Contents.java
new file mode 100644 (file)
index 0000000..40491de
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.provider.ContactsContract;
+
+/**
+ * The set of constants to use when sending Barcode Scanner an Intent which requests a barcode
+ * to be encoded.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class Contents {
+  private Contents() {
+  }
+
+  public static final class Type {
+    /**
+     * Plain text. Use Intent.putExtra(DATA, string). This can be used for URLs too, but string
+     * must include "http://" or "https://".
+     */
+    public static final String TEXT = "TEXT_TYPE";
+
+    /**
+     * An email type. Use Intent.putExtra(DATA, string) where string is the email address.
+     */
+    public static final String EMAIL = "EMAIL_TYPE";
+
+    /**
+     * Use Intent.putExtra(DATA, string) where string is the phone number to call.
+     */
+    public static final String PHONE = "PHONE_TYPE";
+
+    /**
+     * An SMS type. Use Intent.putExtra(DATA, string) where string is the number to SMS.
+     */
+    public static final String SMS = "SMS_TYPE";
+
+    /**
+     * A contact. Send a request to encode it as follows:
+     * {@code
+     * import android.provider.Contacts;
+     *
+     * Intent intent = new Intent(Intents.Encode.ACTION);
+     * intent.putExtra(Intents.Encode.TYPE, CONTACT);
+     * Bundle bundle = new Bundle();
+     * bundle.putString(ContactsContract.Intents.Insert.NAME, "Jenny");
+     * bundle.putString(ContactsContract.Intents.Insert.PHONE, "8675309");
+     * bundle.putString(ContactsContract.Intents.Insert.EMAIL, "jenny@the80s.com");
+     * bundle.putString(ContactsContract.Intents.Insert.POSTAL, "123 Fake St. San Francisco, CA 94102");
+     * intent.putExtra(Intents.Encode.DATA, bundle);
+     * }
+     */
+    public static final String CONTACT = "CONTACT_TYPE";
+
+    /**
+     * A geographic location. Use as follows:
+     * Bundle bundle = new Bundle();
+     * bundle.putFloat("LAT", latitude);
+     * bundle.putFloat("LONG", longitude);
+     * intent.putExtra(Intents.Encode.DATA, bundle);
+     */
+    public static final String LOCATION = "LOCATION_TYPE";
+
+    private Type() {
+    }
+  }
+
+  public static final String URL_KEY = "URL_KEY";
+
+  public static final String NOTE_KEY = "NOTE_KEY";
+
+  /**
+   * When using Type.CONTACT, these arrays provide the keys for adding or retrieving multiple
+   * phone numbers and addresses.
+   */
+  public static final String[] PHONE_KEYS = {
+      ContactsContract.Intents.Insert.PHONE,
+      ContactsContract.Intents.Insert.SECONDARY_PHONE,
+      ContactsContract.Intents.Insert.TERTIARY_PHONE
+  };
+
+  public static final String[] PHONE_TYPE_KEYS = {
+      ContactsContract.Intents.Insert.PHONE_TYPE,
+      ContactsContract.Intents.Insert.SECONDARY_PHONE_TYPE,
+      ContactsContract.Intents.Insert.TERTIARY_PHONE_TYPE
+  };
+
+  public static final String[] EMAIL_KEYS = {
+      ContactsContract.Intents.Insert.EMAIL,
+      ContactsContract.Intents.Insert.SECONDARY_EMAIL,
+      ContactsContract.Intents.Insert.TERTIARY_EMAIL
+  };
+
+  public static final String[] EMAIL_TYPE_KEYS = {
+      ContactsContract.Intents.Insert.EMAIL_TYPE,
+      ContactsContract.Intents.Insert.SECONDARY_EMAIL_TYPE,
+      ContactsContract.Intents.Insert.TERTIARY_EMAIL_TYPE
+  };
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeFormatManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeFormatManager.java
new file mode 100644 (file)
index 0000000..9be80b4
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.content.Intent;
+import android.net.Uri;
+
+import com.google.zxing.BarcodeFormat;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+final class DecodeFormatManager {
+
+  private static final Pattern COMMA_PATTERN = Pattern.compile(",");
+
+  static final Set<BarcodeFormat> PRODUCT_FORMATS;
+  static final Set<BarcodeFormat> INDUSTRIAL_FORMATS;
+  private static final Set<BarcodeFormat> ONE_D_FORMATS;
+  static final Set<BarcodeFormat> QR_CODE_FORMATS = EnumSet.of(BarcodeFormat.QR_CODE);
+  static final Set<BarcodeFormat> DATA_MATRIX_FORMATS = EnumSet.of(BarcodeFormat.DATA_MATRIX);
+  static final Set<BarcodeFormat> AZTEC_FORMATS = EnumSet.of(BarcodeFormat.AZTEC);
+  static final Set<BarcodeFormat> PDF417_FORMATS = EnumSet.of(BarcodeFormat.PDF_417);
+  static {
+    PRODUCT_FORMATS = EnumSet.of(BarcodeFormat.UPC_A,
+                                 BarcodeFormat.UPC_E,
+                                 BarcodeFormat.EAN_13,
+                                 BarcodeFormat.EAN_8,
+                                 BarcodeFormat.RSS_14,
+                                 BarcodeFormat.RSS_EXPANDED);
+    INDUSTRIAL_FORMATS = EnumSet.of(BarcodeFormat.CODE_39,
+                                    BarcodeFormat.CODE_93,
+                                    BarcodeFormat.CODE_128,
+                                    BarcodeFormat.ITF,
+                                    BarcodeFormat.CODABAR);
+    ONE_D_FORMATS = EnumSet.copyOf(PRODUCT_FORMATS);
+    ONE_D_FORMATS.addAll(INDUSTRIAL_FORMATS);
+  }
+  private static final Map<String,Set<BarcodeFormat>> FORMATS_FOR_MODE;
+  static {
+    FORMATS_FOR_MODE = new HashMap<>();
+    FORMATS_FOR_MODE.put(Intents.Scan.ONE_D_MODE, ONE_D_FORMATS);
+    FORMATS_FOR_MODE.put(Intents.Scan.PRODUCT_MODE, PRODUCT_FORMATS);
+    FORMATS_FOR_MODE.put(Intents.Scan.QR_CODE_MODE, QR_CODE_FORMATS);
+    FORMATS_FOR_MODE.put(Intents.Scan.DATA_MATRIX_MODE, DATA_MATRIX_FORMATS);
+    FORMATS_FOR_MODE.put(Intents.Scan.AZTEC_MODE, AZTEC_FORMATS);
+    FORMATS_FOR_MODE.put(Intents.Scan.PDF417_MODE, PDF417_FORMATS);
+  }
+
+  private DecodeFormatManager() {}
+
+  static Set<BarcodeFormat> parseDecodeFormats(Intent intent) {
+    Iterable<String> scanFormats = null;
+    CharSequence scanFormatsString = intent.getStringExtra(Intents.Scan.FORMATS);
+    if (scanFormatsString != null) {
+      scanFormats = Arrays.asList(COMMA_PATTERN.split(scanFormatsString));
+    }
+    return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE));
+  }
+
+  static Set<BarcodeFormat> parseDecodeFormats(Uri inputUri) {
+    List<String> formats = inputUri.getQueryParameters(Intents.Scan.FORMATS);
+    if (formats != null && formats.size() == 1 && formats.get(0) != null){
+      formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0)));
+    }
+    return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE));
+  }
+
+  private static Set<BarcodeFormat> parseDecodeFormats(Iterable<String> scanFormats, String decodeMode) {
+    if (scanFormats != null) {
+      Set<BarcodeFormat> formats = EnumSet.noneOf(BarcodeFormat.class);
+      try {
+        for (String format : scanFormats) {
+          formats.add(BarcodeFormat.valueOf(format));
+        }
+        return formats;
+      } catch (IllegalArgumentException iae) {
+        // ignore it then
+      }
+    }
+    if (decodeMode != null) {
+      return FORMATS_FOR_MODE.get(decodeMode);
+    }
+    return null;
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeHandler.java
new file mode 100644 (file)
index 0000000..55f863f
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.PlanarYUVLuminanceSource;
+import com.google.zxing.ReaderException;
+import com.google.zxing.Result;
+import com.google.zxing.common.HybridBinarizer;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Map;
+
+final class DecodeHandler extends Handler {
+
+  private static final String TAG = DecodeHandler.class.getSimpleName();
+
+  private final CaptureActivity activity;
+  private final MultiFormatReader multiFormatReader;
+  private boolean running = true;
+
+  DecodeHandler(CaptureActivity activity, Map<DecodeHintType,Object> hints) {
+    multiFormatReader = new MultiFormatReader();
+    multiFormatReader.setHints(hints);
+    this.activity = activity;
+  }
+
+  @Override
+  public void handleMessage(Message message) {
+    if (!running) {
+      return;
+    }
+    switch (message.what) {
+      case R.id.decode:
+        decode((byte[]) message.obj, message.arg1, message.arg2);
+        break;
+      case R.id.quit:
+        running = false;
+        Looper.myLooper().quit();
+        break;
+    }
+  }
+
+  /**
+   * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
+   * reuse the same reader objects from one decode to the next.
+   *
+   * @param data   The YUV preview frame.
+   * @param width  The width of the preview frame.
+   * @param height The height of the preview frame.
+   */
+  private void decode(byte[] data, int width, int height) {
+    long start = System.currentTimeMillis();
+    Result rawResult = null;
+    PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
+    if (source != null) {
+      BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+      try {
+        rawResult = multiFormatReader.decodeWithState(bitmap);
+      } catch (ReaderException re) {
+        // continue
+      } finally {
+        multiFormatReader.reset();
+      }
+    }
+
+    Handler handler = activity.getHandler();
+    if (rawResult != null) {
+      // Don't log the barcode contents for security.
+      long end = System.currentTimeMillis();
+      Log.d(TAG, "Found barcode in " + (end - start) + " ms");
+      if (handler != null) {
+        Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
+        Bundle bundle = new Bundle();
+        bundleThumbnail(source, bundle);        
+        message.setData(bundle);
+        message.sendToTarget();
+      }
+    } else {
+      if (handler != null) {
+        Message message = Message.obtain(handler, R.id.decode_failed);
+        message.sendToTarget();
+      }
+    }
+  }
+
+  private static void bundleThumbnail(PlanarYUVLuminanceSource source, Bundle bundle) {
+    int[] pixels = source.renderThumbnail();
+    int width = source.getThumbnailWidth();
+    int height = source.getThumbnailHeight();
+    Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
+    ByteArrayOutputStream out = new ByteArrayOutputStream();    
+    bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
+    bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
+    bundle.putFloat(DecodeThread.BARCODE_SCALED_FACTOR, (float) width / source.getWidth());
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeHintManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeHintManager.java
new file mode 100644 (file)
index 0000000..0cebb09
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.google.zxing.DecodeHintType;
+
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * @author Lachezar Dobrev
+ */
+final class DecodeHintManager {
+  
+  private static final String TAG = DecodeHintManager.class.getSimpleName();
+
+  // This pattern is used in decoding integer arrays.
+  private static final Pattern COMMA = Pattern.compile(",");
+
+  private DecodeHintManager() {}
+
+  /**
+   * <p>Split a query string into a list of name-value pairs.</p>
+   * 
+   * <p>This is an alternative to the {@link android.net.Uri#getQueryParameterNames()} and
+   * {@link android.net.Uri#getQueryParameters(String)}, which are quirky and not suitable
+   * for exist-only Uri parameters.</p>
+   * 
+   * <p>This method ignores multiple parameters with the same name and returns the
+   * first one only. This is technically incorrect, but should be acceptable due
+   * to the method of processing Hints: no multiple values for a hint.</p>
+   * 
+   * @param query query to split
+   * @return name-value pairs
+   */
+  private static Map<String,String> splitQuery(String query) {
+    Map<String,String> map = new HashMap<>();
+    int pos = 0;
+    while (pos < query.length()) {
+      if (query.charAt(pos) == '&') {
+        // Skip consecutive ampersand separators.
+        pos ++;
+        continue;
+      }
+      int amp = query.indexOf('&', pos);
+      int equ = query.indexOf('=', pos);
+      if (amp < 0) {
+        // This is the last element in the query, no more ampersand elements.
+        String name;
+        String text;
+        if (equ < 0) {
+          // No equal sign
+          name = query.substring(pos);
+          name = name.replace('+', ' '); // Preemptively decode +
+          name = Uri.decode(name);
+          text = "";
+        } else {
+          // Split name and text.
+          name = query.substring(pos, equ);
+          name = name.replace('+', ' '); // Preemptively decode +
+          name = Uri.decode(name);
+          text = query.substring(equ + 1);
+          text = text.replace('+', ' '); // Preemptively decode +
+          text = Uri.decode(text);
+        }
+        if (!map.containsKey(name)) {
+          map.put(name, text);
+        }
+        break;
+      }
+      if (equ < 0 || equ > amp) {
+        // No equal sign until the &: this is a simple parameter with no value.
+        String name = query.substring(pos, amp);
+        name = name.replace('+', ' '); // Preemptively decode +
+        name = Uri.decode(name);
+        if (!map.containsKey(name)) {
+          map.put(name, "");
+        }
+        pos = amp + 1;
+        continue;
+      }
+      String name = query.substring(pos, equ);
+      name = name.replace('+', ' '); // Preemptively decode +
+      name = Uri.decode(name);
+      String text = query.substring(equ+1, amp);
+      text = text.replace('+', ' '); // Preemptively decode +
+      text = Uri.decode(text);
+      if (!map.containsKey(name)) {
+        map.put(name, text);
+      }
+      pos = amp + 1;
+    }
+    return map;
+  }
+
+  static Map<DecodeHintType,?> parseDecodeHints(Uri inputUri) {
+    String query = inputUri.getEncodedQuery();
+    if (query == null || query.isEmpty()) {
+      return null;
+    }
+
+    // Extract parameters
+    Map<String, String> parameters = splitQuery(query);
+
+    Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
+
+    for (DecodeHintType hintType: DecodeHintType.values()) {
+
+      if (hintType == DecodeHintType.CHARACTER_SET ||
+          hintType == DecodeHintType.NEED_RESULT_POINT_CALLBACK ||
+          hintType == DecodeHintType.POSSIBLE_FORMATS) {
+        continue; // This hint is specified in another way
+      }
+
+      String parameterName = hintType.name();
+      String parameterText = parameters.get(parameterName);
+      if (parameterText == null) {
+        continue;
+      }
+      if (hintType.getValueType().equals(Object.class)) {
+        // This is an unspecified type of hint content. Use the value as is.
+        // TODO: Can we make a different assumption on this?
+        hints.put(hintType, parameterText);
+        continue;
+      }
+      if (hintType.getValueType().equals(Void.class)) {
+        // Void hints are just flags: use the constant specified by DecodeHintType
+        hints.put(hintType, Boolean.TRUE);
+        continue;
+      }
+      if (hintType.getValueType().equals(String.class)) {
+        // A string hint: use the decoded value.
+        hints.put(hintType, parameterText);
+        continue;
+      }
+      if (hintType.getValueType().equals(Boolean.class)) {
+        // A boolean hint: a few values for false, everything else is true.
+        // An empty parameter is simply a flag-style parameter, assuming true
+        if (parameterText.isEmpty()) {
+          hints.put(hintType, Boolean.TRUE);
+        } else if ("0".equals(parameterText) || 
+                   "false".equalsIgnoreCase(parameterText) || 
+                   "no".equalsIgnoreCase(parameterText)) {
+          hints.put(hintType, Boolean.FALSE);
+        } else {
+          hints.put(hintType, Boolean.TRUE);
+        }
+
+        continue;
+      }
+      if (hintType.getValueType().equals(int[].class)) {
+        // An integer array. Used to specify valid lengths.
+        // Strip a trailing comma as in Java style array initialisers.
+        if (!parameterText.isEmpty() && parameterText.charAt(parameterText.length() - 1) == ',') {
+          parameterText = parameterText.substring(0, parameterText.length() - 1);
+        }
+        String[] values = COMMA.split(parameterText);
+        int[] array = new int[values.length];
+        for (int i = 0; i < values.length; i++) {
+          try {
+            array[i] = Integer.parseInt(values[i]);
+          } catch (NumberFormatException ignored) {
+            Log.w(TAG, "Skipping array of integers hint " + hintType + " due to invalid numeric value: '" + values[i] + '\'');
+            array = null;
+            break;
+          }
+        }
+        if (array != null) {
+          hints.put(hintType, array);
+        }
+        continue;
+      } 
+      Log.w(TAG, "Unsupported hint type '" + hintType + "' of type " + hintType.getValueType());
+    }
+
+    Log.i(TAG, "Hints from the URI: " + hints);
+    return hints;
+  }
+
+  static Map<DecodeHintType, Object> parseDecodeHints(Intent intent) {
+    Bundle extras = intent.getExtras();
+    if (extras == null || extras.isEmpty()) {
+      return null;
+    }
+    Map<DecodeHintType,Object> hints = new EnumMap<>(DecodeHintType.class);
+
+    for (DecodeHintType hintType: DecodeHintType.values()) {
+
+      if (hintType == DecodeHintType.CHARACTER_SET ||
+          hintType == DecodeHintType.NEED_RESULT_POINT_CALLBACK ||
+          hintType == DecodeHintType.POSSIBLE_FORMATS) {
+        continue; // This hint is specified in another way
+      }
+
+      String hintName = hintType.name();
+      if (extras.containsKey(hintName)) {
+        if (hintType.getValueType().equals(Void.class)) {
+          // Void hints are just flags: use the constant specified by the DecodeHintType
+          hints.put(hintType, Boolean.TRUE);
+        } else {
+          Object hintData = extras.get(hintName);
+          if (hintType.getValueType().isInstance(hintData)) {
+            hints.put(hintType, hintData);
+          } else {
+            Log.w(TAG, "Ignoring hint " + hintType + " because it is not assignable from " + hintData);
+          }
+        }
+      }
+    }
+
+    Log.i(TAG, "Hints from the Intent: " + hints);
+    return hints;
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeThread.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/DecodeThread.java
new file mode 100644 (file)
index 0000000..4f3354a
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.content.SharedPreferences;
+import android.os.Handler;
+import android.os.Looper;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.ResultPointCallback;
+
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This thread does all the heavy lifting of decoding the images.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+final class DecodeThread extends Thread {
+
+  public static final String BARCODE_BITMAP = "barcode_bitmap";
+  public static final String BARCODE_SCALED_FACTOR = "barcode_scaled_factor";
+
+  private final CaptureActivity activity;
+  private final Map<DecodeHintType,Object> hints;
+  private Handler handler;
+  private final CountDownLatch handlerInitLatch;
+  DecodeThread(CaptureActivity activity,
+               Collection<BarcodeFormat> decodeFormats,
+               Map<DecodeHintType,?> baseHints,
+               String characterSet,
+               ResultPointCallback resultPointCallback) {
+
+    this.activity = activity;
+    handlerInitLatch = new CountDownLatch(1);
+
+    hints = new EnumMap<>(DecodeHintType.class);
+    if (baseHints != null) {
+      hints.putAll(baseHints);
+    }
+
+    // The prefs can't change while the thread is running, so pick them up once here.
+    if (decodeFormats == null || decodeFormats.isEmpty()) {
+      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+      decodeFormats = EnumSet.noneOf(BarcodeFormat.class);
+      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D_PRODUCT, true)) {
+        decodeFormats.addAll(DecodeFormatManager.PRODUCT_FORMATS);
+      }
+      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D_INDUSTRIAL, true)) {
+        decodeFormats.addAll(DecodeFormatManager.INDUSTRIAL_FORMATS);
+      }
+      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, true)) {
+        decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
+      }
+      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_DATA_MATRIX, true)) {
+        decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
+      }
+      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_AZTEC, false)) {
+        decodeFormats.addAll(DecodeFormatManager.AZTEC_FORMATS);
+      }
+      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_PDF417, false)) {
+        decodeFormats.addAll(DecodeFormatManager.PDF417_FORMATS);
+      }
+    }
+    hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
+
+    if (characterSet != null) {
+      hints.put(DecodeHintType.CHARACTER_SET, characterSet);
+    }
+    hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback);
+    Log.i("DecodeThread", "Hints: " + hints);
+  }
+
+  Handler getHandler() {
+    try {
+      handlerInitLatch.await();
+    } catch (InterruptedException ie) {
+      // continue?
+    }
+    return handler;
+  }
+
+  @Override
+  public void run() {
+    Looper.prepare();
+    handler = new DecodeHandler(activity, hints);
+    handlerInitLatch.countDown();
+    Looper.loop();
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/FinishListener.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/FinishListener.java
new file mode 100644 (file)
index 0000000..c2a9d52
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.Activity;
+import android.content.DialogInterface;
+
+/**
+ * Simple listener used to exit the app in a few cases.
+ *
+ * @author Sean Owen
+ */
+public final class FinishListener implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
+
+  private final Activity activityToFinish;
+
+  public FinishListener(Activity activityToFinish) {
+    this.activityToFinish = activityToFinish;
+  }
+
+  @Override
+  public void onCancel(DialogInterface dialogInterface) {
+    run();
+  }
+
+  @Override
+  public void onClick(DialogInterface dialogInterface, int i) {
+    run();
+  }
+
+  private void run() {
+    activityToFinish.finish();
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/HelpActivity.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/HelpActivity.java
new file mode 100644 (file)
index 0000000..13850d5
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.webkit.WebView;
+
+/**
+ * An HTML-based help screen.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class HelpActivity extends Activity {
+
+  private static final String BASE_URL =
+      "file:///android_asset/html-" + LocaleManager.getTranslatedAssetLanguage() + '/';
+
+  private WebView webView;
+
+  @Override
+  protected void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+    setContentView(R.layout.help);
+
+    webView = (WebView) findViewById(R.id.help_contents);
+
+    if (icicle == null) {
+      webView.loadUrl(BASE_URL + "index.html");
+    } else {
+      webView.restoreState(icicle);
+    }
+  }
+
+  @Override
+  public boolean onKeyDown(int keyCode, KeyEvent event) {
+    if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
+      webView.goBack();
+      return true;
+    }
+    return super.onKeyDown(keyCode, event);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/HttpHelper.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/HttpHelper.java
new file mode 100644 (file)
index 0000000..0238ea5
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2011 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+
+/**
+ * Utility methods for retrieving content over HTTP using the more-supported {@code java.net} classes
+ * in Android.
+ */
+public final class HttpHelper {
+
+  private static final String TAG = HttpHelper.class.getSimpleName();
+
+  private static final Collection<String> REDIRECTOR_DOMAINS = new HashSet<>(Arrays.asList(
+    "amzn.to", "bit.ly", "bitly.com", "fb.me", "goo.gl", "is.gd", "j.mp", "lnkd.in", "ow.ly",
+    "R.BEETAGG.COM", "r.beetagg.com", "SCN.BY", "su.pr", "t.co", "tinyurl.com", "tr.im"
+  ));
+
+  private HttpHelper() {
+  }
+  
+  public enum ContentType {
+    /** HTML-like content type, including HTML, XHTML, etc. */
+    HTML,
+    /** JSON content */
+    JSON,
+    /** XML */
+    XML,
+    /** Plain text content */
+    TEXT,
+  }
+
+  /**
+   * Downloads the entire resource instead of part.
+   *
+   * @param uri URI to retrieve
+   * @param type expected text-like MIME type of that content
+   * @return content as a {@code String}
+   * @throws java.io.IOException if the content can't be retrieved because of a bad URI, network problem, etc.
+   * @see #downloadViaHttp(String, HttpHelper.ContentType, int)
+   */
+  public static CharSequence downloadViaHttp(String uri, ContentType type) throws IOException {
+    return downloadViaHttp(uri, type, Integer.MAX_VALUE);
+  }
+
+  /**
+   * @param uri URI to retrieve
+   * @param type expected text-like MIME type of that content
+   * @param maxChars approximate maximum characters to read from the source
+   * @return content as a {@code String}
+   * @throws java.io.IOException if the content can't be retrieved because of a bad URI, network problem, etc.
+   */
+  public static CharSequence downloadViaHttp(String uri, ContentType type, int maxChars) throws IOException {
+    String contentTypes;
+    switch (type) {
+      case HTML:
+        contentTypes = "application/xhtml+xml,text/html,text/*,*/*";
+        break;
+      case JSON:
+        contentTypes = "application/json,text/*,*/*";
+        break;
+      case XML:
+        contentTypes = "application/xml,text/*,*/*";
+        break;
+      case TEXT:
+      default:
+        contentTypes = "text/*,*/*";
+    }
+    return downloadViaHttp(uri, contentTypes, maxChars);
+  }
+
+  private static CharSequence downloadViaHttp(String uri, String contentTypes, int maxChars) throws IOException {
+    int redirects = 0;
+    while (redirects < 5) {
+      URL url = new URL(uri);
+      HttpURLConnection connection = safelyOpenConnection(url);
+      connection.setInstanceFollowRedirects(true); // Won't work HTTP -> HTTPS or vice versa
+      connection.setRequestProperty("Accept", contentTypes);
+      connection.setRequestProperty("Accept-Charset", "utf-8,*");
+      connection.setRequestProperty("User-Agent", "ZXing (Android)");
+      try {
+        int responseCode = safelyConnect(connection);
+        switch (responseCode) {
+          case HttpURLConnection.HTTP_OK:
+            return consume(connection, maxChars);
+          case HttpURLConnection.HTTP_MOVED_TEMP:
+            String location = connection.getHeaderField("Location");
+            if (location != null) {
+              uri = location;
+              redirects++;
+              continue;
+            }
+            throw new IOException("No Location");
+          default:
+            throw new IOException("Bad HTTP response: " + responseCode);
+        }
+      } finally {
+        connection.disconnect();
+      }
+    }
+    throw new IOException("Too many redirects");
+  }
+
+  private static String getEncoding(URLConnection connection) {
+    String contentTypeHeader = connection.getHeaderField("Content-Type");
+    if (contentTypeHeader != null) {
+      int charsetStart = contentTypeHeader.indexOf("charset=");
+      if (charsetStart >= 0) {
+        return contentTypeHeader.substring(charsetStart + "charset=".length());
+      }
+    }
+    return "UTF-8";
+  }
+
+  private static CharSequence consume(URLConnection connection, int maxChars) throws IOException {
+    String encoding = getEncoding(connection);
+    StringBuilder out = new StringBuilder();
+    Reader in = null;
+    try {
+      in = new InputStreamReader(connection.getInputStream(), encoding);
+      char[] buffer = new char[1024];
+      int charsRead;
+      while (out.length() < maxChars && (charsRead = in.read(buffer)) > 0) {
+        out.append(buffer, 0, charsRead);
+      }
+    } finally {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (IOException | NullPointerException ioe) {
+          // continue
+        }
+      }
+    }
+    return out;
+  }
+
+  public static URI unredirect(URI uri) throws IOException {
+    if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {
+      return uri;
+    }
+    URL url = uri.toURL();
+    HttpURLConnection connection = safelyOpenConnection(url);
+    connection.setInstanceFollowRedirects(false);
+    connection.setDoInput(false);
+    connection.setRequestMethod("HEAD");
+    connection.setRequestProperty("User-Agent", "ZXing (Android)");
+    try {
+      int responseCode = safelyConnect(connection);
+      switch (responseCode) {
+        case HttpURLConnection.HTTP_MULT_CHOICE:
+        case HttpURLConnection.HTTP_MOVED_PERM:
+        case HttpURLConnection.HTTP_MOVED_TEMP:
+        case HttpURLConnection.HTTP_SEE_OTHER:
+        case 307: // No constant for 307 Temporary Redirect ?
+          String location = connection.getHeaderField("Location");
+          if (location != null) {
+            try {
+              return new URI(location);
+            } catch (URISyntaxException e) {
+              // nevermind
+            }
+          }
+      }
+      return uri;
+    } finally {
+      connection.disconnect();
+    }
+  }
+  
+  private static HttpURLConnection safelyOpenConnection(URL url) throws IOException {
+    URLConnection conn;
+    try {
+      conn = url.openConnection();
+    } catch (NullPointerException npe) {
+      // Another strange bug in Android?
+      Log.w(TAG, "Bad URI? " + url);
+      throw new IOException(npe);
+    }
+    if (!(conn instanceof HttpURLConnection)) {
+      throw new IOException();
+    }
+    return (HttpURLConnection) conn;
+  }
+
+  private static int safelyConnect(HttpURLConnection connection) throws IOException {
+    try {
+      connection.connect();
+    } catch (NullPointerException | IllegalArgumentException | IndexOutOfBoundsException | SecurityException e) {
+      // this is an Android bug: http://code.google.com/p/android/issues/detail?id=16895
+      throw new IOException(e);
+    }
+    try {
+      return connection.getResponseCode();
+    } catch (NullPointerException | StringIndexOutOfBoundsException | IllegalArgumentException e) {
+      // this is maybe this Android bug: http://code.google.com/p/android/issues/detail?id=15554
+      throw new IOException(e);
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/InactivityTimer.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/InactivityTimer.java
new file mode 100644 (file)
index 0000000..457e76c
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.AsyncTask;
+import android.os.BatteryManager;
+import android.util.Log;
+
+/**
+ * Finishes an activity after a period of inactivity if the device is on battery power.
+ */
+final class InactivityTimer {
+
+  private static final String TAG = InactivityTimer.class.getSimpleName();
+
+  private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L;
+
+  private final Activity activity;
+  private final BroadcastReceiver powerStatusReceiver;
+  private boolean registered;
+  private AsyncTask<Object,Object,Object> inactivityTask;
+
+  InactivityTimer(Activity activity) {
+    this.activity = activity;
+    powerStatusReceiver = new PowerStatusReceiver();
+    registered = false;
+    onActivity();
+  }
+
+  synchronized void onActivity() {
+    cancel();
+    inactivityTask = new InactivityAsyncTask();
+    inactivityTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+  }
+
+  public synchronized void onPause() {
+    cancel();
+    if (registered) {
+      activity.unregisterReceiver(powerStatusReceiver);
+      registered = false;
+    } else {
+      Log.w(TAG, "PowerStatusReceiver was never registered?");
+    }
+  }
+
+  public synchronized void onResume() {
+    if (registered) {
+      Log.w(TAG, "PowerStatusReceiver was already registered?");
+    } else {
+      activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+      registered = true;
+    }
+    onActivity();
+  }
+
+  private synchronized void cancel() {
+    AsyncTask<?,?,?> task = inactivityTask;
+    if (task != null) {
+      task.cancel(true);
+      inactivityTask = null;
+    }
+  }
+
+  void shutdown() {
+    cancel();
+  }
+
+  private final class PowerStatusReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent){
+      if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
+        // 0 indicates that we're on battery
+        boolean onBatteryNow = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) <= 0;
+        if (onBatteryNow) {
+          InactivityTimer.this.onActivity();
+        } else {
+          InactivityTimer.this.cancel();
+        }
+      }
+    }
+  }
+
+  private final class InactivityAsyncTask extends AsyncTask<Object,Object,Object> {
+    @Override
+    protected Object doInBackground(Object... objects) {
+      try {
+        Thread.sleep(INACTIVITY_DELAY_MS);
+        Log.i(TAG, "Finishing activity due to inactivity");
+        activity.finish();
+      } catch (InterruptedException e) {
+        // continue without killing
+      }
+      return null;
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/IntentSource.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/IntentSource.java
new file mode 100644 (file)
index 0000000..7613476
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+enum IntentSource {
+
+  NATIVE_APP_INTENT,
+  PRODUCT_SEARCH_LINK,
+  ZXING_LINK,
+  NONE
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/Intents.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/Intents.java
new file mode 100644 (file)
index 0000000..857a1c6
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+/**
+ * This class provides the constants to use when sending an Intent to Barcode Scanner.
+ * These strings are effectively API and cannot be changed.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class Intents {
+  private Intents() {
+  }
+
+  public static final class Scan {
+    /**
+     * Send this intent to open the Barcodes app in scanning mode, find a barcode, and return
+     * the results.
+     */
+    public static final String ACTION = "cz.cvut.fel.dce.barcodescanner.SCAN";
+
+    /**
+     * By default, sending this will decode all barcodes that we understand. However it
+     * may be useful to limit scanning to certain formats. Use
+     * {@link android.content.Intent#putExtra(String, String)} with one of the values below.
+     *
+     * Setting this is effectively shorthand for setting explicit formats with {@link #FORMATS}.
+     * It is overridden by that setting.
+     */
+    public static final String MODE = "SCAN_MODE";
+
+    /**
+     * Decode only UPC and EAN barcodes. This is the right choice for shopping apps which get
+     * prices, reviews, etc. for products.
+     */
+    public static final String PRODUCT_MODE = "PRODUCT_MODE";
+
+    /**
+     * Decode only 1D barcodes.
+     */
+    public static final String ONE_D_MODE = "ONE_D_MODE";
+
+    /**
+     * Decode only QR codes.
+     */
+    public static final String QR_CODE_MODE = "QR_CODE_MODE";
+
+    /**
+     * Decode only Data Matrix codes.
+     */
+    public static final String DATA_MATRIX_MODE = "DATA_MATRIX_MODE";
+
+    /**
+     * Decode only Aztec.
+     */
+    public static final String AZTEC_MODE = "AZTEC_MODE";
+
+    /**
+     * Decode only PDF417.
+     */
+    public static final String PDF417_MODE = "PDF417_MODE";
+
+    /**
+     * Comma-separated list of formats to scan for. The values must match the names of
+     * {@link com.google.zxing.BarcodeFormat}s, e.g. {@link com.google.zxing.BarcodeFormat#EAN_13}.
+     * Example: "EAN_13,EAN_8,QR_CODE". This overrides {@link #MODE}.
+     */
+    public static final String FORMATS = "SCAN_FORMATS";
+
+    /**
+     * Optional parameter to specify the id of the camera from which to recognize barcodes.
+     * Overrides the default camera that would otherwise would have been selected.
+     * If provided, should be an int.
+     */
+    public static final String CAMERA_ID = "SCAN_CAMERA_ID";
+
+    /**
+     * @see com.google.zxing.DecodeHintType#CHARACTER_SET
+     */
+    public static final String CHARACTER_SET = "CHARACTER_SET";
+
+    /**
+     * Optional parameters to specify the width and height of the scanning rectangle in pixels.
+     * The app will try to honor these, but will clamp them to the size of the preview frame.
+     * You should specify both or neither, and pass the size as an int.
+     */
+    public static final String WIDTH = "SCAN_WIDTH";
+    public static final String HEIGHT = "SCAN_HEIGHT";
+
+    /**
+     * Desired duration in milliseconds for which to pause after a successful scan before
+     * returning to the calling intent. Specified as a long, not an integer!
+     * For example: 1000L, not 1000.
+     */
+    public static final String RESULT_DISPLAY_DURATION_MS = "RESULT_DISPLAY_DURATION_MS";
+
+    /**
+     * Prompt to show on-screen when scanning by intent. Specified as a {@link String}.
+     */
+    public static final String PROMPT_MESSAGE = "PROMPT_MESSAGE";
+
+    /**
+     * If a barcode is found, Barcodes returns {@link android.app.Activity#RESULT_OK} to
+     * {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)}
+     * of the app which requested the scan via
+     * {@link android.app.Activity#startActivityForResult(android.content.Intent, int)}
+     * The barcodes contents can be retrieved with
+     * {@link android.content.Intent#getStringExtra(String)}. 
+     * If the user presses Back, the result code will be {@link android.app.Activity#RESULT_CANCELED}.
+     */
+    public static final String RESULT = "SCAN_RESULT";
+
+    /**
+     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_FORMAT}
+     * to determine which barcode format was found.
+     * See {@link com.google.zxing.BarcodeFormat} for possible values.
+     */
+    public static final String RESULT_FORMAT = "SCAN_RESULT_FORMAT";
+
+    /**
+     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_UPC_EAN_EXTENSION}
+     * to return the content of any UPC extension barcode that was also found. Only applicable
+     * to {@link com.google.zxing.BarcodeFormat#UPC_A} and {@link com.google.zxing.BarcodeFormat#EAN_13}
+     * formats.
+     */
+    public static final String RESULT_UPC_EAN_EXTENSION = "SCAN_RESULT_UPC_EAN_EXTENSION";
+
+    /**
+     * Call {@link android.content.Intent#getByteArrayExtra(String)} with {@link #RESULT_BYTES}
+     * to get a {@code byte[]} of raw bytes in the barcode, if available.
+     */
+    public static final String RESULT_BYTES = "SCAN_RESULT_BYTES";
+
+    /**
+     * Key for the value of {@link com.google.zxing.ResultMetadataType#ORIENTATION}, if available.
+     * Call {@link android.content.Intent#getIntArrayExtra(String)} with {@link #RESULT_ORIENTATION}.
+     */
+    public static final String RESULT_ORIENTATION = "SCAN_RESULT_ORIENTATION";
+
+    /**
+     * Key for the value of {@link com.google.zxing.ResultMetadataType#ERROR_CORRECTION_LEVEL}, if available.
+     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_ERROR_CORRECTION_LEVEL}.
+     */
+    public static final String RESULT_ERROR_CORRECTION_LEVEL = "SCAN_RESULT_ERROR_CORRECTION_LEVEL";
+
+    /**
+     * Prefix for keys that map to the values of {@link com.google.zxing.ResultMetadataType#BYTE_SEGMENTS},
+     * if available. The actual values will be set under a series of keys formed by adding 0, 1, 2, ...
+     * to this prefix. So the first byte segment is under key "SCAN_RESULT_BYTE_SEGMENTS_0" for example.
+     * Call {@link android.content.Intent#getByteArrayExtra(String)} with these keys.
+     */
+    public static final String RESULT_BYTE_SEGMENTS_PREFIX = "SCAN_RESULT_BYTE_SEGMENTS_";
+
+    /**
+     * Setting this to false will not save scanned codes in the history. Specified as a {@code boolean}.
+     */
+    public static final String SAVE_HISTORY = "SAVE_HISTORY";
+
+    private Scan() {
+    }
+  }
+
+  public static final class History {
+
+    public static final String ITEM_NUMBER = "ITEM_NUMBER";
+
+    private History() {
+    }
+  }
+
+  public static final class Encode {
+    /**
+     * Send this intent to encode a piece of data as a QR code and display it full screen, so
+     * that another person can scan the barcode from your screen.
+     */
+    public static final String ACTION = "cccz.cvut.fel.dce.barcodescanner.ODE";
+
+    /**
+     * The data to encode. Use {@link android.content.Intent#putExtra(String, String)} or
+     * {@link android.content.Intent#putExtra(String, android.os.Bundle)}, 
+     * depending on the type and format specified. Non-QR Code formats should
+     * just use a String here. For QR Code, see Contents for details.
+     */
+    public static final String DATA = "ENCODE_DATA";
+
+    /**
+     * The type of data being supplied if the format is QR Code. Use
+     * {@link android.content.Intent#putExtra(String, String)} with one of {@link Contents.Type}.
+     */
+    public static final String TYPE = "ENCODE_TYPE";
+
+    /**
+     * The barcode format to be displayed. If this isn't specified or is blank,
+     * it defaults to QR Code. Use {@link android.content.Intent#putExtra(String, String)}, where
+     * format is one of {@link com.google.zxing.BarcodeFormat}.
+     */
+    public static final String FORMAT = "ENCODE_FORMAT";
+
+    /**
+     * Normally the contents of the barcode are displayed to the user in a TextView. Setting this
+     * boolean to false will hide that TextView, showing only the encode barcode.
+     */
+    public static final String SHOW_CONTENTS = "ENCODE_SHOW_CONTENTS";
+
+    private Encode() {
+    }
+  }
+
+  public static final class SearchBookContents {
+    /**
+     * Use Google Book Search to search the contents of the book provided.
+     */
+    public static final String ACTION = "coczcz.cvut.fel.dce.barcodescanner.H_BOOK_CONTENTS";
+
+    /**
+     * The book to search, identified by ISBN number.
+     */
+    public static final String ISBN = "ISBN";
+
+    /**
+     * An optional field which is the text to search for.
+     */
+    public static final String QUERY = "QUERY";
+
+    private SearchBookContents() {
+    }
+  }
+
+  public static final class WifiConnect {
+    /**
+     * Internal intent used to trigger connection to a wi-fi network.
+     */
+    public static final String ACTION = "comcz.cz.cvut.fel.dce.barcodescanner.NNECT";
+
+    /**
+     * The network to connect to, all the configuration provided here.
+     */
+    public static final String SSID = "SSID";
+
+    /**
+     * The network to connect to, all the configuration provided here.
+     */
+    public static final String TYPE = "TYPE";
+
+    /**
+     * The network to connect to, all the configuration provided here.
+     */
+    public static final String PASSWORD = "PASSWORD";
+
+    private WifiConnect() {
+    }
+  }
+
+  public static final class Share {
+    /**
+     * Give the user a choice of items to encode as a barcode, then render it as a QR Code and
+     * display onscreen for a friend to scan with their phone.
+     */
+    public static final String ACTION = "com.google.zxing.client.android.SHARE";
+
+    private Share() {
+    }
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/LocaleManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/LocaleManager.java
new file mode 100644 (file)
index 0000000..93834b1
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Handles any locale-specific logic for the client.
+ *
+ * @author Sean Owen
+ */
+public final class LocaleManager {
+
+  private static final String DEFAULT_TLD = "com";
+  private static final String DEFAULT_COUNTRY = "US";
+  private static final String DEFAULT_LANGUAGE = "en";
+
+  /**
+   * Locales (well, countries) where Google web search is available.
+   * These should be kept in sync with our translations.
+   */
+  private static final Map<String,String> GOOGLE_COUNTRY_TLD;
+  static {
+    GOOGLE_COUNTRY_TLD = new HashMap<>();
+    GOOGLE_COUNTRY_TLD.put("AR", "com.ar"); // ARGENTINA
+    GOOGLE_COUNTRY_TLD.put("AU", "com.au"); // AUSTRALIA
+    GOOGLE_COUNTRY_TLD.put("BR", "com.br"); // BRAZIL
+    GOOGLE_COUNTRY_TLD.put("BG", "bg"); // BULGARIA
+    GOOGLE_COUNTRY_TLD.put(Locale.CANADA.getCountry(), "ca");
+    GOOGLE_COUNTRY_TLD.put(Locale.CHINA.getCountry(), "cn");
+    GOOGLE_COUNTRY_TLD.put("CZ", "cz"); // CZECH REPUBLIC
+    GOOGLE_COUNTRY_TLD.put("DK", "dk"); // DENMARK
+    GOOGLE_COUNTRY_TLD.put("FI", "fi"); // FINLAND
+    GOOGLE_COUNTRY_TLD.put(Locale.FRANCE.getCountry(), "fr");
+    GOOGLE_COUNTRY_TLD.put(Locale.GERMANY.getCountry(), "de");
+    GOOGLE_COUNTRY_TLD.put("GR", "gr"); // GREECE
+    GOOGLE_COUNTRY_TLD.put("HU", "hu"); // HUNGARY
+    GOOGLE_COUNTRY_TLD.put("ID", "co.id"); // INDONESIA
+    GOOGLE_COUNTRY_TLD.put("IL", "co.il"); // ISRAEL
+    GOOGLE_COUNTRY_TLD.put(Locale.ITALY.getCountry(), "it");
+    GOOGLE_COUNTRY_TLD.put(Locale.JAPAN.getCountry(), "co.jp");
+    GOOGLE_COUNTRY_TLD.put(Locale.KOREA.getCountry(), "co.kr");
+    GOOGLE_COUNTRY_TLD.put("NL", "nl"); // NETHERLANDS
+    GOOGLE_COUNTRY_TLD.put("PL", "pl"); // POLAND
+    GOOGLE_COUNTRY_TLD.put("PT", "pt"); // PORTUGAL
+    GOOGLE_COUNTRY_TLD.put("RO", "ro"); // ROMANIA    
+    GOOGLE_COUNTRY_TLD.put("RU", "ru"); // RUSSIA
+    GOOGLE_COUNTRY_TLD.put("SK", "sk"); // SLOVAK REPUBLIC
+    GOOGLE_COUNTRY_TLD.put("SI", "si"); // SLOVENIA
+    GOOGLE_COUNTRY_TLD.put("ES", "es"); // SPAIN
+    GOOGLE_COUNTRY_TLD.put("SE", "se"); // SWEDEN
+    GOOGLE_COUNTRY_TLD.put("CH", "ch"); // SWITZERLAND    
+    GOOGLE_COUNTRY_TLD.put(Locale.TAIWAN.getCountry(), "tw");
+    GOOGLE_COUNTRY_TLD.put("TR", "com.tr"); // TURKEY
+    GOOGLE_COUNTRY_TLD.put(Locale.UK.getCountry(), "co.uk");
+    GOOGLE_COUNTRY_TLD.put(Locale.US.getCountry(), "com");
+  }
+
+  /**
+   * Google Product Search for mobile is available in fewer countries than web search. See here:
+   * http://support.google.com/merchants/bin/answer.py?hl=en-GB&answer=160619
+   */
+  private static final Map<String,String> GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD;
+  static {
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD = new HashMap<>();
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put("AU", "com.au"); // AUSTRALIA
+    //GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.CHINA.getCountry(), "cn");
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.FRANCE.getCountry(), "fr");
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.GERMANY.getCountry(), "de");
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.ITALY.getCountry(), "it");
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.JAPAN.getCountry(), "co.jp");
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put("NL", "nl"); // NETHERLANDS
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put("ES", "es"); // SPAIN
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put("CH", "ch"); // SWITZERLAND
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.UK.getCountry(), "co.uk");
+    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.US.getCountry(), "com");
+  }
+
+  /**
+   * Book search is offered everywhere that web search is available.
+   */
+  private static final Map<String,String> GOOGLE_BOOK_SEARCH_COUNTRY_TLD = GOOGLE_COUNTRY_TLD;
+
+  private static final Collection<String> TRANSLATED_HELP_ASSET_LANGUAGES =
+      Arrays.asList("de", "en", "es", "fr", "it", "ja", "ko", "nl", "pt", "ru", "zh-rCN", "zh-rTW", "zh-rHK");
+
+  private LocaleManager() {}
+
+  /**
+   * @param context application's {@link android.content.Context}
+   * @return country-specific TLD suffix appropriate for the current default locale
+   *  (e.g. "co.uk" for the United Kingdom)
+   */
+  public static String getCountryTLD(Context context) {
+    return doGetTLD(GOOGLE_COUNTRY_TLD, context);
+  }
+
+  /**
+   * The same as above, but specifically for Google Product Search.
+   *
+   * @param context application's {@link android.content.Context}
+   * @return The top-level domain to use.
+   */
+  public static String getProductSearchCountryTLD(Context context) {
+    return doGetTLD(GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD, context);
+  }
+
+  /**
+   * The same as above, but specifically for Google Book Search.
+   *
+   * @param context application's {@link android.content.Context}
+   * @return The top-level domain to use.
+   */
+  public static String getBookSearchCountryTLD(Context context) {
+    return doGetTLD(GOOGLE_BOOK_SEARCH_COUNTRY_TLD, context);
+  }
+
+  /**
+   * Does a given URL point to Google Book Search, regardless of domain.
+   *
+   * @param url The address to check.
+   * @return True if this is a Book Search URL.
+   */
+  public static boolean isBookSearchUrl(String url) {
+    return url.startsWith("http://google.com/books") || url.startsWith("http://books.google.");
+  }
+
+  private static String getSystemCountry() {
+    Locale locale = Locale.getDefault();
+    return locale == null ? DEFAULT_COUNTRY : locale.getCountry();
+  }
+
+  private static String getSystemLanguage() {
+    Locale locale = Locale.getDefault();
+    if (locale == null) {
+      return DEFAULT_LANGUAGE;
+    }
+    String language = locale.getLanguage();
+    // Special case Chinese
+    if (Locale.SIMPLIFIED_CHINESE.getLanguage().equals(language)) {
+      return language + "-r" + getSystemCountry();
+    }
+    return language;
+  }
+
+  public static String getTranslatedAssetLanguage() {
+    String language = getSystemLanguage();
+    return TRANSLATED_HELP_ASSET_LANGUAGES.contains(language) ? language : DEFAULT_LANGUAGE;
+  }
+
+  private static String doGetTLD(Map<String,String> map, Context context) {
+    String tld = map.get(getCountry(context));
+    return tld == null ? DEFAULT_TLD : tld;
+  }
+
+  public static String getCountry(Context context) {
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+    String countryOverride = prefs.getString(PreferencesActivity.KEY_SEARCH_COUNTRY, "-");
+    if (countryOverride != null && !countryOverride.isEmpty() && !"-".equals(countryOverride)) {
+      return countryOverride;
+    }
+    return getSystemCountry();
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/PreferencesActivity.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/PreferencesActivity.java
new file mode 100644 (file)
index 0000000..242261f
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * The main settings activity.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ * @author Sean Owen
+ */
+public final class PreferencesActivity extends Activity {
+
+  public static final String KEY_DECODE_1D_PRODUCT = "preferences_decode_1D_product";
+  public static final String KEY_DECODE_1D_INDUSTRIAL = "preferences_decode_1D_industrial";
+  public static final String KEY_DECODE_QR = "preferences_decode_QR";
+  public static final String KEY_DECODE_DATA_MATRIX = "preferences_decode_Data_Matrix";
+  public static final String KEY_DECODE_AZTEC = "preferences_decode_Aztec";
+  public static final String KEY_DECODE_PDF417 = "preferences_decode_PDF417";
+
+  public static final String KEY_CUSTOM_PRODUCT_SEARCH = "preferences_custom_product_search";
+
+  public static final String KEY_PLAY_BEEP = "preferences_play_beep";
+  public static final String KEY_VIBRATE = "preferences_vibrate";
+  public static final String KEY_COPY_TO_CLIPBOARD = "preferences_copy_to_clipboard";
+  public static final String KEY_FRONT_LIGHT_MODE = "preferences_front_light_mode";
+  public static final String KEY_BULK_MODE = "preferences_bulk_mode";
+  public static final String KEY_REMEMBER_DUPLICATES = "preferences_remember_duplicates";
+  public static final String KEY_ENABLE_HISTORY = "preferences_history";
+  public static final String KEY_SUPPLEMENTAL = "preferences_supplemental";
+  public static final String KEY_AUTO_FOCUS = "preferences_auto_focus";
+  public static final String KEY_INVERT_SCAN = "preferences_invert_scan";  
+  public static final String KEY_SEARCH_COUNTRY = "preferences_search_country";
+  public static final String KEY_DISABLE_AUTO_ORIENTATION = "preferences_orientation";
+
+  public static final String KEY_DISABLE_CONTINUOUS_FOCUS = "preferences_disable_continuous_focus";
+  public static final String KEY_DISABLE_EXPOSURE = "preferences_disable_exposure";
+  public static final String KEY_DISABLE_METERING = "preferences_disable_metering";
+  public static final String KEY_DISABLE_BARCODE_SCENE_MODE = "preferences_disable_barcode_scene_mode";
+  public static final String KEY_AUTO_OPEN_WEB = "preferences_auto_open_web";
+
+  @Override
+  protected void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+    getFragmentManager().beginTransaction().replace(android.R.id.content, new PreferencesFragment()).commit();
+  }
+
+  // Apparently this will be necessary when targeting API 19+:
+  /*
+  @Override
+  protected boolean isValidFragment(String fragmentName) {
+    return true;
+  }
+   */
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/PreferencesFragment.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/PreferencesFragment.java
new file mode 100644 (file)
index 0000000..0d5518a
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2013 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.app.AlertDialog;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public final class PreferencesFragment 
+    extends PreferenceFragment 
+    implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+  private CheckBoxPreference[] checkBoxPrefs;
+  
+  @Override
+  public void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+    addPreferencesFromResource(R.xml.preferences);
+    
+    PreferenceScreen preferences = getPreferenceScreen();
+    preferences.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+    checkBoxPrefs = findDecodePrefs(preferences,
+                                    PreferencesActivity.KEY_DECODE_1D_PRODUCT,
+                                    PreferencesActivity.KEY_DECODE_1D_INDUSTRIAL,
+                                    PreferencesActivity.KEY_DECODE_QR,
+                                    PreferencesActivity.KEY_DECODE_DATA_MATRIX,
+                                    PreferencesActivity.KEY_DECODE_AZTEC,
+                                    PreferencesActivity.KEY_DECODE_PDF417);
+    disableLastCheckedPref();
+
+    EditTextPreference customProductSearch = (EditTextPreference)
+        preferences.findPreference(PreferencesActivity.KEY_CUSTOM_PRODUCT_SEARCH);
+    customProductSearch.setOnPreferenceChangeListener(new CustomSearchURLValidator());
+  }
+
+  private static CheckBoxPreference[] findDecodePrefs(PreferenceScreen preferences, String... keys) {
+    CheckBoxPreference[] prefs = new CheckBoxPreference[keys.length];
+    for (int i = 0; i < keys.length; i++) {
+      prefs[i] = (CheckBoxPreference) preferences.findPreference(keys[i]);
+    }
+    return prefs;
+  }
+  
+  @Override
+  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+    disableLastCheckedPref();
+  }
+
+  private void disableLastCheckedPref() {
+    Collection<CheckBoxPreference> checked = new ArrayList<>(checkBoxPrefs.length);
+    for (CheckBoxPreference pref : checkBoxPrefs) {
+      if (pref.isChecked()) {
+        checked.add(pref);
+      }
+    }
+    boolean disable = checked.size() <= 1;
+    for (CheckBoxPreference pref : checkBoxPrefs) {
+      pref.setEnabled(!(disable && checked.contains(pref)));
+    }
+  }
+
+  private class CustomSearchURLValidator implements Preference.OnPreferenceChangeListener {
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+      if (!isValid(newValue)) {
+        AlertDialog.Builder builder =
+            new AlertDialog.Builder(PreferencesFragment.this.getActivity());
+        builder.setTitle(R.string.msg_error);
+        builder.setMessage(R.string.msg_invalid_value);
+        builder.setCancelable(true);
+        builder.show();
+        return false;
+      }
+      return true;
+    }
+
+    private boolean isValid(Object newValue) {
+      // Allow empty/null value
+      if (newValue == null) {
+        return true;
+      }
+      String valueString = newValue.toString();
+      if (valueString.isEmpty()) {
+        return true;
+      }
+      // Before validating, remove custom placeholders, which will not
+      // be considered valid parts of the URL in some locations:
+      // Blank %t and %s:
+      valueString = valueString.replaceAll("%[st]", "");
+      // Blank %f but not if followed by digit or a-f as it may be a hex sequence
+      valueString = valueString.replaceAll("%f(?![0-9a-f])", "");
+      // Require a scheme otherwise:
+      try {
+        URI uri = new URI(valueString);
+        return uri.getScheme() != null;
+      } catch (URISyntaxException use) {
+        return false;
+      }
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/ScanFromWebPageManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/ScanFromWebPageManager.java
new file mode 100644 (file)
index 0000000..69cc204
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2012 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.net.Uri;
+
+import com.google.zxing.Result;
+import cz.cvut.fel.dce.barcodescanner.result.ResultHandler;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+/**
+ * Manages functionality related to responding to requests to scan from an HTTP link in a web page.
+ * See <a href="http://github.com/zxing/zxing/wiki/ScanningFromWebPages">ScanningFromWebPages</a>.
+ *
+ * @author Sean Owen
+ */
+final class ScanFromWebPageManager {
+
+  private static final CharSequence CODE_PLACEHOLDER = "{CODE}";
+  private static final CharSequence RAW_CODE_PLACEHOLDER = "{RAWCODE}";
+  private static final CharSequence META_PLACEHOLDER = "{META}";
+  private static final CharSequence FORMAT_PLACEHOLDER = "{FORMAT}";
+  private static final CharSequence TYPE_PLACEHOLDER = "{TYPE}";
+
+  private static final String RETURN_URL_PARAM = "ret";
+  private static final String RAW_PARAM = "raw";
+
+  private final String returnUrlTemplate;
+  private final boolean returnRaw;
+
+  ScanFromWebPageManager(Uri inputUri) {
+    returnUrlTemplate = inputUri.getQueryParameter(RETURN_URL_PARAM);
+    returnRaw = inputUri.getQueryParameter(RAW_PARAM) != null;
+  }
+
+  boolean isScanFromWebPage() {
+    return returnUrlTemplate != null;
+  }
+
+  String buildReplyURL(Result rawResult, ResultHandler resultHandler) {
+    String result = returnUrlTemplate;
+    result = replace(CODE_PLACEHOLDER,
+                     returnRaw ? rawResult.getText() : resultHandler.getDisplayContents(), result);
+    result = replace(RAW_CODE_PLACEHOLDER, rawResult.getText(), result);
+    result = replace(FORMAT_PLACEHOLDER, rawResult.getBarcodeFormat().toString(), result);
+    result = replace(TYPE_PLACEHOLDER, resultHandler.getType().toString(), result);
+    result = replace(META_PLACEHOLDER, String.valueOf(rawResult.getResultMetadata()), result);
+    return result;
+  }
+
+  private static String replace(CharSequence placeholder, CharSequence with, String pattern) {
+    CharSequence escapedWith = with == null ? "" : with;
+    try {
+      escapedWith = URLEncoder.encode(escapedWith.toString(), "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      // can't happen; UTF-8 is always supported. Continue, I guess, without encoding
+    }
+    return pattern.replace(placeholder, escapedWith);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/ViewfinderResultPointCallback.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/ViewfinderResultPointCallback.java
new file mode 100644 (file)
index 0000000..cc3e8aa
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import com.google.zxing.ResultPoint;
+import com.google.zxing.ResultPointCallback;
+
+final class ViewfinderResultPointCallback implements ResultPointCallback {
+
+  private final ViewfinderView viewfinderView;
+
+  ViewfinderResultPointCallback(ViewfinderView viewfinderView) {
+    this.viewfinderView = viewfinderView;
+  }
+
+  @Override
+  public void foundPossibleResultPoint(ResultPoint point) {
+    viewfinderView.addPossibleResultPoint(point);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/ViewfinderView.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/ViewfinderView.java
new file mode 100644 (file)
index 0000000..e19d582
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.google.zxing.ResultPoint;
+import cz.cvut.fel.dce.barcodescanner.camera.CameraManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This view is overlaid on top of the camera preview. It adds the viewfinder rectangle and partial
+ * transparency outside it, as well as the laser scanner animation and result points.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class ViewfinderView extends View {
+
+  private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};
+  private static final long ANIMATION_DELAY = 80L;
+  private static final int CURRENT_POINT_OPACITY = 0xA0;
+  private static final int MAX_RESULT_POINTS = 20;
+  private static final int POINT_SIZE = 6;
+
+  private CameraManager cameraManager;
+  private final Paint paint;
+  private Bitmap resultBitmap;
+  private final int maskColor;
+  private final int resultColor;
+  private final int laserColor;
+  private final int resultPointColor;
+  private int scannerAlpha;
+  private List<ResultPoint> possibleResultPoints;
+  private List<ResultPoint> lastPossibleResultPoints;
+
+  // This constructor is used when the class is built from an XML resource.
+  public ViewfinderView(Context context, AttributeSet attrs) {
+    super(context, attrs);
+
+    // Initialize these once for performance rather than calling them every time in onDraw().
+    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+    Resources resources = getResources();
+    maskColor = resources.getColor(R.color.viewfinder_mask);
+    resultColor = resources.getColor(R.color.result_view);
+    laserColor = resources.getColor(R.color.viewfinder_laser);
+    resultPointColor = resources.getColor(R.color.possible_result_points);
+    scannerAlpha = 0;
+    possibleResultPoints = new ArrayList<>(5);
+    lastPossibleResultPoints = null;
+  }
+
+  public void setCameraManager(CameraManager cameraManager) {
+    this.cameraManager = cameraManager;
+  }
+
+  @SuppressLint("DrawAllocation")
+  @Override
+  public void onDraw(Canvas canvas) {
+    if (cameraManager == null) {
+      return; // not ready yet, early draw before done configuring
+    }
+    Rect frame = cameraManager.getFramingRect();
+    Rect previewFrame = cameraManager.getFramingRectInPreview();    
+    if (frame == null || previewFrame == null) {
+      return;
+    }
+    int width = canvas.getWidth();
+    int height = canvas.getHeight();
+
+    // Draw the exterior (i.e. outside the framing rect) darkened
+    paint.setColor(resultBitmap != null ? resultColor : maskColor);
+    canvas.drawRect(0, 0, width, frame.top, paint);
+    canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
+    canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
+    canvas.drawRect(0, frame.bottom + 1, width, height, paint);
+
+    if (resultBitmap != null) {
+      // Draw the opaque result bitmap over the scanning rectangle
+      paint.setAlpha(CURRENT_POINT_OPACITY);
+      canvas.drawBitmap(resultBitmap, null, frame, paint);
+    } else {
+
+      // Draw a red "laser scanner" line through the middle to show decoding is active
+      paint.setColor(laserColor);
+      paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
+      scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
+      int middle = frame.height() / 2 + frame.top;
+      canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
+      
+      float scaleX = frame.width() / (float) previewFrame.width();
+      float scaleY = frame.height() / (float) previewFrame.height();
+
+      List<ResultPoint> currentPossible = possibleResultPoints;
+      List<ResultPoint> currentLast = lastPossibleResultPoints;
+      int frameLeft = frame.left;
+      int frameTop = frame.top;
+      if (currentPossible.isEmpty()) {
+        lastPossibleResultPoints = null;
+      } else {
+        possibleResultPoints = new ArrayList<>(5);
+        lastPossibleResultPoints = currentPossible;
+        paint.setAlpha(CURRENT_POINT_OPACITY);
+        paint.setColor(resultPointColor);
+        synchronized (currentPossible) {
+          for (ResultPoint point : currentPossible) {
+            canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
+                              frameTop + (int) (point.getY() * scaleY),
+                              POINT_SIZE, paint);
+          }
+        }
+      }
+      if (currentLast != null) {
+        paint.setAlpha(CURRENT_POINT_OPACITY / 2);
+        paint.setColor(resultPointColor);
+        synchronized (currentLast) {
+          float radius = POINT_SIZE / 2.0f;
+          for (ResultPoint point : currentLast) {
+            canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
+                              frameTop + (int) (point.getY() * scaleY),
+                              radius, paint);
+          }
+        }
+      }
+
+      // Request another update at the animation interval, but only repaint the laser line,
+      // not the entire viewfinder mask.
+      postInvalidateDelayed(ANIMATION_DELAY,
+                            frame.left - POINT_SIZE,
+                            frame.top - POINT_SIZE,
+                            frame.right + POINT_SIZE,
+                            frame.bottom + POINT_SIZE);
+    }
+  }
+
+  public void drawViewfinder() {
+    Bitmap resultBitmap = this.resultBitmap;
+    this.resultBitmap = null;
+    if (resultBitmap != null) {
+      resultBitmap.recycle();
+    }
+    invalidate();
+  }
+
+  /**
+   * Draw a bitmap with the result points highlighted instead of the live scanning display.
+   *
+   * @param barcode An image of the decoded barcode.
+   */
+  public void drawResultBitmap(Bitmap barcode) {
+    resultBitmap = barcode;
+    invalidate();
+  }
+
+  public void addPossibleResultPoint(ResultPoint point) {
+    List<ResultPoint> points = possibleResultPoints;
+    synchronized (points) {
+      points.add(point);
+      int size = points.size();
+      if (size > MAX_RESULT_POINTS) {
+        // trim it
+        points.subList(0, size - MAX_RESULT_POINTS / 2).clear();
+      }
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/BrowseBookListener.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/BrowseBookListener.java
new file mode 100644 (file)
index 0000000..8b96f08
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.book;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.view.View;
+import android.widget.AdapterView;
+
+import cz.cvut.fel.dce.barcodescanner.LocaleManager;
+
+import java.util.List;
+
+final class BrowseBookListener implements AdapterView.OnItemClickListener {
+
+  private final SearchBookContentsActivity activity;
+  private final List<SearchBookContentsResult> items;
+
+  BrowseBookListener(SearchBookContentsActivity activity, List<SearchBookContentsResult> items) {
+    this.activity = activity;
+    this.items = items;
+  }
+
+  @Override
+  public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
+    if (position < 1) {
+      // Clicked header, ignore it
+      return;
+    }
+    int itemOffset = position - 1;
+    if (itemOffset >= items.size()) {
+      return;
+    }
+    String pageId = items.get(itemOffset).getPageId();
+    String query = SearchBookContentsResult.getQuery();
+    if (LocaleManager.isBookSearchUrl(activity.getISBN()) && !pageId.isEmpty()) {
+      String uri = activity.getISBN();
+      int equals = uri.indexOf('=');
+      String volumeId = uri.substring(equals + 1);
+      String readBookURI = "http://books.google." +
+          LocaleManager.getBookSearchCountryTLD(activity) +
+          "/books?id=" + volumeId + "&pg=" + pageId + "&vq=" + query;
+      Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(readBookURI));
+      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);                    
+      activity.startActivity(intent);
+    }
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsActivity.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsActivity.java
new file mode 100644 (file)
index 0000000..34ef3e0
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.book;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.webkit.CookieManager;
+import android.webkit.CookieSyncManager;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import cz.cvut.fel.dce.barcodescanner.HttpHelper;
+import cz.cvut.fel.dce.barcodescanner.Intents;
+import cz.cvut.fel.dce.barcodescanner.LocaleManager;
+import cz.cvut.fel.dce.barcodescanner.R;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * Uses Google Book Search to find a word or phrase in the requested book.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class SearchBookContentsActivity extends Activity {
+
+  private static final String TAG = SearchBookContentsActivity.class.getSimpleName();
+
+  private static final Pattern TAG_PATTERN = Pattern.compile("\\<.*?\\>");
+  private static final Pattern LT_ENTITY_PATTERN = Pattern.compile("&lt;");
+  private static final Pattern GT_ENTITY_PATTERN = Pattern.compile("&gt;");
+  private static final Pattern QUOTE_ENTITY_PATTERN = Pattern.compile("&#39;");
+  private static final Pattern QUOT_ENTITY_PATTERN = Pattern.compile("&quot;");
+
+  private String isbn;
+  private EditText queryTextView;
+  private View queryButton;
+  private ListView resultListView;
+  private TextView headerView;
+  private AsyncTask<String,?,?> networkTask;
+
+  private final View.OnClickListener buttonListener = new View.OnClickListener() {
+    @Override
+    public void onClick(View view) {
+      launchSearch();
+    }
+  };
+
+  private final View.OnKeyListener keyListener = new View.OnKeyListener() {
+    @Override
+    public boolean onKey(View view, int keyCode, KeyEvent event) {
+      if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
+        launchSearch();
+        return true;
+      }
+      return false;
+    }
+  };
+
+  String getISBN() {
+    return isbn;
+  }
+
+  @Override
+  public void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+
+    // Make sure that expired cookies are removed on launch.
+    CookieSyncManager.createInstance(this);
+    CookieManager.getInstance().removeExpiredCookie();
+
+    Intent intent = getIntent();
+    if (intent == null || !intent.getAction().equals(Intents.SearchBookContents.ACTION)) {
+      finish();
+      return;
+    }
+
+    isbn = intent.getStringExtra(Intents.SearchBookContents.ISBN);
+    if (LocaleManager.isBookSearchUrl(isbn)) {
+      setTitle(getString(R.string.sbc_name));
+    } else {
+      setTitle(getString(R.string.sbc_name) + ": ISBN " + isbn);
+    }
+
+    setContentView(R.layout.search_book_contents);
+    queryTextView = (EditText) findViewById(R.id.query_text_view);
+
+    String initialQuery = intent.getStringExtra(Intents.SearchBookContents.QUERY);
+    if (initialQuery != null && !initialQuery.isEmpty()) {
+      // Populate the search box but don't trigger the search
+      queryTextView.setText(initialQuery);
+    }
+    queryTextView.setOnKeyListener(keyListener);
+
+    queryButton = findViewById(R.id.query_button);
+    queryButton.setOnClickListener(buttonListener);
+
+    resultListView = (ListView) findViewById(R.id.result_list_view);
+    LayoutInflater factory = LayoutInflater.from(this);
+    headerView = (TextView) factory.inflate(R.layout.search_book_contents_header,
+        resultListView, false);
+    resultListView.addHeaderView(headerView);
+  }
+
+  @Override
+  protected void onResume() {
+    super.onResume();
+    queryTextView.selectAll();
+  }
+
+  @Override
+  protected void onPause() {
+    AsyncTask<?,?,?> oldTask = networkTask;
+    if (oldTask != null) {
+      oldTask.cancel(true);
+      networkTask = null;
+    }
+    super.onPause();
+  }
+
+  private void launchSearch() {
+    String query = queryTextView.getText().toString();
+    if (query != null && !query.isEmpty()) {
+      AsyncTask<?,?,?> oldTask = networkTask;
+      if (oldTask != null) {
+        oldTask.cancel(true);
+      }
+      networkTask = new NetworkTask();
+      networkTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, query, isbn);
+      headerView.setText(R.string.msg_sbc_searching_book);
+      resultListView.setAdapter(null);
+      queryTextView.setEnabled(false);
+      queryButton.setEnabled(false);
+    }
+  }
+
+  private final class NetworkTask extends AsyncTask<String,Object,JSONObject> {
+
+    @Override
+    protected JSONObject doInBackground(String... args) {
+      try {
+        // These return a JSON result which describes if and where the query was found. This API may
+        // break or disappear at any time in the future. Since this is an API call rather than a
+        // website, we don't use LocaleManager to change the TLD.
+        String theQuery = args[0];
+        String theIsbn = args[1];
+        String uri;
+        if (LocaleManager.isBookSearchUrl(theIsbn)) {
+          int equals = theIsbn.indexOf('=');
+          String volumeId = theIsbn.substring(equals + 1);
+          uri = "http://www.google.com/books?id=" + volumeId + "&jscmd=SearchWithinVolume2&q=" + theQuery;
+        } else {
+          uri = "http://www.google.com/books?vid=isbn" + theIsbn + "&jscmd=SearchWithinVolume2&q=" + theQuery;
+        }
+        CharSequence content = HttpHelper.downloadViaHttp(uri, HttpHelper.ContentType.JSON);
+        return new JSONObject(content.toString());
+      } catch (IOException ioe) {
+        Log.w(TAG, "Error accessing book search", ioe);
+        return null;
+      } catch (JSONException je) {
+        Log.w(TAG, "Error accessing book search", je);
+        return null;
+      }
+    }
+
+    @Override
+    protected void onPostExecute(JSONObject result) {
+      if (result == null) {
+        headerView.setText(R.string.msg_sbc_failed);
+      } else {
+        handleSearchResults(result);
+      }
+      queryTextView.setEnabled(true);
+      queryTextView.selectAll();
+      queryButton.setEnabled(true);
+    }
+
+    // Currently there is no way to distinguish between a query which had no results and a book
+    // which is not searchable - both return zero results.
+    private void handleSearchResults(JSONObject json) {
+      try {
+        int count = json.getInt("number_of_results");
+        headerView.setText(getString(R.string.msg_sbc_results) + " : " + count);
+        if (count > 0) {
+          JSONArray results = json.getJSONArray("search_results");
+          SearchBookContentsResult.setQuery(queryTextView.getText().toString());
+          List<SearchBookContentsResult> items = new ArrayList<>(count);
+          for (int x = 0; x < count; x++) {
+            items.add(parseResult(results.getJSONObject(x)));
+          }
+          resultListView.setOnItemClickListener(new BrowseBookListener(SearchBookContentsActivity.this, items));
+          resultListView.setAdapter(new SearchBookContentsAdapter(SearchBookContentsActivity.this, items));
+        } else {
+          String searchable = json.optString("searchable");
+          if ("false".equals(searchable)) {
+            headerView.setText(R.string.msg_sbc_book_not_searchable);
+          }
+          resultListView.setAdapter(null);
+        }
+      } catch (JSONException e) {
+        Log.w(TAG, "Bad JSON from book search", e);
+        resultListView.setAdapter(null);
+        headerView.setText(R.string.msg_sbc_failed);
+      }
+    }
+
+    // Available fields: page_id, page_number, snippet_text
+    private SearchBookContentsResult parseResult(JSONObject json) {
+
+      String pageId;
+      String pageNumber;
+      String snippet;
+      try {
+        pageId = json.getString("page_id");
+        pageNumber = json.optString("page_number");
+        snippet = json.optString("snippet_text");        
+      } catch (JSONException e) {
+        Log.w(TAG, e);
+        // Never seen in the wild, just being complete.
+        return new SearchBookContentsResult(getString(R.string.msg_sbc_no_page_returned), "", "", false);
+      }
+      
+      if (pageNumber == null || pageNumber.isEmpty()) {
+        // This can happen for text on the jacket, and possibly other reasons.
+        pageNumber = "";
+      } else {
+        pageNumber = getString(R.string.msg_sbc_page) + ' ' + pageNumber;
+      }
+      
+      boolean valid = snippet != null && !snippet.isEmpty();
+      if (valid) {
+        // Remove all HTML tags and encoded characters.          
+        snippet = TAG_PATTERN.matcher(snippet).replaceAll("");
+        snippet = LT_ENTITY_PATTERN.matcher(snippet).replaceAll("<");
+        snippet = GT_ENTITY_PATTERN.matcher(snippet).replaceAll(">");
+        snippet = QUOTE_ENTITY_PATTERN.matcher(snippet).replaceAll("'");
+        snippet = QUOT_ENTITY_PATTERN.matcher(snippet).replaceAll("\"");
+      } else {
+        snippet = '(' + getString(R.string.msg_sbc_snippet_unavailable) + ')';        
+      }
+
+      return new SearchBookContentsResult(pageId, pageNumber, snippet, valid);
+    }
+
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsAdapter.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsAdapter.java
new file mode 100644 (file)
index 0000000..723c1fd
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.book;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+
+import cz.cvut.fel.dce.barcodescanner.R;
+
+import java.util.List;
+
+/**
+ * Manufactures list items which represent SBC results.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+final class SearchBookContentsAdapter extends ArrayAdapter<SearchBookContentsResult> {
+
+  SearchBookContentsAdapter(Context context, List<SearchBookContentsResult> items) {
+    super(context, R.layout.search_book_contents_list_item, 0, items);
+  }
+
+  @Override
+  public View getView(int position, View view, ViewGroup viewGroup) {
+    SearchBookContentsListItem listItem;
+
+    if (view == null) {
+      LayoutInflater factory = LayoutInflater.from(getContext());
+      listItem = (SearchBookContentsListItem) factory.inflate(
+          R.layout.search_book_contents_list_item, viewGroup, false);
+    } else {
+      if (view instanceof SearchBookContentsListItem) {
+        listItem = (SearchBookContentsListItem) view;
+      } else {
+        return view;
+      }
+    }
+
+    SearchBookContentsResult result = getItem(position);
+    listItem.set(result);
+    return listItem;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsListItem.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsListItem.java
new file mode 100644 (file)
index 0000000..2e04cec
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.book;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.style.StyleSpan;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import cz.cvut.fel.dce.barcodescanner.R;
+
+import java.util.Locale;
+
+/**
+ * A list item which displays the page number and snippet of this search result.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class SearchBookContentsListItem extends LinearLayout {
+  private TextView pageNumberView;
+  private TextView snippetView;
+
+  SearchBookContentsListItem(Context context) {
+    super(context);
+  }
+
+  public SearchBookContentsListItem(Context context, AttributeSet attrs) {
+    super(context, attrs);
+  }
+
+  @Override
+  protected void onFinishInflate() {
+    super.onFinishInflate();
+    pageNumberView = (TextView) findViewById(R.id.page_number_view);
+    snippetView = (TextView) findViewById(R.id.snippet_view);
+  }
+
+  public void set(SearchBookContentsResult result) {
+    pageNumberView.setText(result.getPageNumber());
+    String snippet = result.getSnippet();
+    if (snippet.isEmpty()) {
+      snippetView.setText("");
+    } else {
+      if (result.getValidSnippet()) {
+        String lowerQuery = SearchBookContentsResult.getQuery().toLowerCase(Locale.getDefault());
+        String lowerSnippet = snippet.toLowerCase(Locale.getDefault());
+        Spannable styledSnippet = new SpannableString(snippet);
+        StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
+        int queryLength = lowerQuery.length();
+        int offset = 0;
+        while (true) {
+          int pos = lowerSnippet.indexOf(lowerQuery, offset);
+          if (pos < 0) {
+            break;
+          }
+          styledSnippet.setSpan(boldSpan, pos, pos + queryLength, 0);
+          offset = pos + queryLength;
+        }
+        snippetView.setText(styledSnippet);
+      } else {
+        // This may be an error message, so don't try to bold the query terms within it
+        snippetView.setText(snippet);
+      }
+    }
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsResult.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/book/SearchBookContentsResult.java
new file mode 100644 (file)
index 0000000..32c6218
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.book;
+
+/**
+ * The underlying data for a SBC result.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+final class SearchBookContentsResult {
+
+  private static String query = null;
+
+  private final String pageId;
+  private final String pageNumber;
+  private final String snippet;
+  private final boolean validSnippet;
+
+    SearchBookContentsResult(String pageId,
+                             String pageNumber,
+                             String snippet,
+                             boolean validSnippet) {
+    this.pageId = pageId;
+    this.pageNumber = pageNumber;
+    this.snippet = snippet;
+    this.validSnippet = validSnippet;
+  }
+
+  public static void setQuery(String query) {
+    SearchBookContentsResult.query = query;
+  }
+
+  public String getPageId() {
+    return pageId;
+  }
+
+  public String getPageNumber() {
+    return pageNumber;
+  }
+
+  public String getSnippet() {
+    return snippet;
+  }
+
+  public boolean getValidSnippet() {
+    return validSnippet;
+  }
+
+  public static String getQuery() {
+    return query;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/AutoFocusManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/AutoFocusManager.java
new file mode 100644 (file)
index 0000000..d833916
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2012 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.camera;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.hardware.Camera;
+import android.os.AsyncTask;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import cz.cvut.fel.dce.barcodescanner.PreferencesActivity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.RejectedExecutionException;
+
+final class AutoFocusManager implements Camera.AutoFocusCallback {
+
+  private static final String TAG = AutoFocusManager.class.getSimpleName();
+
+  private static final long AUTO_FOCUS_INTERVAL_MS = 2000L;
+  private static final Collection<String> FOCUS_MODES_CALLING_AF;
+  static {
+    FOCUS_MODES_CALLING_AF = new ArrayList<>(2);
+    FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_AUTO);
+    FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_MACRO);
+  }
+
+  private boolean stopped;
+  private boolean focusing;
+  private final boolean useAutoFocus;
+  private final Camera camera;
+  private AsyncTask<?,?,?> outstandingTask;
+
+  AutoFocusManager(Context context, Camera camera) {
+    this.camera = camera;
+    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+    String currentFocusMode = camera.getParameters().getFocusMode();
+    useAutoFocus =
+        sharedPrefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true) &&
+        FOCUS_MODES_CALLING_AF.contains(currentFocusMode);
+    Log.i(TAG, "Current focus mode '" + currentFocusMode + "'; use auto focus? " + useAutoFocus);
+    start();
+  }
+
+  @Override
+  public synchronized void onAutoFocus(boolean success, Camera theCamera) {
+    focusing = false;
+    autoFocusAgainLater();
+  }
+
+  private synchronized void autoFocusAgainLater() {
+    if (!stopped && outstandingTask == null) {
+      AutoFocusTask newTask = new AutoFocusTask();
+      try {
+        newTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+        outstandingTask = newTask;
+      } catch (RejectedExecutionException ree) {
+        Log.w(TAG, "Could not request auto focus", ree);
+      }
+    }
+  }
+
+  synchronized void start() {
+    if (useAutoFocus) {
+      outstandingTask = null;
+      if (!stopped && !focusing) {
+        try {
+          camera.autoFocus(this);
+          focusing = true;
+        } catch (RuntimeException re) {
+          // Have heard RuntimeException reported in Android 4.0.x+; continue?
+          Log.w(TAG, "Unexpected exception while focusing", re);
+          // Try again later to keep cycle going
+          autoFocusAgainLater();
+        }
+      }
+    }
+  }
+
+  private synchronized void cancelOutstandingTask() {
+    if (outstandingTask != null) {
+      if (outstandingTask.getStatus() != AsyncTask.Status.FINISHED) {
+        outstandingTask.cancel(true);
+      }
+      outstandingTask = null;
+    }
+  }
+
+  synchronized void stop() {
+    stopped = true;
+    if (useAutoFocus) {
+      cancelOutstandingTask();
+      // Doesn't hurt to call this even if not focusing
+      try {
+        camera.cancelAutoFocus();
+      } catch (RuntimeException re) {
+        // Have heard RuntimeException reported in Android 4.0.x+; continue?
+        Log.w(TAG, "Unexpected exception while cancelling focusing", re);
+      }
+    }
+  }
+
+  private final class AutoFocusTask extends AsyncTask<Object,Object,Object> {
+    @Override
+    protected Object doInBackground(Object... voids) {
+      try {
+        Thread.sleep(AUTO_FOCUS_INTERVAL_MS);
+      } catch (InterruptedException e) {
+        // continue
+      }
+      start();
+      return null;
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/CameraConfigurationManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/CameraConfigurationManager.java
new file mode 100644 (file)
index 0000000..520bee2
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.camera;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Point;
+import android.hardware.Camera;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.Display;
+import android.view.WindowManager;
+
+import cz.cvut.fel.dce.barcodescanner.PreferencesActivity;
+import com.google.zxing.client.android.camera.CameraConfigurationUtils;
+
+/**
+ * A class which deals with reading, parsing, and setting the camera parameters which are used to
+ * configure the camera hardware.
+ */
+final class CameraConfigurationManager {
+
+  private static final String TAG = "CameraConfiguration";
+
+  private final Context context;
+  private Point screenResolution;
+  private Point cameraResolution;
+
+  CameraConfigurationManager(Context context) {
+    this.context = context;
+  }
+
+  /**
+   * Reads, one time, values from the camera that are needed by the app.
+   */
+  void initFromCameraParameters(Camera camera) {
+    Camera.Parameters parameters = camera.getParameters();
+    WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+    Display display = manager.getDefaultDisplay();
+    Point theScreenResolution = new Point();
+    display.getSize(theScreenResolution);
+    screenResolution = theScreenResolution;
+    Log.i(TAG, "Screen resolution: " + screenResolution);
+    cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
+    Log.i(TAG, "Camera resolution: " + cameraResolution);
+  }
+
+  void setDesiredCameraParameters(Camera camera, boolean safeMode) {
+    Camera.Parameters parameters = camera.getParameters();
+
+    if (parameters == null) {
+      Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
+      return;
+    }
+
+    Log.i(TAG, "Initial camera parameters: " + parameters.flatten());
+
+    if (safeMode) {
+      Log.w(TAG, "In camera config safe mode -- most settings will not be honored");
+    }
+
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+
+    initializeTorch(parameters, prefs, safeMode);
+
+    CameraConfigurationUtils.setFocus(
+                       parameters,
+                       prefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true),
+                       prefs.getBoolean(PreferencesActivity.KEY_DISABLE_CONTINUOUS_FOCUS, true),
+                       safeMode);
+
+    if (!safeMode) {
+      if (prefs.getBoolean(PreferencesActivity.KEY_INVERT_SCAN, false)) {
+        CameraConfigurationUtils.setInvertColor(parameters);
+      }
+
+      if (!prefs.getBoolean(PreferencesActivity.KEY_DISABLE_BARCODE_SCENE_MODE, true)) {
+        CameraConfigurationUtils.setBarcodeSceneMode(parameters);
+      }
+
+      if (!prefs.getBoolean(PreferencesActivity.KEY_DISABLE_METERING, true)) {
+        CameraConfigurationUtils.setVideoStabilization(parameters);
+        CameraConfigurationUtils.setFocusArea(parameters);
+        CameraConfigurationUtils.setMetering(parameters);
+      }
+
+    }
+
+    parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
+
+    Log.i(TAG, "Final camera parameters: " + parameters.flatten());
+
+    camera.setParameters(parameters);
+
+    Camera.Parameters afterParameters = camera.getParameters();
+    Camera.Size afterSize = afterParameters.getPreviewSize();
+    if (afterSize!= null && (cameraResolution.x != afterSize.width || cameraResolution.y != afterSize.height)) {
+      Log.w(TAG, "Camera said it supported preview size " + cameraResolution.x + 'x' + cameraResolution.y +
+                 ", but after setting it, preview size is " + afterSize.width + 'x' + afterSize.height);
+      cameraResolution.x = afterSize.width;
+      cameraResolution.y = afterSize.height;
+    }
+  }
+
+  Point getCameraResolution() {
+    return cameraResolution;
+  }
+
+  Point getScreenResolution() {
+    return screenResolution;
+  }
+
+  boolean getTorchState(Camera camera) {
+    if (camera != null) {
+      Camera.Parameters parameters = camera.getParameters();
+      if (parameters != null) {
+        String flashMode = parameters.getFlashMode();
+        return flashMode != null &&
+            (Camera.Parameters.FLASH_MODE_ON.equals(flashMode) ||
+             Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode));
+      }
+    }
+    return false;
+  }
+
+  void setTorch(Camera camera, boolean newSetting) {
+    Camera.Parameters parameters = camera.getParameters();
+    doSetTorch(parameters, newSetting, false);
+    camera.setParameters(parameters);
+  }
+
+  private void initializeTorch(Camera.Parameters parameters, SharedPreferences prefs, boolean safeMode) {
+    boolean currentSetting = FrontLightMode.readPref(prefs) == FrontLightMode.ON;
+    doSetTorch(parameters, currentSetting, safeMode);
+  }
+
+  private void doSetTorch(Camera.Parameters parameters, boolean newSetting, boolean safeMode) {
+    CameraConfigurationUtils.setTorch(parameters, newSetting);
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+    if (!safeMode && !prefs.getBoolean(PreferencesActivity.KEY_DISABLE_EXPOSURE, true)) {
+      CameraConfigurationUtils.setBestExposure(parameters, newSetting);
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/CameraManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/CameraManager.java
new file mode 100644 (file)
index 0000000..d0706e8
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.camera;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.Camera;
+import android.os.Handler;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import com.google.zxing.PlanarYUVLuminanceSource;
+import cz.cvut.fel.dce.barcodescanner.camera.open.OpenCameraInterface;
+
+import java.io.IOException;
+
+/**
+ * This object wraps the Camera service object and expects to be the only one talking to it. The
+ * implementation encapsulates the steps needed to take preview-sized images, which are used for
+ * both preview and decoding.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class CameraManager {
+
+  private static final String TAG = CameraManager.class.getSimpleName();
+
+  private static final int MIN_FRAME_WIDTH = 240;
+  private static final int MIN_FRAME_HEIGHT = 240;
+  private static final int MAX_FRAME_WIDTH = 1200; // = 5/8 * 1920
+  private static final int MAX_FRAME_HEIGHT = 675; // = 5/8 * 1080
+
+  private final Context context;
+  private final CameraConfigurationManager configManager;
+  private Camera camera;
+  private AutoFocusManager autoFocusManager;
+  private Rect framingRect;
+  private Rect framingRectInPreview;
+  private boolean initialized;
+  private boolean previewing;
+  private int requestedCameraId = OpenCameraInterface.NO_REQUESTED_CAMERA;
+  private int requestedFramingRectWidth;
+  private int requestedFramingRectHeight;
+  /**
+   * Preview frames are delivered here, which we pass on to the registered handler. Make sure to
+   * clear the handler so it will only receive one message.
+   */
+  private final PreviewCallback previewCallback;
+
+  public CameraManager(Context context) {
+    this.context = context;
+    this.configManager = new CameraConfigurationManager(context);
+    previewCallback = new PreviewCallback(configManager);
+  }
+  
+  /**
+   * Opens the camera driver and initializes the hardware parameters.
+   *
+   * @param holder The surface object which the camera will draw preview frames into.
+   * @throws java.io.IOException Indicates the camera driver failed to open.
+   */
+  public synchronized void openDriver(SurfaceHolder holder) throws IOException {
+    Camera theCamera = camera;
+    if (theCamera == null) {
+
+      theCamera = OpenCameraInterface.open(requestedCameraId);
+      if (theCamera == null) {
+        throw new IOException();
+      }
+      camera = theCamera;
+    }
+    theCamera.setPreviewDisplay(holder);
+
+    if (!initialized) {
+      initialized = true;
+      configManager.initFromCameraParameters(theCamera);
+      if (requestedFramingRectWidth > 0 && requestedFramingRectHeight > 0) {
+        setManualFramingRect(requestedFramingRectWidth, requestedFramingRectHeight);
+        requestedFramingRectWidth = 0;
+        requestedFramingRectHeight = 0;
+      }
+    }
+
+    Camera.Parameters parameters = theCamera.getParameters();
+    String parametersFlattened = parameters == null ? null : parameters.flatten(); // Save these, temporarily
+    try {
+      configManager.setDesiredCameraParameters(theCamera, false);
+    } catch (RuntimeException re) {
+      // Driver failed
+      Log.w(TAG, "Camera rejected parameters. Setting only minimal safe-mode parameters");
+      Log.i(TAG, "Resetting to saved camera params: " + parametersFlattened);
+      // Reset:
+      if (parametersFlattened != null) {
+        parameters = theCamera.getParameters();
+        parameters.unflatten(parametersFlattened);
+        try {
+          theCamera.setParameters(parameters);
+          configManager.setDesiredCameraParameters(theCamera, true);
+        } catch (RuntimeException re2) {
+          // Well, darn. Give up
+          Log.w(TAG, "Camera rejected even safe-mode parameters! No configuration");
+        }
+      }
+    }
+
+  }
+
+  public synchronized boolean isOpen() {
+    return camera != null;
+  }
+
+  /**
+   * Closes the camera driver if still in use.
+   */
+  public synchronized void closeDriver() {
+    if (camera != null) {
+      camera.release();
+      camera = null;
+      // Make sure to clear these each time we close the camera, so that any scanning rect
+      // requested by intent is forgotten.
+      framingRect = null;
+      framingRectInPreview = null;
+    }
+  }
+
+  /**
+   * Asks the camera hardware to begin drawing preview frames to the screen.
+   */
+  public synchronized void startPreview() {
+    Camera theCamera = camera;
+    if (theCamera != null && !previewing) {
+      theCamera.startPreview();
+      previewing = true;
+      autoFocusManager = new AutoFocusManager(context, camera);
+    }
+  }
+
+  /**
+   * Tells the camera to stop drawing preview frames.
+   */
+  public synchronized void stopPreview() {
+    if (autoFocusManager != null) {
+      autoFocusManager.stop();
+      autoFocusManager = null;
+    }
+    if (camera != null && previewing) {
+      camera.stopPreview();
+      previewCallback.setHandler(null, 0);
+      previewing = false;
+    }
+  }
+
+  /**
+   * Convenience method for {@link cz.cvut.fel.dce.barcodescanner.CaptureActivity}
+   *
+   * @param newSetting if {@code true}, light should be turned on if currently off. And vice versa.
+   */
+  public synchronized void setTorch(boolean newSetting) {
+    if (newSetting != configManager.getTorchState(camera)) {
+      if (camera != null) {
+        if (autoFocusManager != null) {
+          autoFocusManager.stop();
+        }
+        configManager.setTorch(camera, newSetting);
+        if (autoFocusManager != null) {
+          autoFocusManager.start();
+        }
+      }
+    }
+  }
+
+  /**
+   * A single preview frame will be returned to the handler supplied. The data will arrive as byte[]
+   * in the message.obj field, with width and height encoded as message.arg1 and message.arg2,
+   * respectively.
+   *
+   * @param handler The handler to send the message to.
+   * @param message The what field of the message to be sent.
+   */
+  public synchronized void requestPreviewFrame(Handler handler, int message) {
+    Camera theCamera = camera;
+    if (theCamera != null && previewing) {
+      previewCallback.setHandler(handler, message);
+      theCamera.setOneShotPreviewCallback(previewCallback);
+    }
+  }
+
+  /**
+   * Calculates the framing rect which the UI should draw to show the user where to place the
+   * barcode. This target helps with alignment as well as forces the user to hold the device
+   * far enough away to ensure the image will be in focus.
+   *
+   * @return The rectangle to draw on screen in window coordinates.
+   */
+  public synchronized Rect getFramingRect() {
+    if (framingRect == null) {
+      if (camera == null) {
+        return null;
+      }
+      Point screenResolution = configManager.getScreenResolution();
+      if (screenResolution == null) {
+        // Called early, before init even finished
+        return null;
+      }
+
+      int width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
+      int height = findDesiredDimensionInRange(screenResolution.y, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
+
+      int leftOffset = (screenResolution.x - width) / 2;
+      int topOffset = (screenResolution.y - height) / 2;
+      framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
+      Log.d(TAG, "Calculated framing rect: " + framingRect);
+    }
+    return framingRect;
+  }
+
+  private static int findDesiredDimensionInRange(int resolution, int hardMin, int hardMax) {
+    int dim = 5 * resolution / 8; // Target 5/8 of each dimension
+    if (dim < hardMin) {
+      return hardMin;
+    }
+    if (dim > hardMax) {
+      return hardMax;
+    }
+    return dim;
+  }
+
+  /**
+   * Like {@link #getFramingRect} but coordinates are in terms of the preview frame,
+   * not UI / screen.
+   *
+   * @return {@link android.graphics.Rect} expressing barcode scan area in terms of the preview size
+   */
+  public synchronized Rect getFramingRectInPreview() {
+    if (framingRectInPreview == null) {
+      Rect framingRect = getFramingRect();
+      if (framingRect == null) {
+        return null;
+      }
+      Rect rect = new Rect(framingRect);
+      Point cameraResolution = configManager.getCameraResolution();
+      Point screenResolution = configManager.getScreenResolution();
+      if (cameraResolution == null || screenResolution == null) {
+        // Called early, before init even finished
+        return null;
+      }
+      rect.left = rect.left * cameraResolution.x / screenResolution.x;
+      rect.right = rect.right * cameraResolution.x / screenResolution.x;
+      rect.top = rect.top * cameraResolution.y / screenResolution.y;
+      rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
+      framingRectInPreview = rect;
+    }
+    return framingRectInPreview;
+  }
+
+  
+  /**
+   * Allows third party apps to specify the camera ID, rather than determine
+   * it automatically based on available cameras and their orientation.
+   *
+   * @param cameraId camera ID of the camera to use. A negative value means "no preference".
+   */
+  public synchronized void setManualCameraId(int cameraId) {
+    requestedCameraId = cameraId;
+  }
+  
+  /**
+   * Allows third party apps to specify the scanning rectangle dimensions, rather than determine
+   * them automatically based on screen resolution.
+   *
+   * @param width The width in pixels to scan.
+   * @param height The height in pixels to scan.
+   */
+  public synchronized void setManualFramingRect(int width, int height) {
+    if (initialized) {
+      Point screenResolution = configManager.getScreenResolution();
+      if (width > screenResolution.x) {
+        width = screenResolution.x;
+      }
+      if (height > screenResolution.y) {
+        height = screenResolution.y;
+      }
+      int leftOffset = (screenResolution.x - width) / 2;
+      int topOffset = (screenResolution.y - height) / 2;
+      framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
+      Log.d(TAG, "Calculated manual framing rect: " + framingRect);
+      framingRectInPreview = null;
+    } else {
+      requestedFramingRectWidth = width;
+      requestedFramingRectHeight = height;
+    }
+  }
+
+  /**
+   * A factory method to build the appropriate LuminanceSource object based on the format
+   * of the preview buffers, as described by Camera.Parameters.
+   *
+   * @param data A preview frame.
+   * @param width The width of the image.
+   * @param height The height of the image.
+   * @return A PlanarYUVLuminanceSource instance.
+   */
+  public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
+    Rect rect = getFramingRectInPreview();
+    if (rect == null) {
+      return null;
+    }
+    // Go ahead and assume it's YUV rather than die.
+    return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
+                                        rect.width(), rect.height(), false);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/FrontLightMode.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/FrontLightMode.java
new file mode 100644 (file)
index 0000000..b7ce34e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.camera;
+
+import android.content.SharedPreferences;
+
+import cz.cvut.fel.dce.barcodescanner.PreferencesActivity;
+
+/**
+ * Enumerates settings of the preference controlling the front light.
+ */
+public enum FrontLightMode {
+
+  /** Always on. */
+  ON,
+  /** On only when ambient light is low. */
+  AUTO,
+  /** Always off. */
+  OFF;
+
+  private static FrontLightMode parse(String modeString) {
+    return modeString == null ? OFF : valueOf(modeString);
+  }
+
+  public static FrontLightMode readPref(SharedPreferences sharedPrefs) {
+    return parse(sharedPrefs.getString(PreferencesActivity.KEY_FRONT_LIGHT_MODE, OFF.toString()));
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/PreviewCallback.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/PreviewCallback.java
new file mode 100644 (file)
index 0000000..dcd5646
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.camera;
+
+import android.graphics.Point;
+import android.hardware.Camera;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+final class PreviewCallback implements Camera.PreviewCallback {
+
+  private static final String TAG = PreviewCallback.class.getSimpleName();
+
+  private final CameraConfigurationManager configManager;
+  private Handler previewHandler;
+  private int previewMessage;
+
+  PreviewCallback(CameraConfigurationManager configManager) {
+    this.configManager = configManager;
+  }
+
+  void setHandler(Handler previewHandler, int previewMessage) {
+    this.previewHandler = previewHandler;
+    this.previewMessage = previewMessage;
+  }
+
+  @Override
+  public void onPreviewFrame(byte[] data, Camera camera) {
+    Point cameraResolution = configManager.getCameraResolution();
+    Handler thePreviewHandler = previewHandler;
+    if (cameraResolution != null && thePreviewHandler != null) {
+      Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
+          cameraResolution.y, data);
+      message.sendToTarget();
+      previewHandler = null;
+    } else {
+      Log.d(TAG, "Got preview callback, but no handler or resolution available");
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/open/OpenCameraInterface.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/open/OpenCameraInterface.java
new file mode 100644 (file)
index 0000000..6bf1e3a
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2012 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.camera.open;
+
+import android.hardware.Camera;
+import android.util.Log;
+
+public final class OpenCameraInterface {
+
+  private static final String TAG = OpenCameraInterface.class.getName();
+
+  private OpenCameraInterface() {
+  }
+
+  /** For {@link #open(int)}, means no preference for which camera to open. */
+  public static final int NO_REQUESTED_CAMERA = -1;
+
+  /**
+   * Opens the requested camera with {@link android.hardware.Camera#open(int)}, if one exists.
+   *
+   * @param cameraId camera ID of the camera to use. A negative value
+   *  or {@link #NO_REQUESTED_CAMERA} means "no preference"
+   * @return handle to {@link android.hardware.Camera} that was opened
+   */
+  public static Camera open(int cameraId) {
+    
+    int numCameras = Camera.getNumberOfCameras();
+    if (numCameras == 0) {
+      Log.w(TAG, "No cameras!");
+      return null;
+    }
+
+    boolean explicitRequest = cameraId >= 0;
+
+    if (!explicitRequest) {
+      // Select a camera if no explicit camera requested
+      int index = 0;
+      while (index < numCameras) {
+        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+        Camera.getCameraInfo(index, cameraInfo);
+        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
+          break;
+        }
+        index++;
+      }
+      
+      cameraId = index;
+    }
+
+    Camera camera;
+    if (cameraId < numCameras) {
+      Log.i(TAG, "Opening camera #" + cameraId);
+      camera = Camera.open(cameraId);
+    } else {
+      if (explicitRequest) {
+        Log.w(TAG, "Requested camera does not exist: " + cameraId);
+        camera = null;
+      } else {
+        Log.i(TAG, "No camera facing back; returning camera #0");
+        camera = Camera.open(0);
+      }
+    }
+    
+    return camera;
+  }
+  
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/clipboard/ClipboardInterface.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/clipboard/ClipboardInterface.java
new file mode 100644 (file)
index 0000000..b8d5a6d
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.clipboard;
+
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.util.Log;
+
+public final class ClipboardInterface {
+  
+  private static final String TAG = ClipboardInterface.class.getSimpleName();
+
+  private ClipboardInterface() {
+  }
+
+  public static CharSequence getText(Context context) {
+    ClipboardManager clipboard = getManager(context);
+    ClipData clip = clipboard.getPrimaryClip();
+    return hasText(context) ? clip.getItemAt(0).coerceToText(context) : null;
+  }
+
+  public static void setText(CharSequence text, Context context) {
+    if (text != null) {
+      try {
+        getManager(context).setPrimaryClip(ClipData.newPlainText(null, text));
+      } catch (NullPointerException | IllegalStateException e) {
+        // Have seen this in the wild, bizarrely
+        Log.w(TAG, "Clipboard bug", e);
+      }
+    }
+  }
+
+  public static boolean hasText(Context context) {
+    ClipboardManager clipboard = getManager(context);
+    ClipData clip = clipboard.getPrimaryClip();
+    return clip != null && clip.getItemCount() > 0;
+  }
+  
+  private static ClipboardManager getManager(Context context) {
+    return (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/ContactEncoder.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/ContactEncoder.java
new file mode 100644 (file)
index 0000000..65e7247
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.encode;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * Implementations encode according to some scheme for encoding contact information, like VCard or
+ * MECARD.
+ *
+ * @author Sean Owen
+ */
+abstract class ContactEncoder {
+
+  /**
+   * @return first, the best effort encoding of all data in the appropriate format; second, a
+   *   display-appropriate version of the contact information
+   */
+  abstract String[] encode(List<String> names,
+                           String organization,
+                           List<String> addresses,
+                           List<String> phones,
+                           List<String> phoneTypes,
+                           List<String> emails,
+                           List<String> urls,
+                           String note);
+
+  /**
+   * @return null if s is null or empty, or result of s.trim() otherwise
+   */
+  static String trim(String s) {
+    if (s == null) {
+      return null;
+    }
+    String result = s.trim();
+    return result.isEmpty() ? null : result;
+  }
+
+  static void append(StringBuilder newContents,
+                     StringBuilder newDisplayContents,
+                     String prefix,
+                     String value,
+                     Formatter fieldFormatter,
+                     char terminator) {
+    String trimmed = trim(value);
+    if (trimmed != null) {
+      newContents.append(prefix).append(fieldFormatter.format(trimmed, 0)).append(terminator);
+      newDisplayContents.append(trimmed).append('\n');
+    }
+  }
+
+  static void appendUpToUnique(StringBuilder newContents,
+                               StringBuilder newDisplayContents,
+                               String prefix,
+                               List<String> values,
+                               int max,
+                               Formatter displayFormatter,
+                               Formatter fieldFormatter,
+                               char terminator) {
+    if (values == null) {
+      return;
+    }
+    int count = 0;
+    Collection<String> uniques = new HashSet<>(2);
+    for (int i = 0; i < values.size(); i++) {
+      String value = values.get(i);
+      String trimmed = trim(value);
+      if (trimmed != null && !trimmed.isEmpty() && !uniques.contains(trimmed)) {
+        newContents.append(prefix).append(fieldFormatter.format(trimmed, i)).append(terminator);
+        CharSequence display = displayFormatter == null ? trimmed : displayFormatter.format(trimmed, i);
+        newDisplayContents.append(display).append('\n');
+        if (++count == max) {
+          break;
+        }
+        uniques.add(trimmed);
+      }
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/EncodeActivity.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/EncodeActivity.java
new file mode 100644 (file)
index 0000000..91add77
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.encode;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.Display;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.google.zxing.WriterException;
+import cz.cvut.fel.dce.barcodescanner.Contents;
+import cz.cvut.fel.dce.barcodescanner.FinishListener;
+import cz.cvut.fel.dce.barcodescanner.Intents;
+import cz.cvut.fel.dce.barcodescanner.R;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+/**
+ * This class encodes data from an Intent into a QR code, and then displays it full screen so that
+ * another person can scan it with their device.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class EncodeActivity extends Activity {
+
+  private static final String TAG = EncodeActivity.class.getSimpleName();
+
+  private static final int MAX_BARCODE_FILENAME_LENGTH = 24;
+  private static final Pattern NOT_ALPHANUMERIC = Pattern.compile("[^A-Za-z0-9]");
+  private static final String USE_VCARD_KEY = "USE_VCARD";
+
+  private QRCodeEncoder qrCodeEncoder;
+
+  @Override
+  public void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+    Intent intent = getIntent();
+    if (intent == null) {
+      finish();
+    } else {
+      String action = intent.getAction();
+      if (Intents.Encode.ACTION.equals(action) || Intent.ACTION_SEND.equals(action)) {
+        setContentView(R.layout.encode);
+      } else {
+        finish();
+      }
+    }
+  }
+
+  @Override
+  public boolean onCreateOptionsMenu(Menu menu) {
+    MenuInflater menuInflater = getMenuInflater();
+    menuInflater.inflate(R.menu.encode, menu);
+    boolean useVcard = qrCodeEncoder != null && qrCodeEncoder.isUseVCard();
+    int encodeNameResource = useVcard ? R.string.menu_encode_mecard : R.string.menu_encode_vcard;
+    MenuItem encodeItem = menu.findItem(R.id.menu_encode);
+    encodeItem.setTitle(encodeNameResource);
+    Intent intent = getIntent();
+    if (intent != null) {
+      String type = intent.getStringExtra(Intents.Encode.TYPE);
+      encodeItem.setVisible(Contents.Type.CONTACT.equals(type));
+    }
+    return super.onCreateOptionsMenu(menu);
+  }
+
+  @Override
+  public boolean onOptionsItemSelected(MenuItem item) {
+    switch (item.getItemId()) {
+      case R.id.menu_share:
+        share();
+        return true;
+      case R.id.menu_encode:
+        Intent intent = getIntent();
+        if (intent == null) {
+          return false;
+        }
+        intent.putExtra(USE_VCARD_KEY, !qrCodeEncoder.isUseVCard());
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        startActivity(intent);
+        finish();
+        return true;
+      default:
+        return false;
+    }
+  }
+  
+  private void share() {
+    QRCodeEncoder encoder = qrCodeEncoder;
+    if (encoder == null) { // Odd
+      Log.w(TAG, "No existing barcode to send?");
+      return;
+    }
+
+    String contents = encoder.getContents();
+    if (contents == null) {
+      Log.w(TAG, "No existing barcode to send?");
+      return;
+    }
+
+    Bitmap bitmap;
+    try {
+      bitmap = encoder.encodeAsBitmap();
+    } catch (WriterException we) {
+      Log.w(TAG, we);
+      return;
+    }
+    if (bitmap == null) {
+      return;
+    }
+
+    File bsRoot = new File(Environment.getExternalStorageDirectory(), "BarcodeScanner");
+    File barcodesRoot = new File(bsRoot, "Barcodes");
+    if (!barcodesRoot.exists() && !barcodesRoot.mkdirs()) {
+      Log.w(TAG, "Couldn't make dir " + barcodesRoot);
+      showErrorMessage(R.string.msg_unmount_usb);
+      return;
+    }
+    File barcodeFile = new File(barcodesRoot, makeBarcodeFileName(contents) + ".png");
+    if (!barcodeFile.delete()) {
+      Log.w(TAG, "Could not delete " + barcodeFile);
+      // continue anyway
+    }
+    FileOutputStream fos = null;
+    try {
+      fos = new FileOutputStream(barcodeFile);
+      bitmap.compress(Bitmap.CompressFormat.PNG, 0, fos);
+    } catch (FileNotFoundException fnfe) {
+      Log.w(TAG, "Couldn't access file " + barcodeFile + " due to " + fnfe);
+      showErrorMessage(R.string.msg_unmount_usb);
+      return;
+    } finally {
+      if (fos != null) {
+        try {
+          fos.close();
+        } catch (IOException ioe) {
+          // do nothing
+        }
+      }
+    }
+
+    Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
+    intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name) + " - " + encoder.getTitle());
+    intent.putExtra(Intent.EXTRA_TEXT, contents);
+    intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + barcodeFile.getAbsolutePath()));
+    intent.setType("image/png");
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    startActivity(Intent.createChooser(intent, null));
+  }
+
+  private static CharSequence makeBarcodeFileName(CharSequence contents) {
+    String fileName = NOT_ALPHANUMERIC.matcher(contents).replaceAll("_");
+    if (fileName.length() > MAX_BARCODE_FILENAME_LENGTH) {
+      fileName = fileName.substring(0, MAX_BARCODE_FILENAME_LENGTH);
+    }
+    return fileName;
+  }
+
+  @Override
+  protected void onResume() {
+    super.onResume();
+    // This assumes the view is full screen, which is a good assumption
+    WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
+    Display display = manager.getDefaultDisplay();
+    Point displaySize = new Point();
+    display.getSize(displaySize);
+    int width = displaySize.x;
+    int height = displaySize.y;
+    int smallerDimension = width < height ? width : height;
+    smallerDimension = smallerDimension * 7 / 8;
+
+    Intent intent = getIntent();
+    if (intent == null) {
+      return;
+    }
+
+    try {
+      boolean useVCard = intent.getBooleanExtra(USE_VCARD_KEY, false);
+      qrCodeEncoder = new QRCodeEncoder(this, intent, smallerDimension, useVCard);
+      Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();
+      if (bitmap == null) {
+        Log.w(TAG, "Could not encode barcode");
+        showErrorMessage(R.string.msg_encode_contents_failed);
+        qrCodeEncoder = null;
+        return;
+      }
+
+      ImageView view = (ImageView) findViewById(R.id.image_view);
+      view.setImageBitmap(bitmap);
+
+      TextView contents = (TextView) findViewById(R.id.contents_text_view);
+      if (intent.getBooleanExtra(Intents.Encode.SHOW_CONTENTS, true)) {
+        contents.setText(qrCodeEncoder.getDisplayContents());
+        setTitle(qrCodeEncoder.getTitle());
+      } else {
+        contents.setText("");
+        setTitle("");
+      }
+    } catch (WriterException e) {
+      Log.w(TAG, "Could not encode barcode", e);
+      showErrorMessage(R.string.msg_encode_contents_failed);
+      qrCodeEncoder = null;
+    }
+  }
+
+  private void showErrorMessage(int message) {
+    AlertDialog.Builder builder = new AlertDialog.Builder(this);
+    builder.setMessage(message);
+    builder.setPositiveButton(R.string.button_ok, new FinishListener(this));
+    builder.setOnCancelListener(new FinishListener(this));
+    builder.show();
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/Formatter.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/Formatter.java
new file mode 100644 (file)
index 0000000..6339aea
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.encode;
+
+/**
+ * Encapsulates some simple formatting logic, to aid refactoring in {@link ContactEncoder}.
+ *
+ * @author Sean Owen
+ */
+interface Formatter {
+
+  /**
+   * @param value value to format
+   * @param index index of value in a list of values to be formatted
+   * @return formatted value
+   */
+  CharSequence format(CharSequence value, int index);
+  
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/MECARDContactEncoder.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/MECARDContactEncoder.java
new file mode 100644 (file)
index 0000000..84bb400
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2011 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.encode;
+
+import android.telephony.PhoneNumberUtils;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * Encodes contact information according to the MECARD format.
+ *
+ * @author Sean Owen
+ */
+final class MECARDContactEncoder extends ContactEncoder {
+
+  private static final char TERMINATOR = ';';
+
+  @Override
+  public String[] encode(List<String> names,
+                         String organization,
+                         List<String> addresses,
+                         List<String> phones,
+                         List<String> phoneTypes,
+                         List<String> emails,
+                         List<String> urls,
+                         String note) {
+    StringBuilder newContents = new StringBuilder(100);
+    newContents.append("MECARD:");
+
+    StringBuilder newDisplayContents = new StringBuilder(100);
+
+    Formatter fieldFormatter = new MECARDFieldFormatter();
+
+    appendUpToUnique(newContents, newDisplayContents, "N", names, 1, new
+                     MECARDNameDisplayFormatter(), fieldFormatter, TERMINATOR);
+
+    append(newContents, newDisplayContents, "ORG", organization, fieldFormatter, TERMINATOR);
+
+    appendUpToUnique(newContents, newDisplayContents, "ADR", addresses, 1, null, fieldFormatter, TERMINATOR);
+
+    appendUpToUnique(newContents, newDisplayContents, "TEL", phones, Integer.MAX_VALUE,
+                     new MECARDTelDisplayFormatter(), fieldFormatter, TERMINATOR);
+
+    appendUpToUnique(newContents, newDisplayContents, "EMAIL", emails, Integer.MAX_VALUE, null,
+                     fieldFormatter, TERMINATOR);
+
+    appendUpToUnique(newContents, newDisplayContents, "URL", urls, Integer.MAX_VALUE, null,
+                     fieldFormatter, TERMINATOR);
+
+    append(newContents, newDisplayContents, "NOTE", note, fieldFormatter, TERMINATOR);
+
+    newContents.append(';');
+
+    return new String[] { newContents.toString(), newDisplayContents.toString() };
+  }
+
+  private static class MECARDFieldFormatter implements Formatter {
+    private static final Pattern RESERVED_MECARD_CHARS = Pattern.compile("([\\\\:;])");
+    private static final Pattern NEWLINE = Pattern.compile("\\n");
+    @Override
+    public CharSequence format(CharSequence value, int index) {
+      return ':' + NEWLINE.matcher(RESERVED_MECARD_CHARS.matcher(value).replaceAll("\\\\$1")).replaceAll("");
+    }
+  }
+
+  private static class MECARDTelDisplayFormatter implements Formatter {
+    private static final Pattern NOT_DIGITS = Pattern.compile("[^0-9]+");
+    @Override
+    public CharSequence format(CharSequence value, int index) {
+      return NOT_DIGITS.matcher(PhoneNumberUtils.formatNumber(value.toString())).replaceAll("");
+    }
+  }
+
+  private static class MECARDNameDisplayFormatter implements Formatter {
+    private static final Pattern COMMA = Pattern.compile(",");
+    @Override
+    public CharSequence format(CharSequence value, int index) {
+      return COMMA.matcher(value).replaceAll("");
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/QRCodeEncoder.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/QRCodeEncoder.java
new file mode 100644 (file)
index 0000000..1125a61
--- /dev/null
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.encode;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.Result;
+import com.google.zxing.WriterException;
+import cz.cvut.fel.dce.barcodescanner.Intents;
+import cz.cvut.fel.dce.barcodescanner.Contents;
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.AddressBookParsedResult;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.ResultParser;
+import com.google.zxing.common.BitMatrix;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class does the work of decoding the user's request and extracting all the data
+ * to be encoded in a barcode.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+final class QRCodeEncoder {
+
+  private static final String TAG = QRCodeEncoder.class.getSimpleName();
+
+  private static final int WHITE = 0xFFFFFFFF;
+  private static final int BLACK = 0xFF000000;
+
+  private final Context activity;
+  private String contents;
+  private String displayContents;
+  private String title;
+  private BarcodeFormat format;
+  private final int dimension;
+  private final boolean useVCard;
+
+  QRCodeEncoder(Context activity, Intent intent, int dimension, boolean useVCard) throws WriterException {
+    this.activity = activity;
+    this.dimension = dimension;
+    this.useVCard = useVCard;
+    String action = intent.getAction();
+    if (action.equals(Intents.Encode.ACTION)) {
+      encodeContentsFromZXingIntent(intent);
+    } else if (action.equals(Intent.ACTION_SEND)) {
+      encodeContentsFromShareIntent(intent);
+    }
+  }
+
+  String getContents() {
+    return contents;
+  }
+
+  String getDisplayContents() {
+    return displayContents;
+  }
+
+  String getTitle() {
+    return title;
+  }
+
+  boolean isUseVCard() {
+    return useVCard;
+  }
+
+  // It would be nice if the string encoding lived in the core ZXing library,
+  // but we use platform specific code like PhoneNumberUtils, so it can't.
+  private boolean encodeContentsFromZXingIntent(Intent intent) {
+     // Default to QR_CODE if no format given.
+    String formatString = intent.getStringExtra(Intents.Encode.FORMAT);
+    format = null;
+    if (formatString != null) {
+      try {
+        format = BarcodeFormat.valueOf(formatString);
+      } catch (IllegalArgumentException iae) {
+        // Ignore it then
+      }
+    }
+    if (format == null || format == BarcodeFormat.QR_CODE) {
+      String type = intent.getStringExtra(Intents.Encode.TYPE);
+      if (type == null || type.isEmpty()) {
+        return false;
+      }
+      this.format = BarcodeFormat.QR_CODE;
+      encodeQRCodeContents(intent, type);
+    } else {
+      String data = intent.getStringExtra(Intents.Encode.DATA);
+      if (data != null && !data.isEmpty()) {
+        contents = data;
+        displayContents = data;
+        title = activity.getString(R.string.contents_text);
+      }
+    }
+    return contents != null && !contents.isEmpty();
+  }
+
+  // Handles send intents from multitude of Android applications
+  private void encodeContentsFromShareIntent(Intent intent) throws WriterException {
+    // Check if this is a plain text encoding, or contact
+    if (intent.hasExtra(Intent.EXTRA_STREAM)) {
+      encodeFromStreamExtra(intent);
+    } else {
+      encodeFromTextExtras(intent);
+    }
+  }
+
+  private void encodeFromTextExtras(Intent intent) throws WriterException {
+    // Notice: Google Maps shares both URL and details in one text, bummer!
+    String theContents = ContactEncoder.trim(intent.getStringExtra(Intent.EXTRA_TEXT));
+    if (theContents == null) {
+      theContents = ContactEncoder.trim(intent.getStringExtra("android.intent.extra.HTML_TEXT"));
+      // Intent.EXTRA_HTML_TEXT
+      if (theContents == null) {
+        theContents = ContactEncoder.trim(intent.getStringExtra(Intent.EXTRA_SUBJECT));
+        if (theContents == null) {
+          String[] emails = intent.getStringArrayExtra(Intent.EXTRA_EMAIL);
+          if (emails != null) {
+            theContents = ContactEncoder.trim(emails[0]);
+          } else {
+            theContents = "?";
+          }
+        }
+      }
+    }
+
+    // Trim text to avoid URL breaking.
+    if (theContents == null || theContents.isEmpty()) {
+      throw new WriterException("Empty EXTRA_TEXT");
+    }
+    contents = theContents;
+    // We only do QR code.
+    format = BarcodeFormat.QR_CODE;
+    if (intent.hasExtra(Intent.EXTRA_SUBJECT)) {
+      displayContents = intent.getStringExtra(Intent.EXTRA_SUBJECT);
+    } else if (intent.hasExtra(Intent.EXTRA_TITLE)) {
+      displayContents = intent.getStringExtra(Intent.EXTRA_TITLE);
+    } else {
+      displayContents = contents;
+    }
+    title = activity.getString(R.string.contents_text);
+  }
+
+  // Handles send intents from the Contacts app, retrieving a contact as a VCARD.
+  private void encodeFromStreamExtra(Intent intent) throws WriterException {
+    format = BarcodeFormat.QR_CODE;
+    Bundle bundle = intent.getExtras();
+    if (bundle == null) {
+      throw new WriterException("No extras");
+    }
+    Uri uri = bundle.getParcelable(Intent.EXTRA_STREAM);
+    if (uri == null) {
+      throw new WriterException("No EXTRA_STREAM");
+    }
+    byte[] vcard;
+    String vcardString;
+    InputStream stream = null;
+    try {
+      stream = activity.getContentResolver().openInputStream(uri);
+      if (stream == null) {
+        throw new WriterException("Can't open stream for " + uri);
+      }
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      byte[] buffer = new byte[2048];
+      int bytesRead;
+      while ((bytesRead = stream.read(buffer)) > 0) {
+        baos.write(buffer, 0, bytesRead);
+      }
+      vcard = baos.toByteArray();
+      vcardString = new String(vcard, 0, vcard.length, "UTF-8");
+    } catch (IOException ioe) {
+      throw new WriterException(ioe);
+    } finally {
+      if (stream != null) {
+        try {
+          stream.close();
+        } catch (IOException e) {
+          // continue
+        }
+      }
+    }
+    Log.d(TAG, "Encoding share intent content:");
+    Log.d(TAG, vcardString);
+    Result result = new Result(vcardString, vcard, null, BarcodeFormat.QR_CODE);
+    ParsedResult parsedResult = ResultParser.parseResult(result);
+    if (!(parsedResult instanceof AddressBookParsedResult)) {
+      throw new WriterException("Result was not an address");
+    }
+    encodeQRCodeContents((AddressBookParsedResult) parsedResult);
+    if (contents == null || contents.isEmpty()) {
+      throw new WriterException("No content to encode");
+    }
+  }
+
+  private void encodeQRCodeContents(Intent intent, String type) {
+    switch (type) {
+      case Contents.Type.TEXT: {
+        String data = intent.getStringExtra(Intents.Encode.DATA);
+        if (data != null && !data.isEmpty()) {
+          contents = data;
+          displayContents = data;
+          title = activity.getString(R.string.contents_text);
+        }
+        break;
+      }
+      case Contents.Type.EMAIL: {
+        String data = ContactEncoder.trim(intent.getStringExtra(Intents.Encode.DATA));
+        if (data != null) {
+          contents = "mailto:" + data;
+          displayContents = data;
+          title = activity.getString(R.string.contents_email);
+        }
+        break;
+      }
+      case Contents.Type.PHONE: {
+        String data = ContactEncoder.trim(intent.getStringExtra(Intents.Encode.DATA));
+        if (data != null) {
+          contents = "tel:" + data;
+          displayContents = PhoneNumberUtils.formatNumber(data);
+          title = activity.getString(R.string.contents_phone);
+        }
+        break;
+      }
+      case Contents.Type.SMS: {
+        String data = ContactEncoder.trim(intent.getStringExtra(Intents.Encode.DATA));
+        if (data != null) {
+          contents = "sms:" + data;
+          displayContents = PhoneNumberUtils.formatNumber(data);
+          title = activity.getString(R.string.contents_sms);
+        }
+        break;
+      }
+      case Contents.Type.CONTACT: {
+
+        Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);
+        if (bundle != null) {
+
+          String name = bundle.getString(ContactsContract.Intents.Insert.NAME);
+          String organization = bundle.getString(ContactsContract.Intents.Insert.COMPANY);
+          String address = bundle.getString(ContactsContract.Intents.Insert.POSTAL);
+          List<String> phones = getAllBundleValues(bundle, Contents.PHONE_KEYS);
+          List<String> phoneTypes = getAllBundleValues(bundle, Contents.PHONE_TYPE_KEYS);
+          List<String> emails = getAllBundleValues(bundle, Contents.EMAIL_KEYS);
+          String url = bundle.getString(Contents.URL_KEY);
+          List<String> urls = url == null ? null : Collections.singletonList(url);
+          String note = bundle.getString(Contents.NOTE_KEY);
+
+          ContactEncoder encoder = useVCard ? new VCardContactEncoder() : new MECARDContactEncoder();
+          String[] encoded = encoder.encode(Collections.singletonList(name),
+                                            organization,
+                                            Collections.singletonList(address),
+                                            phones,
+                                            phoneTypes,
+                                            emails,
+                                            urls,
+                                            note);
+          // Make sure we've encoded at least one field.
+          if (!encoded[1].isEmpty()) {
+            contents = encoded[0];
+            displayContents = encoded[1];
+            title = activity.getString(R.string.contents_contact);
+          }
+
+        }
+
+        break;
+      }
+      case Contents.Type.LOCATION: {
+        Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);
+        if (bundle != null) {
+          // These must use Bundle.getFloat(), not getDouble(), it's part of the API.
+          float latitude = bundle.getFloat("LAT", Float.MAX_VALUE);
+          float longitude = bundle.getFloat("LONG", Float.MAX_VALUE);
+          if (latitude != Float.MAX_VALUE && longitude != Float.MAX_VALUE) {
+            contents = "geo:" + latitude + ',' + longitude;
+            displayContents = latitude + "," + longitude;
+            title = activity.getString(R.string.contents_location);
+          }
+        }
+        break;
+      }
+    }
+  }
+
+  private static List<String> getAllBundleValues(Bundle bundle, String[] keys) {
+    List<String> values = new ArrayList<>(keys.length);
+    for (String key : keys) {
+      Object value = bundle.get(key);
+      values.add(value == null ? null : value.toString());
+    }
+    return values;
+  }
+
+  private void encodeQRCodeContents(AddressBookParsedResult contact) {
+    ContactEncoder encoder = useVCard ? new VCardContactEncoder() : new MECARDContactEncoder();
+    String[] encoded = encoder.encode(toList(contact.getNames()),
+                                      contact.getOrg(),
+                                      toList(contact.getAddresses()),
+                                      toList(contact.getPhoneNumbers()),
+                                      null,
+                                      toList(contact.getEmails()),
+                                      toList(contact.getURLs()),
+                                      null);
+    // Make sure we've encoded at least one field.
+    if (!encoded[1].isEmpty()) {
+      contents = encoded[0];
+      displayContents = encoded[1];
+      title = activity.getString(R.string.contents_contact);
+    }
+  }
+
+  private static List<String> toList(String[] values) {
+    return values == null ? null : Arrays.asList(values);
+  }
+
+  Bitmap encodeAsBitmap() throws WriterException {
+    String contentsToEncode = contents;
+    if (contentsToEncode == null) {
+      return null;
+    }
+    Map<EncodeHintType,Object> hints = null;
+    String encoding = guessAppropriateEncoding(contentsToEncode);
+    if (encoding != null) {
+      hints = new EnumMap<>(EncodeHintType.class);
+      hints.put(EncodeHintType.CHARACTER_SET, encoding);
+    }
+    BitMatrix result;
+    try {
+      result = new MultiFormatWriter().encode(contentsToEncode, format, dimension, dimension, hints);
+    } catch (IllegalArgumentException iae) {
+      // Unsupported format
+      return null;
+    }
+    int width = result.getWidth();
+    int height = result.getHeight();
+    int[] pixels = new int[width * height];
+    for (int y = 0; y < height; y++) {
+      int offset = y * width;
+      for (int x = 0; x < width; x++) {
+        pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
+      }
+    }
+
+    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+    bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
+    return bitmap;
+  }
+
+  private static String guessAppropriateEncoding(CharSequence contents) {
+    // Very crude at the moment
+    for (int i = 0; i < contents.length(); i++) {
+      if (contents.charAt(i) > 0xFF) {
+        return "UTF-8";
+      }
+    }
+    return null;
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/VCardContactEncoder.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/VCardContactEncoder.java
new file mode 100644 (file)
index 0000000..d9c0d66
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2011 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.encode;
+
+import android.provider.ContactsContract;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Encodes contact information according to the vCard format.
+ *
+ * @author Sean Owen
+ */
+final class VCardContactEncoder extends ContactEncoder {
+
+  private static final char TERMINATOR = '\n';
+
+  @Override
+  public String[] encode(List<String> names,
+                         String organization,
+                         List<String> addresses,
+                         List<String> phones,
+                         List<String> phoneTypes,
+                         List<String> emails,
+                         List<String> urls,
+                         String note) {
+    StringBuilder newContents = new StringBuilder(100);
+    newContents.append("BEGIN:VCARD").append(TERMINATOR);
+    newContents.append("VERSION:3.0").append(TERMINATOR);
+
+    StringBuilder newDisplayContents = new StringBuilder(100);
+
+    Formatter fieldFormatter = new VCardFieldFormatter();
+
+    appendUpToUnique(newContents, newDisplayContents, "N", names, 1, null, fieldFormatter, TERMINATOR);
+
+    append(newContents, newDisplayContents, "ORG", organization, fieldFormatter, TERMINATOR);
+
+    appendUpToUnique(newContents, newDisplayContents, "ADR", addresses, 1, null, fieldFormatter, TERMINATOR);
+
+    List<Map<String,Set<String>>> phoneMetadata = buildPhoneMetadata(phones, phoneTypes);
+    appendUpToUnique(newContents, newDisplayContents, "TEL", phones, Integer.MAX_VALUE,
+                     new VCardTelDisplayFormatter(phoneMetadata),
+                     new VCardFieldFormatter(phoneMetadata), TERMINATOR);
+
+    appendUpToUnique(newContents, newDisplayContents, "EMAIL", emails, Integer.MAX_VALUE, null,
+                     fieldFormatter, TERMINATOR);
+
+    appendUpToUnique(newContents, newDisplayContents, "URL", urls, Integer.MAX_VALUE, null,
+                     fieldFormatter, TERMINATOR);
+
+    append(newContents, newDisplayContents, "NOTE", note, fieldFormatter, TERMINATOR);
+
+    newContents.append("END:VCARD").append(TERMINATOR);
+
+    return new String[] { newContents.toString(), newDisplayContents.toString() };
+  }
+
+  static List<Map<String,Set<String>>> buildPhoneMetadata(Collection<String> phones, List<String> phoneTypes) {
+    if (phoneTypes == null || phoneTypes.isEmpty()) {
+      return null;
+    }
+    List<Map<String,Set<String>>> metadataForIndex = new ArrayList<>();
+    for (int i = 0; i < phones.size(); i++) {
+      if (phoneTypes.size() <= i) {
+        metadataForIndex.add(null);
+      } else {
+        Map<String,Set<String>> metadata = new HashMap<>();
+        metadataForIndex.add(metadata);
+        Set<String> typeTokens = new HashSet<>();
+        metadata.put("TYPE", typeTokens);
+        String typeString = phoneTypes.get(i);
+        Integer androidType = maybeIntValue(typeString);
+        if (androidType == null) {
+          typeTokens.add(typeString);
+        } else {
+          String purpose = vCardPurposeLabelForAndroidType(androidType);
+          String context = vCardContextLabelForAndroidType(androidType);
+          if (purpose != null) {
+            typeTokens.add(purpose);
+          }
+          if (context != null) {
+            typeTokens.add(context);
+          }
+        }
+      }
+    }
+    return metadataForIndex;
+  }
+
+  private static Integer maybeIntValue(String value) {
+    try {
+      return Integer.valueOf(value);
+    } catch (NumberFormatException nfe) {
+      return null;
+    }
+  }
+
+  private static String vCardPurposeLabelForAndroidType(int androidType) {
+    switch (androidType) {
+      case ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME:
+      case ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK:
+      case ContactsContract.CommonDataKinds.Phone.TYPE_OTHER_FAX:
+        return "fax";
+      case ContactsContract.CommonDataKinds.Phone.TYPE_PAGER:
+      case ContactsContract.CommonDataKinds.Phone.TYPE_WORK_PAGER:
+        return "pager";
+      case ContactsContract.CommonDataKinds.Phone.TYPE_TTY_TDD:
+        return "textphone";
+      case ContactsContract.CommonDataKinds.Phone.TYPE_MMS:
+        return "text";
+      default:
+        return null;
+    }
+  }
+
+  private static String vCardContextLabelForAndroidType(int androidType) {
+    switch (androidType) {
+      case ContactsContract.CommonDataKinds.Phone.TYPE_HOME:
+      case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE:
+      case ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME:
+      case ContactsContract.CommonDataKinds.Phone.TYPE_PAGER:
+        return "home";
+      case ContactsContract.CommonDataKinds.Phone.TYPE_COMPANY_MAIN:
+      case ContactsContract.CommonDataKinds.Phone.TYPE_WORK:
+      case ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE:
+      case ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK:
+      case ContactsContract.CommonDataKinds.Phone.TYPE_WORK_PAGER:
+        return "work";
+      default:
+        return null;
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/VCardFieldFormatter.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/VCardFieldFormatter.java
new file mode 100644 (file)
index 0000000..dd2b27e
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.encode;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * @author Sean Owen
+ */
+final class VCardFieldFormatter implements Formatter {
+
+  private static final Pattern RESERVED_VCARD_CHARS = Pattern.compile("([\\\\,;])");
+  private static final Pattern NEWLINE = Pattern.compile("\\n");
+
+  private final List<Map<String,Set<String>>> metadataForIndex;
+
+  VCardFieldFormatter() {
+    this(null);
+  }
+
+  VCardFieldFormatter(List<Map<String,Set<String>>> metadataForIndex) {
+    this.metadataForIndex = metadataForIndex;
+  }
+
+  @Override
+  public CharSequence format(CharSequence value, int index) {
+    value = RESERVED_VCARD_CHARS.matcher(value).replaceAll("\\\\$1");
+    value = NEWLINE.matcher(value).replaceAll("");
+    Map<String,Set<String>> metadata =
+        metadataForIndex == null || metadataForIndex.size() <= index ? null : metadataForIndex.get(index);
+    value = formatMetadata(value, metadata);
+    return value;
+  }
+
+  private static CharSequence formatMetadata(CharSequence value, Map<String,Set<String>> metadata) {
+    StringBuilder withMetadata = new StringBuilder();
+    if (metadata != null) {
+      for (Map.Entry<String,Set<String>> metadatum : metadata.entrySet()) {
+        Set<String> values = metadatum.getValue();
+        if (values == null || values.isEmpty()) {
+          continue;
+        }
+        withMetadata.append(';').append(metadatum.getKey()).append('=');
+        if (values.size() > 1) {
+          withMetadata.append('"');
+        }
+        Iterator<String> valuesIt = values.iterator();
+        withMetadata.append(valuesIt.next());
+        while (valuesIt.hasNext()) {
+          withMetadata.append(',').append(valuesIt.next());
+        }
+        if (values.size() > 1) {
+          withMetadata.append('"');
+        }
+      }
+    }
+    withMetadata.append(':').append(value);
+    return withMetadata;
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/VCardTelDisplayFormatter.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/encode/VCardTelDisplayFormatter.java
new file mode 100644 (file)
index 0000000..bcb103c
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.encode;
+
+import android.telephony.PhoneNumberUtils;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Sean Owen
+ */
+final class VCardTelDisplayFormatter implements Formatter {
+
+  private final List<Map<String,Set<String>>> metadataForIndex;
+
+  VCardTelDisplayFormatter() {
+    this(null);
+  }
+
+  VCardTelDisplayFormatter(List<Map<String,Set<String>>> metadataForIndex) {
+    this.metadataForIndex = metadataForIndex;
+  }
+
+  @Override
+  public CharSequence format(CharSequence value, int index) {
+    value = PhoneNumberUtils.formatNumber(value.toString());
+    Map<String,Set<String>> metadata =
+        metadataForIndex == null || metadataForIndex.size() <= index ? null : metadataForIndex.get(index);
+    value = formatMetadata(value, metadata);
+    return value;
+  }
+
+  private static CharSequence formatMetadata(CharSequence value, Map<String,Set<String>> metadata) {
+    if (metadata == null || metadata.isEmpty()) {
+      return value;
+    }
+    StringBuilder withMetadata = new StringBuilder();
+    for (Map.Entry<String,Set<String>> metadatum : metadata.entrySet()) {
+      Set<String> values = metadatum.getValue();
+      if (values == null || values.isEmpty()) {
+        continue;
+      }
+      Iterator<String> valuesIt = values.iterator();
+      withMetadata.append(valuesIt.next());
+      while (valuesIt.hasNext()) {
+        withMetadata.append(',').append(valuesIt.next());
+      }
+    }
+    if (withMetadata.length() > 0) {
+      withMetadata.append(' ');
+    }
+    withMetadata.append(value);
+    return withMetadata;
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/DBHelper.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/DBHelper.java
new file mode 100644 (file)
index 0000000..7fa9f85
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.history;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+/**
+ * @author Sean Owen
+ */
+final class DBHelper extends SQLiteOpenHelper {
+
+  private static final int DB_VERSION = 5;
+  private static final String DB_NAME = "barcode_scanner_history.db";
+  static final String TABLE_NAME = "history";
+  static final String ID_COL = "id";
+  static final String TEXT_COL = "text";
+  static final String FORMAT_COL = "format";
+  static final String DISPLAY_COL = "display";
+  static final String TIMESTAMP_COL = "timestamp";
+  static final String DETAILS_COL = "details";
+
+  DBHelper(Context context) {
+    super(context, DB_NAME, null, DB_VERSION);
+  }
+
+  @Override
+  public void onCreate(SQLiteDatabase sqLiteDatabase) {
+    sqLiteDatabase.execSQL(
+            "CREATE TABLE " + TABLE_NAME + " (" +
+            ID_COL + " INTEGER PRIMARY KEY, " +
+            TEXT_COL + " TEXT, " +
+            FORMAT_COL + " TEXT, " +
+            DISPLAY_COL + " TEXT, " +
+            TIMESTAMP_COL + " INTEGER, " +
+            DETAILS_COL + " TEXT);");
+  }
+
+  @Override
+  public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
+    sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
+    onCreate(sqLiteDatabase);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryActivity.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryActivity.java
new file mode 100644 (file)
index 0000000..27aa390
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.history;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ListActivity;
+import android.content.ActivityNotFoundException;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import cz.cvut.fel.dce.barcodescanner.CaptureActivity;
+import cz.cvut.fel.dce.barcodescanner.Intents;
+import cz.cvut.fel.dce.barcodescanner.R;
+
+public final class HistoryActivity extends ListActivity {
+
+  private static final String TAG = HistoryActivity.class.getSimpleName();
+
+  private HistoryManager historyManager;
+  private ArrayAdapter<HistoryItem> adapter;
+  private CharSequence originalTitle;
+  
+  @Override
+  protected void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+    this.historyManager = new HistoryManager(this);  
+    adapter = new HistoryItemAdapter(this);
+    setListAdapter(adapter);
+    View listview = getListView();
+    registerForContextMenu(listview);
+    originalTitle = getTitle();
+  }
+
+  @Override
+  protected void onResume() {
+    super.onResume();
+    reloadHistoryItems();
+  }
+
+  private void reloadHistoryItems() {
+    Iterable<HistoryItem> items = historyManager.buildHistoryItems();
+    adapter.clear();
+    for (HistoryItem item : items) {
+      adapter.add(item);
+    }
+    setTitle(originalTitle + " (" + adapter.getCount() + ')');
+    if (adapter.isEmpty()) {
+      adapter.add(new HistoryItem(null, null, null));
+    }
+  }
+
+  @Override
+  protected void onListItemClick(ListView l, View v, int position, long id) {
+    if (adapter.getItem(position).getResult() != null) {
+      Intent intent = new Intent(this, CaptureActivity.class);
+      intent.putExtra(Intents.History.ITEM_NUMBER, position);
+      setResult(Activity.RESULT_OK, intent);
+      finish();
+    }
+  }
+
+  @Override
+  public void onCreateContextMenu(ContextMenu menu,
+                                  View v,
+                                  ContextMenu.ContextMenuInfo menuInfo) {
+    int position = ((AdapterView.AdapterContextMenuInfo) menuInfo).position;
+    if (position >= adapter.getCount() || adapter.getItem(position).getResult() != null) {
+      menu.add(Menu.NONE, position, position, R.string.history_clear_one_history_text);
+    } // else it's just that dummy "Empty" message
+  }
+
+  @Override
+  public boolean onContextItemSelected(MenuItem item) {
+    int position = item.getItemId();
+    historyManager.deleteHistoryItem(position);
+    reloadHistoryItems();
+    return true;
+  }
+
+  @Override
+  public boolean onCreateOptionsMenu(Menu menu) {
+    if (historyManager.hasHistoryItems()) {
+      MenuInflater menuInflater = getMenuInflater();
+      menuInflater.inflate(R.menu.history, menu);
+    }
+    return super.onCreateOptionsMenu(menu);
+  }
+
+  @Override
+  public boolean onOptionsItemSelected(MenuItem item) {
+    switch (item.getItemId()) {
+      case R.id.menu_history_send:
+        CharSequence history = historyManager.buildHistory();
+        Parcelable historyFile = HistoryManager.saveHistory(history.toString());
+        if (historyFile == null) {
+          AlertDialog.Builder builder = new AlertDialog.Builder(this);
+          builder.setMessage(R.string.msg_unmount_usb);
+          builder.setPositiveButton(R.string.button_ok, null);
+          builder.show();
+        } else {
+          Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
+          intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+          String subject = getResources().getString(R.string.history_email_title);
+          intent.putExtra(Intent.EXTRA_SUBJECT, subject);
+          intent.putExtra(Intent.EXTRA_TEXT, subject);
+          intent.putExtra(Intent.EXTRA_STREAM, historyFile);
+          intent.setType("text/csv");
+          try {
+            startActivity(intent);
+          } catch (ActivityNotFoundException anfe) {
+            Log.w(TAG, anfe.toString());
+          }
+        }
+        break;
+      case R.id.menu_history_clear_text:
+        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        builder.setMessage(R.string.msg_sure);
+        builder.setCancelable(true);
+        builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
+          @Override
+          public void onClick(DialogInterface dialog, int i2) {
+            historyManager.clearHistory();
+            dialog.dismiss();
+            finish();
+          }
+        });
+        builder.setNegativeButton(R.string.button_cancel, null);
+        builder.show();
+        break;
+      default:
+        return super.onOptionsItemSelected(item);
+    }
+    return true;
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryItem.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryItem.java
new file mode 100644 (file)
index 0000000..3f76a51
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.history;
+
+import com.google.zxing.Result;
+
+public final class HistoryItem {
+
+  private final Result result;
+  private final String display;
+  private final String details;
+  
+  HistoryItem(Result result, String display, String details) {
+    this.result = result;
+    this.display = display;
+    this.details = details;
+  }
+
+  public Result getResult() {
+    return result;
+  }
+
+  public String getDisplayAndDetails() {
+    StringBuilder displayResult = new StringBuilder();
+    if (display == null || display.isEmpty()) {
+      displayResult.append(result.getText());
+    } else {
+      displayResult.append(display);
+    }
+    if (details != null && !details.isEmpty()) {
+      displayResult.append(" : ").append(details);
+    }
+    return displayResult.toString();
+  }
+  
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryItemAdapter.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryItemAdapter.java
new file mode 100644 (file)
index 0000000..6151a95
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.history;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.google.zxing.Result;
+import cz.cvut.fel.dce.barcodescanner.R;
+
+import java.util.ArrayList;
+
+final class HistoryItemAdapter extends ArrayAdapter<HistoryItem> {
+
+  private final Context activity;
+
+  HistoryItemAdapter(Context activity) {
+    super(activity, R.layout.history_list_item, new ArrayList<HistoryItem>());
+    this.activity = activity;
+  }
+
+  @Override
+  public View getView(int position, View view, ViewGroup viewGroup) {
+    View layout;
+    if (view instanceof LinearLayout) {
+      layout = view;
+    } else {
+      LayoutInflater factory = LayoutInflater.from(activity);
+      layout = factory.inflate(R.layout.history_list_item, viewGroup, false);
+    }
+
+    HistoryItem item = getItem(position);
+    Result result = item.getResult();
+
+    CharSequence title;
+    CharSequence detail;
+    if (result != null) {
+      title = result.getText();
+      detail = item.getDisplayAndDetails();      
+    } else {
+      Resources resources = getContext().getResources();
+      title = resources.getString(R.string.history_empty);
+      detail = resources.getString(R.string.history_empty_detail);
+    }
+
+    ((TextView) layout.findViewById(R.id.history_title)).setText(title);    
+    ((TextView) layout.findViewById(R.id.history_detail)).setText(detail);
+
+    return layout;
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/history/HistoryManager.java
new file mode 100644 (file)
index 0000000..4f9a934
--- /dev/null
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2009 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.history;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.net.Uri;
+import android.os.Environment;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.Result;
+import cz.cvut.fel.dce.barcodescanner.Intents;
+import cz.cvut.fel.dce.barcodescanner.PreferencesActivity;
+import cz.cvut.fel.dce.barcodescanner.result.ResultHandler;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>Manages functionality related to scan history.</p>
+ *
+ * @author Sean Owen
+ */
+public final class HistoryManager {
+
+  private static final String TAG = HistoryManager.class.getSimpleName();
+
+  private static final int MAX_ITEMS = 2000;
+
+  private static final String[] COLUMNS = {
+      DBHelper.TEXT_COL,
+      DBHelper.DISPLAY_COL,
+      DBHelper.FORMAT_COL,
+      DBHelper.TIMESTAMP_COL,
+      DBHelper.DETAILS_COL,
+  };
+
+  private static final String[] COUNT_COLUMN = { "COUNT(1)" };
+
+  private static final String[] ID_COL_PROJECTION = { DBHelper.ID_COL };
+  private static final String[] ID_DETAIL_COL_PROJECTION = { DBHelper.ID_COL, DBHelper.DETAILS_COL };
+
+  private final Activity activity;
+  private final boolean enableHistory;
+
+  public HistoryManager(Activity activity) {
+    this.activity = activity;
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+    enableHistory = prefs.getBoolean(PreferencesActivity.KEY_ENABLE_HISTORY, true);
+  }
+
+  public boolean hasHistoryItems() {
+    SQLiteOpenHelper helper = new DBHelper(activity);
+    SQLiteDatabase db = null;
+    Cursor cursor = null;
+    try {
+      db = helper.getReadableDatabase();
+      cursor = db.query(DBHelper.TABLE_NAME, COUNT_COLUMN, null, null, null, null, null);
+      cursor.moveToFirst();
+      return cursor.getInt(0) > 0;
+    } finally {
+      close(cursor, db);
+    }
+  }
+
+  public List<HistoryItem> buildHistoryItems() {
+    SQLiteOpenHelper helper = new DBHelper(activity);
+    List<HistoryItem> items = new ArrayList<>();
+    SQLiteDatabase db = null;
+    Cursor cursor = null;
+    try {
+      db = helper.getReadableDatabase();
+      cursor = db.query(DBHelper.TABLE_NAME, COLUMNS, null, null, null, null, DBHelper.TIMESTAMP_COL + " DESC");
+      while (cursor.moveToNext()) {
+        String text = cursor.getString(0);
+        String display = cursor.getString(1);
+        String format = cursor.getString(2);
+        long timestamp = cursor.getLong(3);
+        String details = cursor.getString(4);
+        Result result = new Result(text, null, null, BarcodeFormat.valueOf(format), timestamp);
+        items.add(new HistoryItem(result, display, details));
+      }
+    } finally {
+      close(cursor, db);
+    }
+    return items;
+  }
+
+  public HistoryItem buildHistoryItem(int number) {
+    SQLiteOpenHelper helper = new DBHelper(activity);
+    SQLiteDatabase db = null;
+    Cursor cursor = null;
+    try {
+      db = helper.getReadableDatabase();
+      cursor = db.query(DBHelper.TABLE_NAME, COLUMNS, null, null, null, null, DBHelper.TIMESTAMP_COL + " DESC");
+      cursor.move(number + 1);
+      String text = cursor.getString(0);
+      String display = cursor.getString(1);
+      String format = cursor.getString(2);
+      long timestamp = cursor.getLong(3);
+      String details = cursor.getString(4);
+      Result result = new Result(text, null, null, BarcodeFormat.valueOf(format), timestamp);
+      return new HistoryItem(result, display, details);
+    } finally {
+      close(cursor, db);
+    }
+  }
+  
+  public void deleteHistoryItem(int number) {
+    SQLiteOpenHelper helper = new DBHelper(activity);
+    SQLiteDatabase db = null;
+    Cursor cursor = null;
+    try {
+      db = helper.getWritableDatabase();      
+      cursor = db.query(DBHelper.TABLE_NAME,
+                        ID_COL_PROJECTION,
+                        null, null, null, null,
+                        DBHelper.TIMESTAMP_COL + " DESC");
+      cursor.move(number + 1);
+      db.delete(DBHelper.TABLE_NAME, DBHelper.ID_COL + '=' + cursor.getString(0), null);
+    } finally {
+      close(cursor, db);
+    }
+  }
+
+  public void addHistoryItem(Result result, ResultHandler handler) {
+    // Do not save this item to the history if the preference is turned off, or the contents are
+    // considered secure.
+    if (!activity.getIntent().getBooleanExtra(Intents.Scan.SAVE_HISTORY, true) ||
+        handler.areContentsSecure() || !enableHistory) {
+      return;
+    }
+
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+    if (!prefs.getBoolean(PreferencesActivity.KEY_REMEMBER_DUPLICATES, false)) {
+      deletePrevious(result.getText());
+    }
+
+    ContentValues values = new ContentValues();
+    values.put(DBHelper.TEXT_COL, result.getText());
+    values.put(DBHelper.FORMAT_COL, result.getBarcodeFormat().toString());
+    values.put(DBHelper.DISPLAY_COL, handler.getDisplayContents().toString());
+    values.put(DBHelper.TIMESTAMP_COL, System.currentTimeMillis());
+
+    SQLiteOpenHelper helper = new DBHelper(activity);
+    SQLiteDatabase db = null;
+    try {
+      db = helper.getWritableDatabase();      
+      // Insert the new entry into the DB.
+      db.insert(DBHelper.TABLE_NAME, DBHelper.TIMESTAMP_COL, values);
+    } finally {
+      close(null, db);
+    }
+  }
+
+  public void addHistoryItemDetails(String itemID, String itemDetails) {
+    // As we're going to do an update only we don't need need to worry
+    // about the preferences; if the item wasn't saved it won't be udpated
+    SQLiteOpenHelper helper = new DBHelper(activity);
+    SQLiteDatabase db = null;    
+    Cursor cursor = null;
+    try {
+      db = helper.getWritableDatabase();
+      cursor = db.query(DBHelper.TABLE_NAME,
+                        ID_DETAIL_COL_PROJECTION,
+                        DBHelper.TEXT_COL + "=?",
+                        new String[] { itemID },
+                        null,
+                        null,
+                        DBHelper.TIMESTAMP_COL + " DESC",
+                        "1");
+      String oldID = null;
+      String oldDetails = null;
+      if (cursor.moveToNext()) {
+        oldID = cursor.getString(0);
+        oldDetails = cursor.getString(1);
+      }
+
+      if (oldID != null) {
+        String newDetails;
+        if (oldDetails == null) {
+          newDetails = itemDetails;
+        } else if (oldDetails.contains(itemDetails)) {
+          newDetails = null;
+        } else {
+          newDetails = oldDetails + " : " + itemDetails;
+        } 
+        if (newDetails != null) {
+          ContentValues values = new ContentValues();
+          values.put(DBHelper.DETAILS_COL, newDetails);
+          db.update(DBHelper.TABLE_NAME, values, DBHelper.ID_COL + "=?", new String[] { oldID });
+        }
+      }
+
+    } finally {
+      close(cursor, db);
+    }
+  }
+
+  private void deletePrevious(String text) {
+    SQLiteOpenHelper helper = new DBHelper(activity);
+    SQLiteDatabase db = null;
+    try {
+      db = helper.getWritableDatabase();      
+      db.delete(DBHelper.TABLE_NAME, DBHelper.TEXT_COL + "=?", new String[] { text });
+    } finally {
+      close(null, db);
+    }
+  }
+
+  public void trimHistory() {
+    SQLiteOpenHelper helper = new DBHelper(activity);
+    SQLiteDatabase db = null;
+    Cursor cursor = null;
+    try {
+      db = helper.getWritableDatabase();      
+      cursor = db.query(DBHelper.TABLE_NAME,
+                        ID_COL_PROJECTION,
+                        null, null, null, null,
+                        DBHelper.TIMESTAMP_COL + " DESC");
+      cursor.move(MAX_ITEMS);
+      while (cursor.moveToNext()) {
+        String id = cursor.getString(0);
+        Log.i(TAG, "Deleting scan history ID " + id);
+        db.delete(DBHelper.TABLE_NAME, DBHelper.ID_COL + '=' + id, null);
+      }
+    } catch (SQLiteException sqle) {
+      // We're seeing an error here when called in CaptureActivity.onCreate() in rare cases
+      // and don't understand it. First theory is that it's transient so can be safely ignored.
+      Log.w(TAG, sqle);
+      // continue
+    } finally {
+      close(cursor, db);
+    }
+  }
+
+  /**
+   * <p>Builds a text representation of the scanning history. Each scan is encoded on one
+   * line, terminated by a line break (\r\n). The values in each line are comma-separated,
+   * and double-quoted. Double-quotes within values are escaped with a sequence of two
+   * double-quotes. The fields output are:</p>
+   *
+   * <ol>
+   *  <li>Raw text</li>
+   *  <li>Display text</li>
+   *  <li>Format (e.g. QR_CODE)</li>
+   *  <li>Unix timestamp (milliseconds since the epoch)</li>
+   *  <li>Formatted version of timestamp</li>
+   *  <li>Supplemental info (e.g. price info for a product barcode)</li>
+   * </ol>
+   */
+  CharSequence buildHistory() {
+    SQLiteOpenHelper helper = new DBHelper(activity);
+    SQLiteDatabase db = null;
+    Cursor cursor = null;
+    try {
+      db = helper.getWritableDatabase();
+      cursor = db.query(DBHelper.TABLE_NAME,
+                        COLUMNS,
+                        null, null, null, null,
+                        DBHelper.TIMESTAMP_COL + " DESC");
+
+      DateFormat format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
+      StringBuilder historyText = new StringBuilder(1000);
+      while (cursor.moveToNext()) {
+
+        historyText.append('"').append(massageHistoryField(cursor.getString(0))).append("\",");
+        historyText.append('"').append(massageHistoryField(cursor.getString(1))).append("\",");
+        historyText.append('"').append(massageHistoryField(cursor.getString(2))).append("\",");
+        historyText.append('"').append(massageHistoryField(cursor.getString(3))).append("\",");
+
+        // Add timestamp again, formatted
+        long timestamp = cursor.getLong(3);
+        historyText.append('"').append(massageHistoryField(
+            format.format(new Date(timestamp)))).append("\",");
+
+        // Above we're preserving the old ordering of columns which had formatted data in position 5
+
+        historyText.append('"').append(massageHistoryField(cursor.getString(4))).append("\"\r\n");
+      }
+      return historyText;
+    } finally {
+      close(cursor, db);
+    }
+  }
+  
+  void clearHistory() {
+    SQLiteOpenHelper helper = new DBHelper(activity);
+    SQLiteDatabase db = null;
+    try {
+      db = helper.getWritableDatabase();      
+      db.delete(DBHelper.TABLE_NAME, null, null);
+    } finally {
+      close(null, db);
+    }
+  }
+
+  static Uri saveHistory(String history) {
+    File bsRoot = new File(Environment.getExternalStorageDirectory(), "BarcodeScanner");
+    File historyRoot = new File(bsRoot, "History");
+    if (!historyRoot.exists() && !historyRoot.mkdirs()) {
+      Log.w(TAG, "Couldn't make dir " + historyRoot);
+      return null;
+    }
+    File historyFile = new File(historyRoot, "history-" + System.currentTimeMillis() + ".csv");
+    OutputStreamWriter out = null;
+    try {
+      out = new OutputStreamWriter(new FileOutputStream(historyFile), Charset.forName("UTF-8"));
+      out.write(history);
+      return Uri.parse("file://" + historyFile.getAbsolutePath());
+    } catch (IOException ioe) {
+      Log.w(TAG, "Couldn't access file " + historyFile + " due to " + ioe);
+      return null;
+    } finally {
+      if (out != null) {
+        try {
+          out.close();
+        } catch (IOException ioe) {
+          // do nothing
+        }
+      }
+    }
+  }
+
+  private static String massageHistoryField(String value) {
+    return value == null ? "" : value.replace("\"","\"\"");
+  }
+  
+  private static void close(Cursor cursor, SQLiteDatabase database) {
+    if (cursor != null) {
+      cursor.close();
+    }
+    if (database != null) {
+      database.close();
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/AddressBookResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/AddressBookResultHandler.java
new file mode 100644 (file)
index 0000000..57bec7c
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+import android.telephony.PhoneNumberUtils;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.style.StyleSpan;
+
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.AddressBookParsedResult;
+import com.google.zxing.client.result.ParsedResult;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Handles address book entries.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class AddressBookResultHandler extends ResultHandler {
+
+  private static final DateFormat[] DATE_FORMATS = {
+    new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH),
+    new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH),
+    new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH),
+    new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH),
+  };
+  static {
+    for (DateFormat format : DATE_FORMATS) {
+      format.setLenient(false);
+    }
+  }
+
+  private static final int[] BUTTON_TEXTS = {
+    R.string.button_add_contact,
+    R.string.button_show_map,
+    R.string.button_dial,
+    R.string.button_email,
+  };
+
+  private final boolean[] fields;
+  private int buttonCount;
+
+  // This takes all the work out of figuring out which buttons/actions should be in which
+  // positions, based on which fields are present in this barcode.
+  private int mapIndexToAction(int index) {
+    if (index < buttonCount) {
+      int count = -1;
+      for (int x = 0; x < MAX_BUTTON_COUNT; x++) {
+        if (fields[x]) {
+          count++;
+        }
+        if (count == index) {
+          return x;
+        }
+      }
+    }
+    return -1;
+  }
+
+  public AddressBookResultHandler(Activity activity, ParsedResult result) {
+    super(activity, result);
+    AddressBookParsedResult addressResult = (AddressBookParsedResult) result;
+    String[] addresses = addressResult.getAddresses();
+    boolean hasAddress = addresses != null && addresses.length > 0 && addresses[0] != null && !addresses[0].isEmpty();
+    String[] phoneNumbers = addressResult.getPhoneNumbers();
+    boolean hasPhoneNumber = phoneNumbers != null && phoneNumbers.length > 0;
+    String[] emails = addressResult.getEmails();
+    boolean hasEmailAddress = emails != null && emails.length > 0;
+
+    fields = new boolean[MAX_BUTTON_COUNT];
+    fields[0] = true; // Add contact is always available
+    fields[1] = hasAddress;
+    fields[2] = hasPhoneNumber;
+    fields[3] = hasEmailAddress;
+
+    buttonCount = 0;
+    for (int x = 0; x < MAX_BUTTON_COUNT; x++) {
+      if (fields[x]) {
+        buttonCount++;
+      }
+    }
+  }
+
+  @Override
+  public int getButtonCount() {
+    return buttonCount;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return BUTTON_TEXTS[mapIndexToAction(index)];
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    AddressBookParsedResult addressResult = (AddressBookParsedResult) getResult();
+    String[] addresses = addressResult.getAddresses();
+    String address1 = addresses == null || addresses.length < 1 ? null : addresses[0];
+    String[] addressTypes = addressResult.getAddressTypes();
+    String address1Type = addressTypes == null || addressTypes.length < 1 ? null : addressTypes[0];
+    int action = mapIndexToAction(index);
+    switch (action) {
+      case 0:
+        addContact(addressResult.getNames(),
+                   addressResult.getNicknames(),
+                   addressResult.getPronunciation(),
+                   addressResult.getPhoneNumbers(),
+                   addressResult.getPhoneTypes(),
+                   addressResult.getEmails(),
+                   addressResult.getEmailTypes(),
+                   addressResult.getNote(),
+                   addressResult.getInstantMessenger(),
+                   address1,
+                   address1Type,
+                   addressResult.getOrg(),
+                   addressResult.getTitle(),
+                   addressResult.getURLs(),
+                   addressResult.getBirthday(),
+                   addressResult.getGeo());
+        break;
+      case 1:
+        searchMap(address1);
+        break;
+      case 2:
+        dialPhone(addressResult.getPhoneNumbers()[0]);
+        break;
+      case 3:
+        sendEmail(addressResult.getEmails(), null, null, null, null);
+        break;
+      default:
+        break;
+    }
+  }
+
+  private static Date parseDate(String s) {
+    for (DateFormat currentFormat : DATE_FORMATS) {
+      try {
+        return currentFormat.parse(s);
+      } catch (ParseException e) {
+        // continue
+      }
+    }
+    return null;
+  }
+
+  // Overriden so we can hyphenate phone numbers, format birthdays, and bold the name.
+  @Override
+  public CharSequence getDisplayContents() {
+    AddressBookParsedResult result = (AddressBookParsedResult) getResult();
+    StringBuilder contents = new StringBuilder(100);
+    ParsedResult.maybeAppend(result.getNames(), contents);
+    int namesLength = contents.length();
+
+    String pronunciation = result.getPronunciation();
+    if (pronunciation != null && !pronunciation.isEmpty()) {
+      contents.append("\n(");
+      contents.append(pronunciation);
+      contents.append(')');
+    }
+
+    ParsedResult.maybeAppend(result.getTitle(), contents);
+    ParsedResult.maybeAppend(result.getOrg(), contents);
+    ParsedResult.maybeAppend(result.getAddresses(), contents);
+    String[] numbers = result.getPhoneNumbers();
+    if (numbers != null) {
+      for (String number : numbers) {
+        if (number != null) {
+          ParsedResult.maybeAppend(PhoneNumberUtils.formatNumber(number), contents);
+        }
+      }
+    }
+    ParsedResult.maybeAppend(result.getEmails(), contents);
+    ParsedResult.maybeAppend(result.getURLs(), contents);
+
+    String birthday = result.getBirthday();
+    if (birthday != null && !birthday.isEmpty()) {
+      Date date = parseDate(birthday);
+      if (date != null) {
+        ParsedResult.maybeAppend(DateFormat.getDateInstance(DateFormat.MEDIUM).format(date.getTime()), contents);
+      }
+    }
+    ParsedResult.maybeAppend(result.getNote(), contents);
+
+    if (namesLength > 0) {
+      // Bold the full name to make it stand out a bit.
+      Spannable styled = new SpannableString(contents.toString());
+      styled.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, namesLength, 0);
+      return styled;
+    } else {
+      return contents.toString();
+    }
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_address_book;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/CalendarResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/CalendarResultHandler.java
new file mode 100644 (file)
index 0000000..750f7c8
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.util.Log;
+
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.CalendarParsedResult;
+import com.google.zxing.client.result.ParsedResult;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+/**
+ * Handles calendar entries encoded in QR Codes.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ * @author Sean Owen
+ */
+public final class CalendarResultHandler extends ResultHandler {
+
+  private static final String TAG = CalendarResultHandler.class.getSimpleName();
+
+  private static final int[] buttons = {
+      R.string.button_add_calendar
+  };
+
+  public CalendarResultHandler(Activity activity, ParsedResult result) {
+    super(activity, result);
+  }
+
+  @Override
+  public int getButtonCount() {
+    return buttons.length;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return buttons[index];
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    if (index == 0) {
+      CalendarParsedResult calendarResult = (CalendarParsedResult) getResult();
+
+      String description = calendarResult.getDescription();
+      String organizer = calendarResult.getOrganizer();
+      if (organizer != null) { // No separate Intent key, put in description
+        if (description == null) {
+          description = organizer;
+        } else {
+          description = description + '\n' + organizer;
+        }
+      }
+
+      addCalendarEvent(calendarResult.getSummary(),
+                       calendarResult.getStart(),
+                       calendarResult.isStartAllDay(),
+                       calendarResult.getEnd(),
+                       calendarResult.getLocation(),
+                       description,
+                       calendarResult.getAttendees());
+    }
+  }
+
+  /**
+   * Sends an intent to create a new calendar event by prepopulating the Add Event UI. Older
+   * versions of the system have a bug where the event title will not be filled out.
+   *
+   * @param summary A description of the event
+   * @param start   The start time
+   * @param allDay  if true, event is considered to be all day starting from start time
+   * @param end     The end time (optional)
+   * @param location a text description of the event location
+   * @param description a text description of the event itself
+   * @param attendees attendees to invite
+   */
+  private void addCalendarEvent(String summary,
+                                Date start,
+                                boolean allDay,
+                                Date end,
+                                String location,
+                                String description,
+                                String[] attendees) {
+    Intent intent = new Intent(Intent.ACTION_INSERT);
+    intent.setType("vnd.android.cursor.item/event");
+    long startMilliseconds = start.getTime();
+    intent.putExtra("beginTime", startMilliseconds);
+    if (allDay) {
+      intent.putExtra("allDay", true);
+    }
+    long endMilliseconds;
+    if (end == null) {
+      if (allDay) {
+        // + 1 day
+        endMilliseconds = startMilliseconds + 24 * 60 * 60 * 1000;
+      } else {
+        endMilliseconds = startMilliseconds;
+      }
+    } else {
+      endMilliseconds = end.getTime();
+    }
+    intent.putExtra("endTime", endMilliseconds);
+    intent.putExtra("title", summary);
+    intent.putExtra("eventLocation", location);
+    intent.putExtra("description", description);
+    if (attendees != null) {
+      intent.putExtra(Intent.EXTRA_EMAIL, attendees);
+      // Documentation says this is either a String[] or comma-separated String, which is right?
+    }
+
+    try {
+      // Do this manually at first
+      rawLaunchIntent(intent);
+    } catch (ActivityNotFoundException anfe) {
+      Log.w(TAG, "No calendar app available that responds to " + Intent.ACTION_INSERT);
+      // For calendar apps that don't like "INSERT":
+      intent.setAction(Intent.ACTION_EDIT);
+      launchIntent(intent); // Fail here for real if nothing can handle it
+    }
+  }
+
+
+  @Override
+  public CharSequence getDisplayContents() {
+
+    CalendarParsedResult calResult = (CalendarParsedResult) getResult();
+    StringBuilder result = new StringBuilder(100);
+
+    ParsedResult.maybeAppend(calResult.getSummary(), result);
+
+    Date start = calResult.getStart();
+    ParsedResult.maybeAppend(format(calResult.isStartAllDay(), start), result);
+
+    Date end = calResult.getEnd();
+    if (end != null) {
+      if (calResult.isEndAllDay() && !start.equals(end)) {
+        // Show only year/month/day
+        // if it's all-day and this is the end date, it's exclusive, so show the user
+        // that it ends on the day before to make more intuitive sense.
+        // But don't do it if the event already (incorrectly?) specifies the same start/end
+        end = new Date(end.getTime() - 24 * 60 * 60 * 1000);
+      }
+      ParsedResult.maybeAppend(format(calResult.isEndAllDay(), end), result);
+    }
+
+    ParsedResult.maybeAppend(calResult.getLocation(), result);
+    ParsedResult.maybeAppend(calResult.getOrganizer(), result);
+    ParsedResult.maybeAppend(calResult.getAttendees(), result);
+    ParsedResult.maybeAppend(calResult.getDescription(), result);
+    return result.toString();
+  }
+
+  private static String format(boolean allDay, Date date) {
+    if (date == null) {
+      return null;
+    }
+    DateFormat format = allDay
+        ? DateFormat.getDateInstance(DateFormat.MEDIUM)
+        : DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
+    return format.format(date);
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_calendar;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/EmailAddressResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/EmailAddressResultHandler.java
new file mode 100644 (file)
index 0000000..f729186
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.EmailAddressParsedResult;
+import com.google.zxing.client.result.ParsedResult;
+
+/**
+ * Handles email addresses.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class EmailAddressResultHandler extends ResultHandler {
+  private static final int[] buttons = {
+      R.string.button_email,
+      R.string.button_add_contact
+  };
+
+  public EmailAddressResultHandler(Activity activity, ParsedResult result) {
+    super(activity, result);
+  }
+
+  @Override
+  public int getButtonCount() {
+    return buttons.length;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return buttons[index];
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    EmailAddressParsedResult emailResult = (EmailAddressParsedResult) getResult();
+    switch (index) {
+      case 0:
+        sendEmail(emailResult.getTos(),
+                  emailResult.getCCs(),
+                  emailResult.getBCCs(),
+                  emailResult.getSubject(),
+                  emailResult.getBody());
+        break;
+      case 1:
+        addEmailOnlyContact(emailResult.getTos(), null);
+        break;
+    }
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_email_address;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/GeoResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/GeoResultHandler.java
new file mode 100644 (file)
index 0000000..5c748d0
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.GeoParsedResult;
+import com.google.zxing.client.result.ParsedResult;
+
+/**
+ * Handles geographic coordinates (typically encoded as geo: URLs).
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class GeoResultHandler extends ResultHandler {
+  private static final int[] buttons = {
+      R.string.button_show_map,
+      R.string.button_get_directions
+  };
+
+  public GeoResultHandler(Activity activity, ParsedResult result) {
+    super(activity, result);
+  }
+
+  @Override
+  public int getButtonCount() {
+    return buttons.length;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return buttons[index];
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    GeoParsedResult geoResult = (GeoParsedResult) getResult();
+    switch (index) {
+      case 0:
+        openMap(geoResult.getGeoURI());
+        break;
+      case 1:
+        getDirections(geoResult.getLatitude(), geoResult.getLongitude());
+        break;
+    }
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_geo;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ISBNResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ISBNResultHandler.java
new file mode 100644 (file)
index 0000000..1ffa7cb
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+
+import com.google.zxing.Result;
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.ISBNParsedResult;
+import com.google.zxing.client.result.ParsedResult;
+
+/**
+ * Handles books encoded by their ISBN values.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class ISBNResultHandler extends ResultHandler {
+  private static final int[] buttons = {
+      R.string.button_product_search,
+      R.string.button_book_search,
+      R.string.button_search_book_contents,
+      R.string.button_custom_product_search
+  };
+
+  public ISBNResultHandler(Activity activity, ParsedResult result, Result rawResult) {
+    super(activity, result, rawResult);
+  }
+
+  @Override
+  public int getButtonCount() {
+    return hasCustomProductSearch() ? buttons.length : buttons.length - 1;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return buttons[index];
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    ISBNParsedResult isbnResult = (ISBNParsedResult) getResult();
+    switch (index) {
+      case 0:
+        openProductSearch(isbnResult.getISBN());
+        break;
+      case 1:
+        openBookSearch(isbnResult.getISBN());
+        break;
+      case 2:
+        searchBookContents(isbnResult.getISBN());
+        break;
+      case 3:
+        openURL(fillInCustomSearchURL(isbnResult.getISBN()));
+        break;
+    }
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_isbn;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ProductResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ProductResultHandler.java
new file mode 100644 (file)
index 0000000..9e2acef
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+
+import com.google.zxing.Result;
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.ExpandedProductParsedResult;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.ProductParsedResult;
+
+/**
+ * Handles generic products which are not books.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class ProductResultHandler extends ResultHandler {
+  private static final int[] buttons = {
+      R.string.button_product_search,
+      R.string.button_web_search,
+      R.string.button_custom_product_search
+  };
+
+  public ProductResultHandler(Activity activity, ParsedResult result, Result rawResult) {
+    super(activity, result, rawResult);
+  }
+
+  @Override
+  public int getButtonCount() {
+    return hasCustomProductSearch() ? buttons.length : buttons.length - 1;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return buttons[index];
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    String productID = getProductIDFromResult(getResult());
+    switch (index) {
+      case 0:
+        openProductSearch(productID);
+        break;
+      case 1:
+        webSearch(productID);
+        break;
+      case 2:
+        openURL(fillInCustomSearchURL(productID));
+        break;
+    }
+  }
+
+  private static String getProductIDFromResult(ParsedResult rawResult) {
+    if (rawResult instanceof ProductParsedResult) {
+      return ((ProductParsedResult) rawResult).getNormalizedProductID();
+    }
+    if (rawResult instanceof ExpandedProductParsedResult) {
+      return ((ExpandedProductParsedResult) rawResult).getRawText();
+    }
+    throw new IllegalArgumentException(rawResult.getClass().toString());
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_product;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ResultButtonListener.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ResultButtonListener.java
new file mode 100644 (file)
index 0000000..b1bf0dc
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.view.View;
+
+/**
+ * Handles the result of barcode decoding in the context of the Android platform, by dispatching the
+ * proper intents to open other activities like GMail, Maps, etc.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class ResultButtonListener implements View.OnClickListener {
+  private final ResultHandler resultHandler;
+  private final int index;
+
+  public ResultButtonListener(ResultHandler resultHandler, int index) {
+    this.resultHandler = resultHandler;
+    this.index = index;
+  }
+
+  @Override
+  public void onClick(View view) {
+    resultHandler.handleButtonPress(index);
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ResultHandler.java
new file mode 100644 (file)
index 0000000..0d7a154
--- /dev/null
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.preference.PreferenceManager;
+import android.provider.ContactsContract;
+import android.util.Log;
+
+import com.google.zxing.Result;
+import cz.cvut.fel.dce.barcodescanner.Contents;
+import cz.cvut.fel.dce.barcodescanner.Intents;
+import cz.cvut.fel.dce.barcodescanner.LocaleManager;
+import cz.cvut.fel.dce.barcodescanner.PreferencesActivity;
+import cz.cvut.fel.dce.barcodescanner.R;
+import cz.cvut.fel.dce.barcodescanner.book.SearchBookContentsActivity;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.ParsedResultType;
+import com.google.zxing.client.result.ResultParser;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Locale;
+
+/**
+ * A base class for the Android-specific barcode handlers. These allow the app to polymorphically
+ * suggest the appropriate actions for each data type.
+ *
+ * This class also contains a bunch of utility methods to take common actions like opening a URL.
+ * They could easily be moved into a helper object, but it can't be static because the Activity
+ * instance is needed to launch an intent.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ * @author Sean Owen
+ */
+public abstract class ResultHandler {
+
+  private static final String TAG = ResultHandler.class.getSimpleName();
+
+  private static final String[] EMAIL_TYPE_STRINGS = {"home", "work", "mobile"};
+  private static final String[] PHONE_TYPE_STRINGS = {"home", "work", "mobile", "fax", "pager", "main"};
+  private static final String[] ADDRESS_TYPE_STRINGS = {"home", "work"};
+  private static final int[] EMAIL_TYPE_VALUES = {
+      ContactsContract.CommonDataKinds.Email.TYPE_HOME,
+      ContactsContract.CommonDataKinds.Email.TYPE_WORK,
+      ContactsContract.CommonDataKinds.Email.TYPE_MOBILE,
+  };
+  private static final int[] PHONE_TYPE_VALUES = {
+      ContactsContract.CommonDataKinds.Phone.TYPE_HOME,
+      ContactsContract.CommonDataKinds.Phone.TYPE_WORK,
+      ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE,
+      ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK,
+      ContactsContract.CommonDataKinds.Phone.TYPE_PAGER,
+      ContactsContract.CommonDataKinds.Phone.TYPE_MAIN,
+  };
+  private static final int[] ADDRESS_TYPE_VALUES = {
+      ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME,
+      ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK,
+  };
+  private static final int NO_TYPE = -1;
+
+  public static final int MAX_BUTTON_COUNT = 4;
+
+  private final ParsedResult result;
+  private final Activity activity;
+  private final Result rawResult;
+  private final String customProductSearch;
+
+  ResultHandler(Activity activity, ParsedResult result) {
+    this(activity, result, null);
+  }
+
+  ResultHandler(Activity activity, ParsedResult result, Result rawResult) {
+    this.result = result;
+    this.activity = activity;
+    this.rawResult = rawResult;
+    this.customProductSearch = parseCustomSearchURL();
+  }
+
+  public final ParsedResult getResult() {
+    return result;
+  }
+
+  final boolean hasCustomProductSearch() {
+    return customProductSearch != null;
+  }
+
+  final Activity getActivity() {
+    return activity;
+  }
+
+  /**
+   * Indicates how many buttons the derived class wants shown.
+   *
+   * @return The integer button count.
+   */
+  public abstract int getButtonCount();
+
+  /**
+   * The text of the nth action button.
+   *
+   * @param index From 0 to getButtonCount() - 1
+   * @return The button text as a resource ID
+   */
+  public abstract int getButtonText(int index);
+
+  public Integer getDefaultButtonID() {
+    return null;
+  }
+
+  /**
+   * Execute the action which corresponds to the nth button.
+   *
+   * @param index The button that was clicked.
+   */
+  public abstract void handleButtonPress(int index);
+
+  /**
+   * Some barcode contents are considered secure, and should not be saved to history, copied to
+   * the clipboard, or otherwise persisted.
+   *
+   * @return If true, do not create any permanent record of these contents.
+   */
+  public boolean areContentsSecure() {
+    return false;
+  }
+
+  /**
+   * Create a possibly styled string for the contents of the current barcode.
+   *
+   * @return The text to be displayed.
+   */
+  public CharSequence getDisplayContents() {
+    String contents = result.getDisplayResult();
+    return contents.replace("\r", "");
+  }
+
+  /**
+   * A string describing the kind of barcode that was found, e.g. "Found contact info".
+   *
+   * @return The resource ID of the string.
+   */
+  public abstract int getDisplayTitle();
+
+  /**
+   * A convenience method to get the parsed type. Should not be overridden.
+   *
+   * @return The parsed type, e.g. URI or ISBN
+   */
+  public final ParsedResultType getType() {
+    return result.getType();
+  }
+
+  final void addPhoneOnlyContact(String[] phoneNumbers,String[] phoneTypes) {
+    addContact(null, null, null, phoneNumbers, phoneTypes, null, null, null, null, null, null, null, null, null, null, null);
+  }
+
+  final void addEmailOnlyContact(String[] emails, String[] emailTypes) {
+    addContact(null, null, null, null, null, emails, emailTypes, null, null, null, null, null, null, null, null, null);
+  }
+
+  final void addContact(String[] names,
+                        String[] nicknames,
+                        String pronunciation,
+                        String[] phoneNumbers,
+                        String[] phoneTypes,
+                        String[] emails,
+                        String[] emailTypes,
+                        String note,
+                        String instantMessenger,
+                        String address,
+                        String addressType,
+                        String org,
+                        String title,
+                        String[] urls,
+                        String birthday,
+                        String[] geo) {
+
+    // Only use the first name in the array, if present.
+    Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT, ContactsContract.Contacts.CONTENT_URI);
+    intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
+    putExtra(intent, ContactsContract.Intents.Insert.NAME, names != null ? names[0] : null);
+
+    putExtra(intent, ContactsContract.Intents.Insert.PHONETIC_NAME, pronunciation);
+
+    int phoneCount = Math.min(phoneNumbers != null ? phoneNumbers.length : 0, Contents.PHONE_KEYS.length);
+    for (int x = 0; x < phoneCount; x++) {
+      putExtra(intent, Contents.PHONE_KEYS[x], phoneNumbers[x]);
+      if (phoneTypes != null && x < phoneTypes.length) {
+        int type = toPhoneContractType(phoneTypes[x]);
+        if (type >= 0) {
+          intent.putExtra(Contents.PHONE_TYPE_KEYS[x], type);
+        }
+      }
+    }
+
+    int emailCount = Math.min(emails != null ? emails.length : 0, Contents.EMAIL_KEYS.length);
+    for (int x = 0; x < emailCount; x++) {
+      putExtra(intent, Contents.EMAIL_KEYS[x], emails[x]);
+      if (emailTypes != null && x < emailTypes.length) {
+        int type = toEmailContractType(emailTypes[x]);
+        if (type >= 0) {
+          intent.putExtra(Contents.EMAIL_TYPE_KEYS[x], type);
+        }
+      }
+    }
+
+    ArrayList<ContentValues> data = new ArrayList<>();
+    if (urls != null) {
+      for (String url : urls) {
+        if (url != null && !url.isEmpty()) {
+          ContentValues row = new ContentValues(2);
+          row.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE);
+          row.put(ContactsContract.CommonDataKinds.Website.URL, url);
+          data.add(row);
+          break;
+        }
+      }
+    }
+
+    if (birthday != null) {
+      ContentValues row = new ContentValues(3);
+      row.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE);
+      row.put(ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY);
+      row.put(ContactsContract.CommonDataKinds.Event.START_DATE, birthday);
+      data.add(row);
+    }
+
+    if (nicknames != null) {
+      for (String nickname : nicknames) {
+        if (nickname != null && !nickname.isEmpty()) {
+          ContentValues row = new ContentValues(3);
+          row.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE);
+          row.put(ContactsContract.CommonDataKinds.Nickname.TYPE,
+                  ContactsContract.CommonDataKinds.Nickname.TYPE_DEFAULT);
+          row.put(ContactsContract.CommonDataKinds.Nickname.NAME, nickname);
+          data.add(row);
+          break;
+        }
+      }
+    }
+
+    if (!data.isEmpty()) {
+      intent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, data);
+    }
+
+    StringBuilder aggregatedNotes = new StringBuilder();
+    if (note != null) {
+      aggregatedNotes.append('\n').append(note);
+    }
+    if (geo != null) {
+      aggregatedNotes.append('\n').append(geo[0]).append(',').append(geo[1]);
+    }
+
+    if (aggregatedNotes.length() > 0) {
+      // Remove extra leading '\n'
+      putExtra(intent, ContactsContract.Intents.Insert.NOTES, aggregatedNotes.substring(1));
+    }
+    
+    putExtra(intent, ContactsContract.Intents.Insert.IM_HANDLE, instantMessenger);
+    putExtra(intent, ContactsContract.Intents.Insert.POSTAL, address);
+    if (addressType != null) {
+      int type = toAddressContractType(addressType);
+      if (type >= 0) {
+        intent.putExtra(ContactsContract.Intents.Insert.POSTAL_TYPE, type);
+      }
+    }
+    putExtra(intent, ContactsContract.Intents.Insert.COMPANY, org);
+    putExtra(intent, ContactsContract.Intents.Insert.JOB_TITLE, title);
+    launchIntent(intent);
+  }
+
+  private static int toEmailContractType(String typeString) {
+    return doToContractType(typeString, EMAIL_TYPE_STRINGS, EMAIL_TYPE_VALUES);
+  }
+
+  private static int toPhoneContractType(String typeString) {
+    return doToContractType(typeString, PHONE_TYPE_STRINGS, PHONE_TYPE_VALUES);
+  }
+
+  private static int toAddressContractType(String typeString) {
+    return doToContractType(typeString, ADDRESS_TYPE_STRINGS, ADDRESS_TYPE_VALUES);
+  }
+
+  private static int doToContractType(String typeString, String[] types, int[] values) {
+    if (typeString == null) {
+      return NO_TYPE;
+    }
+    for (int i = 0; i < types.length; i++) {
+      String type = types[i];
+      if (typeString.startsWith(type) || typeString.startsWith(type.toUpperCase(Locale.ENGLISH))) {
+        return values[i];
+      }
+    }
+    return NO_TYPE;
+  }
+
+  final void shareByEmail(String contents) {
+    sendEmail(null, null, null, null, contents);
+  }
+
+  final void sendEmail(String[] to,
+                       String[] cc,
+                       String[] bcc,
+                       String subject,
+                       String body) {
+    Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
+    if (to != null && to.length != 0) {
+      intent.putExtra(Intent.EXTRA_EMAIL, to);
+    }
+    if (cc != null && cc.length != 0) {
+      intent.putExtra(Intent.EXTRA_CC, cc);
+    }
+    if (bcc != null && bcc.length != 0) {
+      intent.putExtra(Intent.EXTRA_BCC, bcc);
+    }
+    putExtra(intent, Intent.EXTRA_SUBJECT, subject);
+    putExtra(intent, Intent.EXTRA_TEXT, body);
+    intent.setType("text/plain");
+    launchIntent(intent);
+  }
+
+  final void shareBySMS(String contents) {
+    sendSMSFromUri("smsto:", contents);
+  }
+
+  final void sendSMS(String phoneNumber, String body) {
+    sendSMSFromUri("smsto:" + phoneNumber, body);
+  }
+
+  final void sendSMSFromUri(String uri, String body) {
+    Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(uri));
+    putExtra(intent, "sms_body", body);
+    // Exit the app once the SMS is sent
+    intent.putExtra("compose_mode", true);
+    launchIntent(intent);
+  }
+
+  final void sendMMS(String phoneNumber, String subject, String body) {
+    sendMMSFromUri("mmsto:" + phoneNumber, subject, body);
+  }
+
+  final void sendMMSFromUri(String uri, String subject, String body) {
+    Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(uri));
+    // The Messaging app needs to see a valid subject or else it will treat this an an SMS.
+    if (subject == null || subject.isEmpty()) {
+      putExtra(intent, "subject", activity.getString(R.string.msg_default_mms_subject));
+    } else {
+      putExtra(intent, "subject", subject);
+    }
+    putExtra(intent, "sms_body", body);
+    intent.putExtra("compose_mode", true);
+    launchIntent(intent);
+  }
+
+  final void dialPhone(String phoneNumber) {
+    launchIntent(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)));
+  }
+
+  final void dialPhoneFromUri(String uri) {
+    launchIntent(new Intent(Intent.ACTION_DIAL, Uri.parse(uri)));
+  }
+
+  final void openMap(String geoURI) {
+    launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(geoURI)));
+  }
+
+  /**
+   * Do a geo search using the address as the query.
+   *
+   * @param address The address to find
+   */
+  final void searchMap(String address) {
+    launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=" + Uri.encode(address))));
+  }
+
+  final void getDirections(double latitude, double longitude) {
+    launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("http://maps.google." +
+        LocaleManager.getCountryTLD(activity) + "/maps?f=d&daddr=" + latitude + ',' + longitude)));
+  }
+
+  // Uses the mobile-specific version of Product Search, which is formatted for small screens.
+  final void openProductSearch(String upc) {
+    Uri uri = Uri.parse("http://www.google." + LocaleManager.getProductSearchCountryTLD(activity) +
+        "/m/products?q=" + upc + "&source=zxing");
+    launchIntent(new Intent(Intent.ACTION_VIEW, uri));
+  }
+
+  final void openBookSearch(String isbn) {
+    Uri uri = Uri.parse("http://books.google." + LocaleManager.getBookSearchCountryTLD(activity) +
+        "/books?vid=isbn" + isbn);
+    launchIntent(new Intent(Intent.ACTION_VIEW, uri));
+  }
+
+  final void searchBookContents(String isbnOrUrl) {
+    Intent intent = new Intent(Intents.SearchBookContents.ACTION);
+    intent.setClassName(activity, SearchBookContentsActivity.class.getName());
+    putExtra(intent, Intents.SearchBookContents.ISBN, isbnOrUrl);
+    launchIntent(intent);
+  }
+
+  final void openURL(String url) {
+    // Strangely, some Android browsers don't seem to register to handle HTTP:// or HTTPS://.
+    // Lower-case these as it should always be OK to lower-case these schemes.
+    if (url.startsWith("HTTP://")) {
+      url = "http" + url.substring(4);
+    } else if (url.startsWith("HTTPS://")) {
+      url = "https" + url.substring(5);
+    }
+    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+    try {
+      launchIntent(intent);
+    } catch (ActivityNotFoundException ignored) {
+      Log.w(TAG, "Nothing available to handle " + intent);
+    }
+  }
+
+  final void webSearch(String query) {
+    Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
+    intent.putExtra("query", query);
+    launchIntent(intent);
+  }
+
+  /**
+   * Like {@link #launchIntent(android.content.Intent)} but will tell you if it is not handle-able
+   * via {@link android.content.ActivityNotFoundException}.
+   *
+   * @throws android.content.ActivityNotFoundException
+   */
+  final void rawLaunchIntent(Intent intent) {
+    if (intent != null) {
+      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+      Log.d(TAG, "Launching intent: " + intent + " with extras: " + intent.getExtras());
+      activity.startActivity(intent);
+    }
+  }
+
+  /**
+   * Like {@link #rawLaunchIntent(android.content.Intent)} but will show a user dialog if nothing is available to handle.
+   */
+  final void launchIntent(Intent intent) {
+    try {
+      rawLaunchIntent(intent);
+    } catch (ActivityNotFoundException ignored) {
+      AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+      builder.setTitle(R.string.app_name);
+      builder.setMessage(R.string.msg_intent_failed);
+      builder.setPositiveButton(R.string.button_ok, null);
+      builder.show();
+    }
+  }
+
+  private static void putExtra(Intent intent, String key, String value) {
+    if (value != null && !value.isEmpty()) {
+      intent.putExtra(key, value);
+    }
+  }
+
+  private String parseCustomSearchURL() {
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+    String customProductSearch = prefs.getString(PreferencesActivity.KEY_CUSTOM_PRODUCT_SEARCH,
+        null);
+    if (customProductSearch != null && customProductSearch.trim().isEmpty()) {
+      return null;
+    }
+    return customProductSearch;
+  }
+
+  final String fillInCustomSearchURL(String text) {
+    if (customProductSearch == null) {
+      return text; // ?
+    }
+    try {
+      text = URLEncoder.encode(text, "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      // can't happen; UTF-8 is always supported. Continue, I guess, without encoding      
+    }
+    String url = customProductSearch;
+    if (rawResult != null) {
+      // Replace %f but only if it doesn't seem to be a hex escape sequence. This remains
+      // problematic but avoids the more surprising problem of breaking escapes
+      url = url.replaceFirst("%f(?![0-9a-f])", rawResult.getBarcodeFormat().toString());
+      if (url.contains("%t")) {
+        ParsedResult parsedResultAgain = ResultParser.parseResult(rawResult);
+        url = url.replace("%t", parsedResultAgain.getType().toString());
+      }
+    }
+    // Replace %s last as it might contain itself %f or %t
+    return url.replace("%s", text);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ResultHandlerFactory.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/ResultHandlerFactory.java
new file mode 100644 (file)
index 0000000..ed7a8c3
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import com.google.zxing.Result;
+import cz.cvut.fel.dce.barcodescanner.CaptureActivity;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.ResultParser;
+
+/**
+ * Manufactures Android-specific handlers based on the barcode content's type.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class ResultHandlerFactory {
+  private ResultHandlerFactory() {
+  }
+
+  public static ResultHandler makeResultHandler(CaptureActivity activity, Result rawResult) {
+    ParsedResult result = parseResult(rawResult);
+    switch (result.getType()) {
+      case ADDRESSBOOK:
+        return new AddressBookResultHandler(activity, result);
+      case EMAIL_ADDRESS:
+        return new EmailAddressResultHandler(activity, result);
+      case PRODUCT:
+        return new ProductResultHandler(activity, result, rawResult);
+      case URI:
+        return new URIResultHandler(activity, result);
+      case WIFI:
+        return new WifiResultHandler(activity, result);
+      case GEO:
+        return new GeoResultHandler(activity, result);
+      case TEL:
+        return new TelResultHandler(activity, result);
+      case SMS:
+        return new SMSResultHandler(activity, result);
+      case CALENDAR:
+        return new CalendarResultHandler(activity, result);
+      case ISBN:
+        return new ISBNResultHandler(activity, result, rawResult);
+      default:
+        return new TextResultHandler(activity, result, rawResult);
+    }
+  }
+
+  private static ParsedResult parseResult(Result rawResult) {
+    return ResultParser.parseResult(rawResult);
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/SMSResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/SMSResultHandler.java
new file mode 100644 (file)
index 0000000..1d6bb8a
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+import android.telephony.PhoneNumberUtils;
+
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.SMSParsedResult;
+
+/**
+ * Handles SMS addresses, offering a choice of composing a new SMS or MMS message.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class SMSResultHandler extends ResultHandler {
+  private static final int[] buttons = {
+      R.string.button_sms,
+      R.string.button_mms
+  };
+
+  public SMSResultHandler(Activity activity, ParsedResult result) {
+    super(activity, result);
+  }
+
+  @Override
+  public int getButtonCount() {
+    return buttons.length;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return buttons[index];
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    SMSParsedResult smsResult = (SMSParsedResult) getResult();
+    String number = smsResult.getNumbers()[0];
+    switch (index) {
+      case 0:
+        // Don't know of a way yet to express a SENDTO intent with multiple recipients
+        sendSMS(number, smsResult.getBody());
+        break;
+      case 1:
+        sendMMS(number, smsResult.getSubject(), smsResult.getBody());
+        break;
+    }
+  }
+
+  @Override
+  public CharSequence getDisplayContents() {
+    SMSParsedResult smsResult = (SMSParsedResult) getResult();
+    String[] rawNumbers = smsResult.getNumbers();
+    String[] formattedNumbers = new String[rawNumbers.length];
+    for (int i = 0; i < rawNumbers.length; i++) {
+      formattedNumbers[i] = PhoneNumberUtils.formatNumber(rawNumbers[i]);
+    }
+    StringBuilder contents = new StringBuilder(50);
+    ParsedResult.maybeAppend(formattedNumbers, contents);
+    ParsedResult.maybeAppend(smsResult.getSubject(), contents);
+    ParsedResult.maybeAppend(smsResult.getBody(), contents);
+    return contents.toString();
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_sms;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/TelResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/TelResultHandler.java
new file mode 100644 (file)
index 0000000..b380b16
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+import android.telephony.PhoneNumberUtils;
+
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.TelParsedResult;
+
+/**
+ * Offers relevant actions for telephone numbers.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class TelResultHandler extends ResultHandler {
+  private static final int[] buttons = {
+      R.string.button_dial,
+      R.string.button_add_contact
+  };
+
+  public TelResultHandler(Activity activity, ParsedResult result) {
+    super(activity, result);
+  }
+
+  @Override
+  public int getButtonCount() {
+    return buttons.length;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return buttons[index];
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    TelParsedResult telResult = (TelParsedResult) getResult();
+    switch (index) {
+      case 0:
+        dialPhoneFromUri(telResult.getTelURI());
+        // When dialer comes up, it allows underlying display activity to continue or something,
+        // but app can't get camera in this state. Avoid issues by just quitting, only in the
+        // case of a phone number
+        getActivity().finish();
+        break;
+      case 1:
+        String[] numbers = new String[1];
+        numbers[0] = telResult.getNumber();
+        addPhoneOnlyContact(numbers, null);
+        break;
+    }
+  }
+
+  // Overriden so we can take advantage of Android's phone number hyphenation routines.
+  @Override
+  public CharSequence getDisplayContents() {
+    String contents = getResult().getDisplayResult();
+    contents = contents.replace("\r", "");
+    return PhoneNumberUtils.formatNumber(contents);
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_tel;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/TextResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/TextResultHandler.java
new file mode 100644 (file)
index 0000000..bf89ab0
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+
+import com.google.zxing.Result;
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.ParsedResult;
+
+/**
+ * This class handles TextParsedResult as well as unknown formats. It's the fallback handler.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class TextResultHandler extends ResultHandler {
+
+  private static final int[] buttons = {
+      R.string.button_web_search,
+      R.string.button_share_by_email,
+      R.string.button_share_by_sms,
+      R.string.button_custom_product_search,
+  };
+
+  public TextResultHandler(Activity activity, ParsedResult result, Result rawResult) {
+    super(activity, result, rawResult);
+  }
+
+  @Override
+  public int getButtonCount() {
+    return hasCustomProductSearch() ? buttons.length : buttons.length - 1;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return buttons[index];
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    String text = getResult().getDisplayResult();
+    switch (index) {
+      case 0:
+        webSearch(text);
+        break;
+      case 1:
+        shareByEmail(text);
+        break;
+      case 2:
+        shareBySMS(text);
+        break;
+      case 3:
+        openURL(fillInCustomSearchURL(text));
+        break;
+    }
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_text;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/URIResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/URIResultHandler.java
new file mode 100644 (file)
index 0000000..7ed2247
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+
+import cz.cvut.fel.dce.barcodescanner.LocaleManager;
+import cz.cvut.fel.dce.barcodescanner.R;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.URIParsedResult;
+
+import java.util.Locale;
+
+/**
+ * Offers appropriate actions for URLS.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class URIResultHandler extends ResultHandler {
+  // URIs beginning with entries in this array will not be saved to history or copied to the
+  // clipboard for security.
+  private static final String[] SECURE_PROTOCOLS = {
+    "otpauth:"
+  };
+
+  private static final int[] buttons = {
+      R.string.button_open_browser,
+      R.string.button_share_by_email,
+      R.string.button_share_by_sms,
+      R.string.button_search_book_contents,
+  };
+
+  public URIResultHandler(Activity activity, ParsedResult result) {
+    super(activity, result);
+  }
+
+  @Override
+  public int getButtonCount() {
+    if (LocaleManager.isBookSearchUrl(((URIParsedResult) getResult()).getURI())) {
+      return buttons.length;
+    }
+    return buttons.length - 1;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return buttons[index];
+  }
+
+  @Override
+  public Integer getDefaultButtonID() {
+    return 0;
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    URIParsedResult uriResult = (URIParsedResult) getResult();
+    String uri = uriResult.getURI();
+    switch (index) {
+      case 0:
+        openURL(uri);
+        break;
+      case 1:
+        shareByEmail(uri);
+        break;
+      case 2:
+        shareBySMS(uri);
+        break;
+      case 3:
+        searchBookContents(uri);
+        break;
+    }
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_uri;
+  }
+
+  @Override
+  public boolean areContentsSecure() {
+    URIParsedResult uriResult = (URIParsedResult) getResult();
+    String uri = uriResult.getURI().toLowerCase(Locale.ENGLISH);
+    for (String secure : SECURE_PROTOCOLS) {
+      if (uri.startsWith(secure)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/WifiResultHandler.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/WifiResultHandler.java
new file mode 100644 (file)
index 0000000..51a9068
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result;
+
+import android.app.Activity;
+import android.content.Context;
+import android.net.wifi.WifiManager;
+import android.os.AsyncTask;
+import android.util.Log;
+import android.widget.Toast;
+
+import cz.cvut.fel.dce.barcodescanner.CaptureActivity;
+import cz.cvut.fel.dce.barcodescanner.R;
+import cz.cvut.fel.dce.barcodescanner.wifi.WifiConfigManager;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.WifiParsedResult;
+
+/**
+ * Handles wifi access information.
+ *
+ * @author Vikram Aggarwal
+ * @author Sean Owen
+ */
+public final class WifiResultHandler extends ResultHandler {
+
+  private static final String TAG = WifiResultHandler.class.getSimpleName();
+
+  private final CaptureActivity parent;
+
+  public WifiResultHandler(CaptureActivity activity, ParsedResult result) {
+    super(activity, result);
+    parent = activity;
+  }
+
+  @Override
+  public int getButtonCount() {
+    // We just need one button, and that is to configure the wireless.  This could change in the future.
+    return 1;
+  }
+
+  @Override
+  public int getButtonText(int index) {
+    return R.string.button_wifi;
+  }
+
+  @Override
+  public void handleButtonPress(int index) {
+    if (index == 0) {
+      WifiParsedResult wifiResult = (WifiParsedResult) getResult();
+      WifiManager wifiManager = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE);
+      if (wifiManager == null) {
+        Log.w(TAG, "No WifiManager available from device");
+        return;
+      }
+      final Activity activity = getActivity();
+      activity.runOnUiThread(new Runnable() {
+        @Override
+        public void run() {
+          Toast.makeText(activity.getApplicationContext(), R.string.wifi_changing_network, Toast.LENGTH_SHORT).show();
+        }
+      });
+      new WifiConfigManager(wifiManager).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, wifiResult);
+      parent.restartPreviewAfterDelay(0L);
+    }
+  }
+
+  // Display the name of the network and the network type to the user.
+  @Override
+  public CharSequence getDisplayContents() {
+    WifiParsedResult wifiResult = (WifiParsedResult) getResult();
+    return wifiResult.getSsid() + " (" + wifiResult.getNetworkEncryption() + ')';
+  }
+
+  @Override
+  public int getDisplayTitle() {
+    return R.string.result_wifi;
+  }
+}
\ No newline at end of file
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/BookResultInfoRetriever.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/BookResultInfoRetriever.java
new file mode 100644 (file)
index 0000000..8142fb1
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2011 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result.supplement;
+
+import android.content.Context;
+import android.widget.TextView;
+
+import cz.cvut.fel.dce.barcodescanner.HttpHelper;
+import cz.cvut.fel.dce.barcodescanner.LocaleManager;
+import cz.cvut.fel.dce.barcodescanner.R;
+import cz.cvut.fel.dce.barcodescanner.history.HistoryManager;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * @author Kamil Kaczmarczyk
+ * @author Sean Owen
+ */
+final class BookResultInfoRetriever extends SupplementalInfoRetriever {
+
+  private final String isbn;
+  private final String source;
+  private final Context context;
+  
+  BookResultInfoRetriever(TextView textView, String isbn, HistoryManager historyManager, Context context) {
+    super(textView, historyManager);
+    this.isbn = isbn;
+    this.source = context.getString(R.string.msg_google_books);
+    this.context = context;
+  }
+
+  @Override
+  void retrieveSupplementalInfo() throws IOException {
+
+    CharSequence contents = HttpHelper.downloadViaHttp("https://www.googleapis.com/books/v1/volumes?q=isbn:" + isbn,
+                                                       HttpHelper.ContentType.JSON);
+
+    if (contents.length() == 0) {
+      return;
+    }
+
+    String title;
+    String pages;
+    Collection<String> authors = null;
+
+    try {
+
+      JSONObject topLevel = (JSONObject) new JSONTokener(contents.toString()).nextValue();
+      JSONArray items = topLevel.optJSONArray("items");
+      if (items == null || items.isNull(0)) {
+        return;
+      }
+
+      JSONObject volumeInfo = ((JSONObject) items.get(0)).getJSONObject("volumeInfo");
+      if (volumeInfo == null) {
+        return;
+      }
+
+      title = volumeInfo.optString("title");
+      pages = volumeInfo.optString("pageCount");
+
+      JSONArray authorsArray = volumeInfo.optJSONArray("authors");
+      if (authorsArray != null && !authorsArray.isNull(0)) {
+        authors = new ArrayList<>(authorsArray.length());
+        for (int i = 0; i < authorsArray.length(); i++) {
+          authors.add(authorsArray.getString(i));
+        }
+      }
+
+    } catch (JSONException e) {
+      throw new IOException(e);
+    }
+
+    Collection<String> newTexts = new ArrayList<>();
+    maybeAddText(title, newTexts);
+    maybeAddTextSeries(authors, newTexts);
+    maybeAddText(pages == null || pages.isEmpty() ? null : pages + "pp.", newTexts);
+    
+    String baseBookUri = "http://www.google." + LocaleManager.getBookSearchCountryTLD(context)
+        + "/search?tbm=bks&source=zxing&q=";
+
+    append(isbn, source, newTexts.toArray(new String[newTexts.size()]), baseBookUri + isbn);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/ProductResultInfoRetriever.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/ProductResultInfoRetriever.java
new file mode 100644 (file)
index 0000000..d45bd21
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result.supplement;
+
+import android.content.Context;
+import android.text.Html;
+import android.widget.TextView;
+
+import cz.cvut.fel.dce.barcodescanner.HttpHelper;
+import cz.cvut.fel.dce.barcodescanner.LocaleManager;
+import cz.cvut.fel.dce.barcodescanner.R;
+import cz.cvut.fel.dce.barcodescanner.history.HistoryManager;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * <p>Retrieves product information from Google Product search.</p>
+ *
+ * <p><strong>Please do not reuse this code.</strong> Using results in this way requires permission
+ * from Google, and that is not granted to users via this project.</p>
+ *
+ * @author Sean Owen
+ */
+final class ProductResultInfoRetriever extends SupplementalInfoRetriever {
+
+  private static final Pattern[] PRODUCT_NAME_PRICE_PATTERNS = {
+    Pattern.compile(",event\\)\">([^<]+)</a></h3>.+<span class=psrp>([^<]+)</span>"),
+    Pattern.compile("owb63p\">([^<]+).+zdi3pb\">([^<]+)"),
+  };
+
+  private final String productID;
+  private final String source;
+  private final Context context;
+
+  ProductResultInfoRetriever(TextView textView, String productID, HistoryManager historyManager, Context context) {
+    super(textView, historyManager);
+    this.productID = productID;
+    this.source = context.getString(R.string.msg_google_product);
+    this.context = context;
+  }
+
+  @Override
+  void retrieveSupplementalInfo() throws IOException {
+
+    String encodedProductID = URLEncoder.encode(productID, "UTF-8");
+    String uri = "https://www.google." + LocaleManager.getProductSearchCountryTLD(context)
+            + "/m/products?ie=utf8&oe=utf8&scoring=p&source=zxing&q=" + encodedProductID;
+    CharSequence content = HttpHelper.downloadViaHttp(uri, HttpHelper.ContentType.HTML);
+
+    for (Pattern p : PRODUCT_NAME_PRICE_PATTERNS) {
+      Matcher matcher = p.matcher(content);
+      if (matcher.find()) {
+        append(productID,
+               source,
+               new String[] { unescapeHTML(matcher.group(1)), unescapeHTML(matcher.group(2)) },
+               uri);
+        break;
+      }
+    }
+  }
+
+  private static String unescapeHTML(String raw) {
+    return Html.fromHtml(raw).toString();
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/SupplementalInfoRetriever.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/SupplementalInfoRetriever.java
new file mode 100644 (file)
index 0000000..87fdd83
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result.supplement;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.method.LinkMovementMethod;
+import android.text.style.URLSpan;
+import android.util.Log;
+import android.widget.TextView;
+
+import cz.cvut.fel.dce.barcodescanner.history.HistoryManager;
+import com.google.zxing.client.result.ISBNParsedResult;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.ProductParsedResult;
+import com.google.zxing.client.result.URIParsedResult;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public abstract class SupplementalInfoRetriever extends AsyncTask<Object,Object,Object> {
+
+  private static final String TAG = "SupplementalInfo";
+
+  public static void maybeInvokeRetrieval(TextView textView,
+                                          ParsedResult result,
+                                          HistoryManager historyManager,
+                                          Context context) {
+    if (result instanceof URIParsedResult) {
+      SupplementalInfoRetriever uriRetriever = 
+          new URIResultInfoRetriever(textView, (URIParsedResult) result, historyManager, context);
+      uriRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+      SupplementalInfoRetriever titleRetriever = 
+          new TitleRetriever(textView, (URIParsedResult) result, historyManager);
+      titleRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    } else if (result instanceof ProductParsedResult) {
+      ProductParsedResult productParsedResult = (ProductParsedResult) result;
+      String productID = productParsedResult.getProductID();
+      SupplementalInfoRetriever productRetriever =
+          new ProductResultInfoRetriever(textView, productID, historyManager, context);
+      productRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    } else if (result instanceof ISBNParsedResult) {
+      String isbn = ((ISBNParsedResult) result).getISBN();
+      SupplementalInfoRetriever productInfoRetriever = 
+          new ProductResultInfoRetriever(textView, isbn, historyManager, context);
+      productInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+      SupplementalInfoRetriever bookInfoRetriever = 
+          new BookResultInfoRetriever(textView, isbn, historyManager, context);
+      bookInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    }
+  }
+
+  private final WeakReference<TextView> textViewRef;
+  private final WeakReference<HistoryManager> historyManagerRef;
+  private final Collection<Spannable> newContents;
+  private final Collection<String[]> newHistories;
+
+  SupplementalInfoRetriever(TextView textView, HistoryManager historyManager) {
+    textViewRef = new WeakReference<>(textView);
+    historyManagerRef = new WeakReference<>(historyManager);
+    newContents = new ArrayList<>();
+    newHistories = new ArrayList<>();
+  }
+
+  @Override
+  public final Object doInBackground(Object... args) {
+    try {
+      retrieveSupplementalInfo();
+    } catch (IOException e) {
+      Log.w(TAG, e);
+    }
+    return null;
+  }
+
+  @Override
+  protected final void onPostExecute(Object arg) {
+    TextView textView = textViewRef.get();
+    if (textView != null) {
+      for (CharSequence content : newContents) {
+        textView.append(content);
+      }
+      textView.setMovementMethod(LinkMovementMethod.getInstance());
+    }
+    HistoryManager historyManager = historyManagerRef.get();
+    if (historyManager != null) {
+      for (String[] text : newHistories) {
+        historyManager.addHistoryItemDetails(text[0], text[1]);
+      }
+    }
+  }
+
+  abstract void retrieveSupplementalInfo() throws IOException;
+
+  final void append(String itemID, String source, String[] newTexts, String linkURL) {
+
+    StringBuilder newTextCombined = new StringBuilder();
+
+    if (source != null) {
+      newTextCombined.append(source).append(' ');
+    }
+
+    int linkStart = newTextCombined.length();
+
+    boolean first = true;
+    for (String newText : newTexts) {
+      if (first) {
+        newTextCombined.append(newText);
+        first = false;
+      } else {
+        newTextCombined.append(" [");
+        newTextCombined.append(newText);
+        newTextCombined.append(']');
+      }
+    }
+
+    int linkEnd = newTextCombined.length();
+
+    String newText = newTextCombined.toString();
+    Spannable content = new SpannableString(newText + "\n\n");
+    if (linkURL != null) {
+      // Strangely, some Android browsers don't seem to register to handle HTTP:// or HTTPS://.
+      // Lower-case these as it should always be OK to lower-case these schemes.
+      if (linkURL.startsWith("HTTP://")) {
+        linkURL = "http" + linkURL.substring(4);
+      } else if (linkURL.startsWith("HTTPS://")) {
+        linkURL = "https" + linkURL.substring(5);
+      }
+      content.setSpan(new URLSpan(linkURL), linkStart, linkEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+    }
+
+    newContents.add(content);
+    newHistories.add(new String[] {itemID, newText});
+  }
+  
+  static void maybeAddText(String text, Collection<String> texts) {
+    if (text != null && !text.isEmpty()) {
+      texts.add(text);
+    }
+  }
+  
+  static void maybeAddTextSeries(Collection<String> textSeries, Collection<String> texts) {
+    if (textSeries != null && !textSeries.isEmpty()) {
+      boolean first = true;
+      StringBuilder authorsText = new StringBuilder();
+      for (String author : textSeries) {
+        if (first) {
+          first = false;
+        } else {
+          authorsText.append(", ");
+        }
+        authorsText.append(author);
+      }
+      texts.add(authorsText.toString());
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/TitleRetriever.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/TitleRetriever.java
new file mode 100644 (file)
index 0000000..05e769f
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result.supplement;
+
+import android.widget.TextView;
+
+import cz.cvut.fel.dce.barcodescanner.HttpHelper;
+import cz.cvut.fel.dce.barcodescanner.history.HistoryManager;
+import com.google.zxing.client.result.URIParsedResult;
+
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Retrieves the title of a web page as supplemental info.
+ *
+ * @author Sean Owen
+ */
+final class TitleRetriever extends SupplementalInfoRetriever {
+
+  private static final Pattern TITLE_PATTERN = Pattern.compile("<title>([^<]+)");
+  private static final int MAX_TITLE_LEN = 100;
+
+  private final String httpUrl;
+
+  TitleRetriever(TextView textView, URIParsedResult result, HistoryManager historyManager) {
+    super(textView, historyManager);
+    this.httpUrl = result.getURI();
+  }
+
+  @Override
+  void retrieveSupplementalInfo() {
+    CharSequence contents;
+    try {
+      contents = HttpHelper.downloadViaHttp(httpUrl, HttpHelper.ContentType.HTML, 4096);
+    } catch (IOException ioe) {
+      // ignore this
+      return;
+    }
+    if (contents != null && contents.length() > 0) {
+      Matcher m = TITLE_PATTERN.matcher(contents);
+      if (m.find()) {
+        String title = m.group(1);
+        if (title != null && !title.isEmpty()) {
+          if (title.length() > MAX_TITLE_LEN) {
+            title = title.substring(0, MAX_TITLE_LEN) + "...";
+          }
+          append(httpUrl, null, new String[] {title}, httpUrl);
+        }
+      }
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/URIResultInfoRetriever.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/result/supplement/URIResultInfoRetriever.java
new file mode 100644 (file)
index 0000000..b7c3985
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.result.supplement;
+
+import android.content.Context;
+import android.widget.TextView;
+
+import cz.cvut.fel.dce.barcodescanner.HttpHelper;
+import cz.cvut.fel.dce.barcodescanner.R;
+import cz.cvut.fel.dce.barcodescanner.history.HistoryManager;
+import com.google.zxing.client.result.URIParsedResult;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+final class URIResultInfoRetriever extends SupplementalInfoRetriever {
+
+  private static final int MAX_REDIRECTS = 5;
+
+  private final URIParsedResult result;
+  private final String redirectString;
+
+  URIResultInfoRetriever(TextView textView, URIParsedResult result, HistoryManager historyManager, Context context) {
+    super(textView, historyManager);
+    redirectString = context.getString(R.string.msg_redirect);
+    this.result = result;
+  }
+
+  @Override
+  void retrieveSupplementalInfo() throws IOException {
+    URI oldURI;
+    try {
+      oldURI = new URI(result.getURI());
+    } catch (URISyntaxException ignored) {
+      return;
+    }
+    URI newURI = HttpHelper.unredirect(oldURI);
+    int count = 0;
+    while (count++ < MAX_REDIRECTS && !oldURI.equals(newURI)) {
+      append(result.getDisplayResult(), 
+             null, 
+             new String[] { redirectString + " : " + newURI }, 
+             newURI.toString());
+      oldURI = newURI;
+      newURI = HttpHelper.unredirect(newURI);
+    }
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/AppInfo.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/AppInfo.java
new file mode 100644 (file)
index 0000000..d1fa63d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.share;
+
+import android.graphics.drawable.Drawable;
+
+final class AppInfo implements Comparable<AppInfo> {
+  
+  private final String packageName;
+  private final String label;
+  private final Drawable icon;
+
+  AppInfo(String packageName, String label, Drawable icon) {
+    this.packageName = packageName;
+    this.label = label;
+    this.icon = icon;
+  }
+
+  String getPackageName() {
+    return packageName;
+  }
+  
+  Drawable getIcon() {
+    return icon;
+  }
+
+  @Override
+  public String toString() {
+    return label;
+  }
+
+  @Override
+  public int compareTo(AppInfo another) {
+    return label.compareTo(another.label);
+  }
+  
+  @Override
+  public int hashCode() {
+    return label.hashCode();
+  }
+  
+  @Override
+  public boolean equals(Object other) {
+    if (!(other instanceof AppInfo)) {
+      return false;
+    }
+    AppInfo another = (AppInfo) other;
+    return label.equals(another.label);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/AppPickerActivity.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/AppPickerActivity.java
new file mode 100644 (file)
index 0000000..c0c267f
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.share;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.provider.Browser;
+import android.view.View;
+import android.widget.Adapter;
+import android.widget.ListView;
+
+import java.util.List;
+
+public final class AppPickerActivity extends ListActivity {
+
+  private AsyncTask<Object,Object,List<AppInfo>> backgroundTask;
+
+  @Override
+  protected void onResume() {
+    super.onResume();
+    backgroundTask = new LoadPackagesAsyncTask(this);
+    backgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+  }
+
+  @Override
+  protected void onPause() {
+    AsyncTask<?,?,?> task = backgroundTask;
+    if (task != null) {
+      task.cancel(true);
+      backgroundTask = null;
+    }
+    super.onPause();
+  }
+
+  @Override
+  protected void onListItemClick(ListView l, View view, int position, long id) {
+    Adapter adapter = getListAdapter();
+    if (position >= 0 && position < adapter.getCount()) {
+      String packageName = ((AppInfo) adapter.getItem(position)).getPackageName();
+      Intent intent = new Intent();
+      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+      intent.putExtra(Browser.BookmarkColumns.URL, "market://details?id=" + packageName);
+      setResult(RESULT_OK, intent);
+    } else {
+      setResult(RESULT_CANCELED);      
+    }
+    finish();
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/BookmarkAdapter.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/BookmarkAdapter.java
new file mode 100644 (file)
index 0000000..4e12154
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.share;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import cz.cvut.fel.dce.barcodescanner.R;
+
+/**
+ * A custom adapter designed to fetch bookmarks from a cursor. Before Honeycomb we used
+ * SimpleCursorAdapter, but it assumes the existence of an _id column, and the bookmark schema was
+ * rewritten for HC without one. This caused the app to crash, hence this new class, which is
+ * forwards and backwards compatible.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+final class BookmarkAdapter extends BaseAdapter {
+  private final Context context;
+  private final Cursor cursor;
+
+  BookmarkAdapter(Context context, Cursor cursor) {
+    this.context = context;
+    this.cursor = cursor;
+  }
+
+  @Override
+  public int getCount() {
+    return cursor.getCount();
+  }
+
+  @Override
+  public Object getItem(int index) {
+    // Not used, so no point in retrieving it.
+    return null;
+  }
+
+  @Override
+  public long getItemId(int index) {
+    return index;
+  }
+
+  @Override
+  public View getView(int index, View view, ViewGroup viewGroup) {
+    View layout;
+    if (view instanceof LinearLayout) {
+      layout = view;
+    } else {
+      LayoutInflater factory = LayoutInflater.from(context);
+      layout = factory.inflate(R.layout.bookmark_picker_list_item, viewGroup, false);
+    }
+
+    if (!cursor.isClosed()) {
+      cursor.moveToPosition(index);
+      CharSequence title = cursor.getString(BookmarkPickerActivity.TITLE_COLUMN);
+      ((TextView) layout.findViewById(R.id.bookmark_title)).setText(title);
+      CharSequence url = cursor.getString(BookmarkPickerActivity.URL_COLUMN);
+      ((TextView) layout.findViewById(R.id.bookmark_url)).setText(url);
+    } // Otherwise... just don't update as the object is shutting down
+    return layout;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/BookmarkPickerActivity.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/BookmarkPickerActivity.java
new file mode 100644 (file)
index 0000000..8e07a0c
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.share;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.Browser;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+
+/**
+ * This class is only needed because I can't successfully send an ACTION_PICK intent to
+ * com.android.browser.BrowserBookmarksPage. It can go away if that starts working in the future.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class BookmarkPickerActivity extends ListActivity {
+
+  private static final String TAG = BookmarkPickerActivity.class.getSimpleName();
+
+  private static final String[] BOOKMARK_PROJECTION = {
+      Browser.BookmarkColumns.TITLE,
+      Browser.BookmarkColumns.URL
+  };
+
+  static final int TITLE_COLUMN = 0;
+  static final int URL_COLUMN = 1;
+
+  private static final String BOOKMARK_SELECTION = 
+      Browser.BookmarkColumns.BOOKMARK + " = 1 AND " + Browser.BookmarkColumns.URL + " IS NOT NULL";
+
+  private Cursor cursor;
+
+  @Override
+  protected void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+    cursor = getContentResolver().query(Browser.BOOKMARKS_URI, BOOKMARK_PROJECTION,
+        BOOKMARK_SELECTION, null, null);
+    if (cursor == null) {
+      Log.w(TAG, "No cursor returned for bookmark query");
+      finish();
+      return;
+    }
+    setListAdapter(new BookmarkAdapter(this, cursor));
+  }
+  
+  @Override
+  protected void onDestroy() {
+    if (cursor != null) {
+      cursor.close();
+    }
+    super.onDestroy();
+  }
+
+  @Override
+  protected void onListItemClick(ListView l, View view, int position, long id) {
+    if (!cursor.isClosed() && cursor.moveToPosition(position)) {
+      Intent intent = new Intent();
+      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+      intent.putExtra(Browser.BookmarkColumns.TITLE, cursor.getString(TITLE_COLUMN));
+      intent.putExtra(Browser.BookmarkColumns.URL, cursor.getString(URL_COLUMN));
+      setResult(RESULT_OK, intent);
+    } else {
+      setResult(RESULT_CANCELED);
+    }
+    finish();
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/LoadPackagesAsyncTask.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/LoadPackagesAsyncTask.java
new file mode 100644 (file)
index 0000000..33dda06
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2009 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.share;
+
+import android.app.ListActivity;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+
+import cz.cvut.fel.dce.barcodescanner.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Loads a list of packages installed on the device asynchronously.
+ *
+ * @author Sean Owen
+ */
+final class LoadPackagesAsyncTask extends AsyncTask<Object,Object,List<AppInfo>> {
+
+  private static final String[] PKG_PREFIX_WHITELIST = {
+      "com.google.android.apps.",
+  };
+  private static final String[] PKG_PREFIX_BLACKLIST = {
+      "com.android.",
+      "android",
+      "com.google.android.",
+      "com.htc",
+  };
+
+  private final ListActivity activity;
+
+  LoadPackagesAsyncTask(ListActivity activity) {
+    this.activity = activity;
+  }
+
+  @Override
+  protected List<AppInfo> doInBackground(Object... objects) {
+    List<AppInfo> labelsPackages = new ArrayList<>();
+    PackageManager packageManager = activity.getPackageManager();
+    Iterable<ApplicationInfo> appInfos = packageManager.getInstalledApplications(0);
+    for (PackageItemInfo appInfo : appInfos) {
+      String packageName = appInfo.packageName;
+      if (!isHidden(packageName)) {
+        CharSequence label = appInfo.loadLabel(packageManager);
+        Drawable icon = appInfo.loadIcon(packageManager);        
+        if (label != null) {
+          labelsPackages.add(new AppInfo(packageName, label.toString(), icon));
+        }
+      }
+    }
+    Collections.sort(labelsPackages);
+    return labelsPackages;
+  }
+
+  private static boolean isHidden(String packageName) {
+    if (packageName == null) {
+      return true;
+    }
+    for (String prefix : PKG_PREFIX_WHITELIST) {
+      if (packageName.startsWith(prefix)) {
+        return false;
+      }
+    }
+    for (String prefix : PKG_PREFIX_BLACKLIST) {
+      if (packageName.startsWith(prefix)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Override
+  protected void onPostExecute(final List<AppInfo> results) {    
+    ListAdapter listAdapter = new ArrayAdapter<AppInfo>(activity, 
+                                                        R.layout.app_picker_list_item, 
+                                                        R.id.app_picker_list_item_label, 
+                                                        results) {
+      @Override
+      public View getView(int position, View convertView, ViewGroup parent) {
+        View view = super.getView(position, convertView, parent);
+        Drawable icon = results.get(position).getIcon();
+        if (icon != null) {
+          ((ImageView) view.findViewById(R.id.app_picker_list_item_icon)).setImageDrawable(icon);
+        }
+        return view;
+      }
+    };
+    activity.setListAdapter(listAdapter);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/ShareActivity.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/share/ShareActivity.java
new file mode 100644 (file)
index 0000000..34d3f5e
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2008 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.share;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.BaseColumns;
+import android.provider.Browser;
+import android.provider.ContactsContract;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.TextView;
+
+import com.google.zxing.BarcodeFormat;
+import cz.cvut.fel.dce.barcodescanner.Contents;
+import cz.cvut.fel.dce.barcodescanner.Intents;
+import cz.cvut.fel.dce.barcodescanner.R;
+import cz.cvut.fel.dce.barcodescanner.clipboard.ClipboardInterface;
+
+/**
+ * Barcode Scanner can share data like contacts and bookmarks by displaying a QR Code on screen,
+ * such that another user can scan the barcode with their phone.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
+public final class ShareActivity extends Activity {
+
+  private static final String TAG = ShareActivity.class.getSimpleName();
+
+  private static final int PICK_BOOKMARK = 0;
+  private static final int PICK_CONTACT = 1;
+  private static final int PICK_APP = 2;
+
+  private View clipboardButton;
+
+  private final View.OnClickListener contactListener = new View.OnClickListener() {
+    @Override
+    public void onClick(View v) {
+      Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
+      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+      startActivityForResult(intent, PICK_CONTACT);
+    }
+  };
+
+  private final View.OnClickListener bookmarkListener = new View.OnClickListener() {
+    @Override
+    public void onClick(View v) {
+      Intent intent = new Intent(Intent.ACTION_PICK);
+      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+      intent.setClassName(ShareActivity.this, BookmarkPickerActivity.class.getName());
+      startActivityForResult(intent, PICK_BOOKMARK);
+    }
+  };
+
+  private final View.OnClickListener appListener = new View.OnClickListener() {
+    @Override
+    public void onClick(View v) {
+      Intent intent = new Intent(Intent.ACTION_PICK);
+      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+      intent.setClassName(ShareActivity.this, AppPickerActivity.class.getName());
+      startActivityForResult(intent, PICK_APP);
+    }
+  };
+
+  private final View.OnClickListener clipboardListener = new View.OnClickListener() {
+    @Override
+    public void onClick(View v) {
+      // Should always be true, because we grey out the clipboard button in onResume() if it's empty
+      CharSequence text = ClipboardInterface.getText(ShareActivity.this);
+      if (text != null) {
+        launchSearch(text.toString());
+      }
+    }
+  };
+
+  private final View.OnKeyListener textListener = new View.OnKeyListener() {
+    @Override
+    public boolean onKey(View view, int keyCode, KeyEvent event) {
+      if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
+        String text = ((TextView) view).getText().toString();
+        if (text != null && !text.isEmpty()) {
+          launchSearch(text);
+        }
+        return true;
+      }
+      return false;
+    }
+  };
+
+  private void launchSearch(String text) {
+    Intent intent = new Intent(Intents.Encode.ACTION);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT);
+    intent.putExtra(Intents.Encode.DATA, text);
+    intent.putExtra(Intents.Encode.FORMAT, BarcodeFormat.QR_CODE.toString());
+    startActivity(intent);
+  }
+
+  @Override
+  public void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+    setContentView(R.layout.share);
+
+    findViewById(R.id.share_contact_button).setOnClickListener(contactListener);
+    findViewById(R.id.share_bookmark_button).setOnClickListener(bookmarkListener);
+    findViewById(R.id.share_app_button).setOnClickListener(appListener);
+    clipboardButton = findViewById(R.id.share_clipboard_button);
+    clipboardButton.setOnClickListener(clipboardListener);
+    findViewById(R.id.share_text_view).setOnKeyListener(textListener);
+  }
+
+  @Override
+  protected void onResume() {
+    super.onResume();
+    clipboardButton.setEnabled(ClipboardInterface.hasText(this));
+  }
+
+  @Override
+  public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+    if (resultCode == RESULT_OK) {
+      switch (requestCode) {
+        case PICK_BOOKMARK:
+        case PICK_APP:
+          showTextAsBarcode(intent.getStringExtra(Browser.BookmarkColumns.URL));
+          break;
+        case PICK_CONTACT:
+          // Data field is content://contacts/people/984
+          showContactAsBarcode(intent.getData());
+          break;
+      }
+    }
+  }
+
+  private void showTextAsBarcode(String text) {
+    Log.i(TAG, "Showing text as barcode: " + text);
+    if (text == null) {
+      return; // Show error?
+    }
+    Intent intent = new Intent(Intents.Encode.ACTION);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT);
+    intent.putExtra(Intents.Encode.DATA, text);
+    intent.putExtra(Intents.Encode.FORMAT, BarcodeFormat.QR_CODE.toString());
+    startActivity(intent);
+  }
+
+  /**
+   * Takes a contact Uri and does the necessary database lookups to retrieve that person's info,
+   * then sends an Encode intent to render it as a QR Code.
+   *
+   * @param contactUri A Uri of the form content://contacts/people/17
+   */
+  private void showContactAsBarcode(Uri contactUri) {
+    Log.i(TAG, "Showing contact URI as barcode: " + contactUri);
+    if (contactUri == null) {
+      return; // Show error?
+    }
+    ContentResolver resolver = getContentResolver();
+
+    Cursor cursor;
+    try {
+      // We're seeing about six reports a week of this exception although I don't understand why.
+      cursor = resolver.query(contactUri, null, null, null, null);
+    } catch (IllegalArgumentException ignored) {
+      return;
+    }
+    if (cursor == null) {
+      return;
+    }
+
+    String id;
+    String name;
+    boolean hasPhone;
+    try {
+      if (!cursor.moveToFirst()) {
+        return;
+      }
+
+      id = cursor.getString(cursor.getColumnIndex(BaseColumns._ID));
+      name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
+      hasPhone = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0;
+
+
+    } finally {
+      cursor.close();
+    }
+
+    // Don't require a name to be present, this contact might be just a phone number.
+    Bundle bundle = new Bundle();
+    if (name != null && !name.isEmpty()) {
+      bundle.putString(ContactsContract.Intents.Insert.NAME, massageContactData(name));
+    }
+
+    if (hasPhone) {
+      Cursor phonesCursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
+                                           null,
+                                           ContactsContract.CommonDataKinds.Phone.CONTACT_ID + '=' + id,
+                                           null,
+                                           null);
+      if (phonesCursor != null) {
+        try {
+          int foundPhone = 0;
+          int phonesNumberColumn = phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
+          int phoneTypeColumn = phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
+          while (phonesCursor.moveToNext() && foundPhone < Contents.PHONE_KEYS.length) {
+            String number = phonesCursor.getString(phonesNumberColumn);
+            if (number != null && !number.isEmpty()) {
+              bundle.putString(Contents.PHONE_KEYS[foundPhone], massageContactData(number));
+            }
+            int type = phonesCursor.getInt(phoneTypeColumn);
+            bundle.putInt(Contents.PHONE_TYPE_KEYS[foundPhone], type);
+            foundPhone++;
+          }
+        } finally {
+          phonesCursor.close();
+        }
+      }
+    }
+
+    Cursor methodsCursor = resolver.query(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,
+                                          null,
+                                          ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + '=' + id,
+                                          null,
+                                          null);
+    if (methodsCursor != null) {
+      try {
+        if (methodsCursor.moveToNext()) {
+          String data = methodsCursor.getString(
+              methodsCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS));
+          if (data != null && !data.isEmpty()) {
+            bundle.putString(ContactsContract.Intents.Insert.POSTAL, massageContactData(data));
+          }
+        }
+      } finally {
+        methodsCursor.close();
+      }
+    }
+
+    Cursor emailCursor = resolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
+                                        null,
+                                        ContactsContract.CommonDataKinds.Email.CONTACT_ID + '=' + id,
+                                        null,
+                                        null);
+    if (emailCursor != null) {
+      try {
+        int foundEmail = 0;
+        int emailColumn = emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
+        while (emailCursor.moveToNext() && foundEmail < Contents.EMAIL_KEYS.length) {
+          String email = emailCursor.getString(emailColumn);
+          if (email != null && !email.isEmpty()) {
+            bundle.putString(Contents.EMAIL_KEYS[foundEmail], massageContactData(email));
+          }
+          foundEmail++;
+        }
+      } finally {
+        emailCursor.close();
+      }
+    }
+
+    Intent intent = new Intent(Intents.Encode.ACTION);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    intent.putExtra(Intents.Encode.TYPE, Contents.Type.CONTACT);
+    intent.putExtra(Intents.Encode.DATA, bundle);
+    intent.putExtra(Intents.Encode.FORMAT, BarcodeFormat.QR_CODE.toString());
+
+    Log.i(TAG, "Sending bundle for encoding: " + bundle);
+    startActivity(intent);
+  }
+
+  private static String massageContactData(String data) {
+    // For now -- make sure we don't put newlines in shared contact data. It messes up
+    // any known encoding of contact data. Replace with space.
+    if (data.indexOf('\n') >= 0) {
+      data = data.replace("\n", " ");
+    }
+    if (data.indexOf('\r') >= 0) {
+      data = data.replace("\r", " ");
+    }
+    return data;
+  }
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/wifi/NetworkType.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/wifi/NetworkType.java
new file mode 100644 (file)
index 0000000..314257f
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.wifi;
+
+enum NetworkType {
+
+  WEP,
+  WPA,
+  NO_PASSWORD;
+
+  static NetworkType forIntentValue(String networkTypeString) {
+    if (networkTypeString == null) {
+      return NO_PASSWORD;
+    }
+    if ("WPA".equals(networkTypeString)) {
+      return WPA;
+    }
+    if ("WEP".equals(networkTypeString)) {
+      return WEP;
+    }
+    if ("nopass".equals(networkTypeString)) {
+      return NO_PASSWORD;
+    }
+    throw new IllegalArgumentException(networkTypeString);
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/wifi/WifiConfigManager.java b/BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/wifi/WifiConfigManager.java
new file mode 100644 (file)
index 0000000..6669d5b
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2011 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.barcodescanner.wifi;
+
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.AsyncTask;
+import android.util.Log;
+
+import com.google.zxing.client.result.WifiParsedResult;
+
+import java.util.regex.Pattern;
+
+/**
+ * @author Vikram Aggarwal
+ * @author Sean Owen
+ */
+public final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,Object> {
+
+  private static final String TAG = WifiConfigManager.class.getSimpleName();
+
+  private static final Pattern HEX_DIGITS = Pattern.compile("[0-9A-Fa-f]+");
+
+  private final WifiManager wifiManager;
+
+  public WifiConfigManager(WifiManager wifiManager) {
+    this.wifiManager = wifiManager;
+  }
+
+  @Override
+  protected Object doInBackground(WifiParsedResult... args) {
+    WifiParsedResult theWifiResult = args[0];
+    // Start WiFi, otherwise nothing will work
+    if (!wifiManager.isWifiEnabled()) {
+      Log.i(TAG, "Enabling wi-fi...");
+      if (wifiManager.setWifiEnabled(true)) {
+        Log.i(TAG, "Wi-fi enabled");
+      } else {
+        Log.w(TAG, "Wi-fi could not be enabled!");
+        return null;
+      }
+      // This happens very quickly, but need to wait for it to enable. A little busy wait?
+      int count = 0;
+      while (!wifiManager.isWifiEnabled()) {
+        if (count >= 10) {
+          Log.i(TAG, "Took too long to enable wi-fi, quitting");
+          return null;
+        }
+        Log.i(TAG, "Still waiting for wi-fi to enable...");
+        try {
+          Thread.sleep(1000L);
+        } catch (InterruptedException ie) {
+          // continue
+        }
+        count++;
+      }
+    }
+    String networkTypeString = theWifiResult.getNetworkEncryption();
+    NetworkType networkType;
+    try {
+      networkType = NetworkType.forIntentValue(networkTypeString);
+    } catch (IllegalArgumentException ignored) {
+      Log.w(TAG, "Bad network type; see NetworkType values: " + networkTypeString);
+      return null;
+    }
+    if (networkType == NetworkType.NO_PASSWORD) {
+      changeNetworkUnEncrypted(wifiManager, theWifiResult);
+    } else {
+      String password = theWifiResult.getPassword();
+      if (password != null && !password.isEmpty()) {
+        if (networkType == NetworkType.WEP) {
+          changeNetworkWEP(wifiManager, theWifiResult);
+        } else if (networkType == NetworkType.WPA) {
+          changeNetworkWPA(wifiManager, theWifiResult);
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Update the network: either create a new network or modify an existing network
+   * @param config the new network configuration
+   */
+  private static void updateNetwork(WifiManager wifiManager, WifiConfiguration config) {
+    Integer foundNetworkID = findNetworkInExistingConfig(wifiManager, config.SSID);
+    if (foundNetworkID != null) {
+      Log.i(TAG, "Removing old configuration for network " + config.SSID);
+      wifiManager.removeNetwork(foundNetworkID);
+      wifiManager.saveConfiguration();
+    }
+    int networkId = wifiManager.addNetwork(config);
+    if (networkId >= 0) {
+      // Try to disable the current network and start a new one.
+      if (wifiManager.enableNetwork(networkId, true)) {
+        Log.i(TAG, "Associating to network " + config.SSID);
+        wifiManager.saveConfiguration();
+      } else {
+        Log.w(TAG, "Failed to enable network " + config.SSID);
+      }
+    } else {
+      Log.w(TAG, "Unable to add network " + config.SSID);
+    }
+  }
+
+  private static WifiConfiguration changeNetworkCommon(WifiParsedResult wifiResult) {
+    WifiConfiguration config = new WifiConfiguration();
+    config.allowedAuthAlgorithms.clear();
+    config.allowedGroupCiphers.clear();
+    config.allowedKeyManagement.clear();
+    config.allowedPairwiseCiphers.clear();
+    config.allowedProtocols.clear();
+    // Android API insists that an ascii SSID must be quoted to be correctly handled.
+    config.SSID = quoteNonHex(wifiResult.getSsid());
+    config.hiddenSSID = wifiResult.isHidden();
+    return config;
+  }
+
+  // Adding a WEP network
+  private static void changeNetworkWEP(WifiManager wifiManager, WifiParsedResult wifiResult) {
+    WifiConfiguration config = changeNetworkCommon(wifiResult);
+    config.wepKeys[0] = quoteNonHex(wifiResult.getPassword(), 10, 26, 58);
+    config.wepTxKeyIndex = 0;
+    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
+    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
+    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
+    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
+    updateNetwork(wifiManager, config);
+  }
+
+  // Adding a WPA or WPA2 network
+  private static void changeNetworkWPA(WifiManager wifiManager, WifiParsedResult wifiResult) {
+    WifiConfiguration config = changeNetworkCommon(wifiResult);
+    // Hex passwords that are 64 bits long are not to be quoted.
+    config.preSharedKey = quoteNonHex(wifiResult.getPassword(), 64);
+    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
+    config.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA
+    config.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2
+    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+    config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
+    config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
+    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+    updateNetwork(wifiManager, config);
+  }
+
+  // Adding an open, unsecured network
+  private static void changeNetworkUnEncrypted(WifiManager wifiManager, WifiParsedResult wifiResult) {
+    WifiConfiguration config = changeNetworkCommon(wifiResult);
+    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+    updateNetwork(wifiManager, config);
+  }
+
+  private static Integer findNetworkInExistingConfig(WifiManager wifiManager, String ssid) {
+    Iterable<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
+    for (WifiConfiguration existingConfig : existingConfigs) {
+      String existingSSID = existingConfig.SSID;
+      if (existingSSID != null && existingSSID.equals(ssid)) {
+        return existingConfig.networkId;
+      }
+    }
+    return null;
+  }
+
+  private static String quoteNonHex(String value, int... allowedLengths) {
+    return isHexOfLength(value, allowedLengths) ? value : convertToQuotedString(value);
+  }
+
+  /**
+   * Encloses the incoming string inside double quotes, if it isn't already quoted.
+   * @param s the input string
+   * @return a quoted string, of the form "input".  If the input string is null, it returns null
+   * as well.
+   */
+  private static String convertToQuotedString(String s) {
+    if (s == null || s.isEmpty()) {
+      return null;
+    }
+    // If already quoted, return as-is
+    if (s.charAt(0) == '"' && s.charAt(s.length() - 1) == '"') {
+      return s;
+    }
+    return '\"' + s + '\"';
+  }
+
+  /**
+   * @param value input to check
+   * @param allowedLengths allowed lengths, if any
+   * @return true if value is a non-null, non-empty string of hex digits, and if allowed lengths are given, has
+   *  an allowed length
+   */
+  private static boolean isHexOfLength(CharSequence value, int... allowedLengths) {
+    if (value == null || !HEX_DIGITS.matcher(value).matches()) {
+      return false;
+    }
+    if (allowedLengths.length == 0) {
+      return true;
+    }
+    for (int length : allowedLengths) {
+      if (value.length() == length) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+}
diff --git a/BarCodeScanner/mobile/src/main/res/drawable-hdpi/launcher_icon.png b/BarCodeScanner/mobile/src/main/res/drawable-hdpi/launcher_icon.png
new file mode 100644 (file)
index 0000000..5932aad
Binary files /dev/null and b/BarCodeScanner/mobile/src/main/res/drawable-hdpi/launcher_icon.png differ
diff --git a/BarCodeScanner/mobile/src/main/res/drawable-xhdpi/launcher_icon.png b/BarCodeScanner/mobile/src/main/res/drawable-xhdpi/launcher_icon.png
new file mode 100644 (file)
index 0000000..330dc2f
Binary files /dev/null and b/BarCodeScanner/mobile/src/main/res/drawable-xhdpi/launcher_icon.png differ
diff --git a/BarCodeScanner/mobile/src/main/res/drawable-xxhdpi/launcher_icon.png b/BarCodeScanner/mobile/src/main/res/drawable-xxhdpi/launcher_icon.png
new file mode 100644 (file)
index 0000000..d535fda
Binary files /dev/null and b/BarCodeScanner/mobile/src/main/res/drawable-xxhdpi/launcher_icon.png differ
diff --git a/BarCodeScanner/mobile/src/main/res/drawable/launcher_icon.png b/BarCodeScanner/mobile/src/main/res/drawable/launcher_icon.png
new file mode 100644 (file)
index 0000000..fc5fafc
Binary files /dev/null and b/BarCodeScanner/mobile/src/main/res/drawable/launcher_icon.png differ
diff --git a/BarCodeScanner/mobile/src/main/res/drawable/share_via_barcode.png b/BarCodeScanner/mobile/src/main/res/drawable/share_via_barcode.png
new file mode 100644 (file)
index 0000000..56c3449
Binary files /dev/null and b/BarCodeScanner/mobile/src/main/res/drawable/share_via_barcode.png differ
diff --git a/BarCodeScanner/mobile/src/main/res/layout-land/encode.xml b/BarCodeScanner/mobile/src/main/res/layout-land/encode.xml
new file mode 100644 (file)
index 0000000..30f32a1
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:fillViewport="true"
+              android:background="@color/encode_view"
+              android:orientation="horizontal"
+              android:gravity="center"
+              tools:ignore="Overdraw">
+
+  <ImageView android:id="@+id/image_view"
+             android:layout_width="wrap_content"
+             android:layout_height="fill_parent"
+             android:layout_gravity="center_vertical"
+             android:scaleType="center"
+             tools:ignore="ContentDescription"/>
+
+  <ScrollView android:layout_width="wrap_content"
+            android:layout_height="fill_parent"
+            android:layout_gravity="center_vertical"
+            android:gravity="center">
+
+    <TextView android:id="@+id/contents_text_view"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:layout_gravity="center_vertical"
+              android:gravity="center"
+              android:textColor="@color/contents_text"
+              android:paddingRight="8dip"
+              android:paddingTop="8dip"
+              android:paddingBottom="8dip"
+              android:textIsSelectable="true"/>
+
+  </ScrollView>
+
+</LinearLayout>
diff --git a/BarCodeScanner/mobile/src/main/res/layout-land/share.xml b/BarCodeScanner/mobile/src/main/res/layout-land/share.xml
new file mode 100644 (file)
index 0000000..7adb432
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:layout_gravity="center"
+              android:gravity="center"
+              android:orientation="vertical"
+              android:padding="8dip">
+
+  <TextView
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content"
+      android:gravity="center"
+      android:text="@string/msg_share_explanation"
+      android:paddingBottom="12dip"
+      android:textIsSelectable="false"/>
+
+  <LinearLayout
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content"
+      android:orientation="horizontal"
+      android:paddingBottom="12dip">
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:scaleType="center"
+        android:src="@drawable/share_via_barcode"
+        android:paddingRight="24dip"
+        tools:ignore="ContentDescription"/>
+
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:orientation="vertical">
+
+      <Button android:id="@+id/share_app_button"
+              style="@style/ShareButton"
+              android:text="@string/button_share_app"/>
+
+      <Button android:id="@+id/share_contact_button"
+              style="@style/ShareButton"
+              android:text="@string/button_share_contact"/>
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:orientation="vertical">
+
+      <Button android:id="@+id/share_bookmark_button"
+              style="@style/ShareButton"
+              android:text="@string/button_share_bookmark"/>
+
+      <Button android:id="@+id/share_clipboard_button"
+              style="@style/ShareButton"
+              android:text="@string/button_share_clipboard"/>
+
+    </LinearLayout>
+
+  </LinearLayout>
+
+  <EditText android:id="@+id/share_text_view"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:hint="@string/msg_share_text"
+            android:singleLine="true"
+            android:selectAllOnFocus="true"/>
+
+</LinearLayout>
diff --git a/BarCodeScanner/mobile/src/main/res/layout-ldpi/capture.xml b/BarCodeScanner/mobile/src/main/res/layout-ldpi/capture.xml
new file mode 100644 (file)
index 0000000..6978813
--- /dev/null
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+       xmlns:tools="http://schemas.android.com/tools">
+
+  <SurfaceView android:id="@+id/preview_view"
+               android:layout_width="fill_parent"
+               android:layout_height="fill_parent"/>
+
+  <cz.cvut.fel.dce.barcodescanner.ViewfinderView
+      android:id="@+id/viewfinder_view"
+      android:layout_width="fill_parent"
+      android:layout_height="fill_parent"/>
+
+  <LinearLayout android:id="@+id/result_view"
+                android:orientation="vertical"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:background="@color/result_view"
+                android:visibility="gone"
+                android:baselineAligned="false">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:gravity="top"
+        android:padding="@dimen/standard_padding">
+
+      <LinearLayout
+          android:orientation="vertical"
+          android:layout_width="wrap_content"
+          android:layout_height="fill_parent"
+          android:gravity="right">
+
+        <ImageView android:id="@+id/barcode_image_view"
+                   android:layout_width="150dip"
+                   android:layout_height="wrap_content"
+                   android:maxWidth="150dip"
+                   android:maxHeight="150dip"
+                   android:layout_marginBottom="@dimen/half_padding"
+                   android:adjustViewBounds="true"
+                   android:scaleType="centerInside"
+                   tools:ignore="ContentDescription"/>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_format"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/format_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_type"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/type_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_time"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/time_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:id="@+id/meta_text_view_label"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_meta"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/meta_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+      </LinearLayout>
+
+      <ScrollView
+          android:layout_width="fill_parent"
+          android:layout_height="wrap_content">
+
+        <LinearLayout
+          android:orientation="vertical"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:id="@+id/contents_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_text"
+                    android:textColorLink="@color/result_text"
+                    android:textSize="22sp"
+                    android:paddingLeft="12dip"
+                    android:autoLink="web"
+                    android:textIsSelectable="true"/>
+
+          <TextView android:id="@+id/contents_supplement_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_text"
+                    android:textColorLink="@color/result_text"
+                    android:paddingLeft="12dip"
+                    android:autoLink="web"
+                    android:textIsSelectable="true"/>
+
+        </LinearLayout>
+
+      </ScrollView>
+
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/result_button_view"
+                  android:orientation="horizontal"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center">
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+    </LinearLayout>
+
+  </LinearLayout>
+
+  <TextView android:id="@+id/status_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|center_horizontal"
+            android:background="@color/transparent"
+            android:text="@string/msg_default_status"
+            android:textColor="@color/status_text"/>
+
+</merge>
diff --git a/BarCodeScanner/mobile/src/main/res/layout/app_picker_list_item.xml b/BarCodeScanner/mobile/src/main/res/layout/app_picker_list_item.xml
new file mode 100644 (file)
index 0000000..0f68618
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:orientation="horizontal"
+              android:layout_width="fill_parent"
+              android:layout_height="wrap_content">
+  
+  <ImageView android:id="@+id/app_picker_list_item_icon"
+             android:layout_width="64dip"
+             android:layout_height="64dip"
+             android:scaleType="centerInside"
+             android:padding="@dimen/half_padding"
+             tools:ignore="ContentDescription"/>
+  
+  <TextView android:id="@+id/app_picker_list_item_label" 
+            android:layout_width="wrap_content"
+            android:layout_height="fill_parent"
+            android:gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceLarge"            
+            android:singleLine="true"
+            android:padding="@dimen/half_padding"/>
+  
+</LinearLayout>
diff --git a/BarCodeScanner/mobile/src/main/res/layout/bookmark_picker_list_item.xml b/BarCodeScanner/mobile/src/main/res/layout/bookmark_picker_list_item.xml
new file mode 100644 (file)
index 0000000..95398b4
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:padding="@dimen/half_padding">
+
+  <TextView android:id="@+id/bookmark_title"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceLarge"            
+            android:singleLine="true"
+            android:textIsSelectable="false"/>
+
+  <TextView android:id="@+id/bookmark_url"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceSmall"                
+            android:singleLine="false"
+            android:textIsSelectable="false"/>
+
+</LinearLayout>
diff --git a/BarCodeScanner/mobile/src/main/res/layout/capture.xml b/BarCodeScanner/mobile/src/main/res/layout/capture.xml
new file mode 100644 (file)
index 0000000..6d1e5b3
--- /dev/null
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+       xmlns:tools="http://schemas.android.com/tools">
+
+  <SurfaceView android:id="@+id/preview_view"
+               android:layout_width="fill_parent"
+               android:layout_height="fill_parent"/>
+
+  <cz.cvut.fel.dce.barcodescanner.ViewfinderView
+      android:id="@+id/viewfinder_view"
+      android:layout_width="fill_parent"
+      android:layout_height="fill_parent"/>
+
+  <LinearLayout android:id="@+id/result_view"
+                android:orientation="vertical"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:background="@color/result_view"
+                android:visibility="gone"
+                android:baselineAligned="false">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:gravity="center"
+        android:padding="@dimen/standard_padding">
+
+      <LinearLayout
+          android:orientation="vertical"
+          android:layout_width="wrap_content"
+          android:layout_height="fill_parent"
+          android:gravity="right|center_vertical">
+
+        <ImageView android:id="@+id/barcode_image_view"
+                   android:layout_width="160dip"
+                   android:layout_height="wrap_content"
+                   android:maxWidth="160dip"
+                   android:maxHeight="160dip"
+                   android:layout_marginBottom="@dimen/half_padding"
+                   android:adjustViewBounds="true"
+                   android:scaleType="centerInside"
+                   tools:ignore="ContentDescription"/>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_format"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/format_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_type"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/type_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_time"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/time_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+          android:orientation="horizontal"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+          <TextView android:id="@+id/meta_text_view_label"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/msg_default_meta"
+                    android:textColor="@color/result_minor_text"
+                    android:textStyle="bold"
+                    android:paddingRight="@dimen/half_padding"/>
+
+          <TextView android:id="@+id/meta_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_minor_text"/>
+
+        </LinearLayout>
+
+      </LinearLayout>
+
+      <ScrollView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content">
+
+        <LinearLayout
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:orientation="vertical">
+
+          <TextView android:id="@+id/contents_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_text"
+                    android:textColorLink="@color/result_text"
+                    android:textSize="22sp"
+                    android:paddingLeft="12dip"
+                    android:autoLink="web"
+                    android:textIsSelectable="true"/>
+
+          <TextView android:id="@+id/contents_supplement_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/result_text"
+                    android:textColorLink="@color/result_text"
+                    android:paddingLeft="12dip"
+                    android:autoLink="web"
+                    android:textIsSelectable="true"/>
+
+        </LinearLayout>
+
+      </ScrollView>
+
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/result_button_view"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:orientation="horizontal"
+                  android:gravity="center">
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+      <Button style="@style/ResultButton"
+              android:visibility="gone"/>
+
+    </LinearLayout>
+
+  </LinearLayout>
+
+  <TextView android:id="@+id/status_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|center_horizontal"
+            android:background="@color/transparent"
+            android:text="@string/msg_default_status"
+            android:textColor="@color/status_text"/>
+
+</merge>
diff --git a/BarCodeScanner/mobile/src/main/res/layout/encode.xml b/BarCodeScanner/mobile/src/main/res/layout/encode.xml
new file mode 100644 (file)
index 0000000..120935f
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:fillViewport="true"
+              android:background="@color/encode_view"
+              android:orientation="vertical"
+              android:gravity="center"
+              tools:ignore="Overdraw">
+
+  <ImageView android:id="@+id/image_view"
+             android:layout_width="fill_parent"
+             android:layout_height="wrap_content"
+             android:layout_gravity="center_horizontal"
+             android:scaleType="center"
+             tools:ignore="ContentDescription"/>
+
+  <ScrollView android:layout_width="fill_parent"
+              android:layout_height="wrap_content"
+              android:layout_gravity="center_horizontal"
+              android:gravity="center">
+
+    <TextView android:id="@+id/contents_text_view"
+              android:layout_width="fill_parent"
+              android:layout_height="wrap_content"
+              android:layout_gravity="center_horizontal"
+              android:gravity="center"
+              android:textColor="@color/contents_text"
+              android:paddingBottom="@dimen/standard_padding"
+              android:paddingLeft="@dimen/standard_padding"
+              android:paddingRight="@dimen/standard_padding"
+              android:textIsSelectable="true"/>
+
+  </ScrollView>
+
+</LinearLayout>
diff --git a/BarCodeScanner/mobile/src/main/res/layout/help.xml b/BarCodeScanner/mobile/src/main/res/layout/help.xml
new file mode 100644 (file)
index 0000000..786a624
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<WebView xmlns:android="http://schemas.android.com/apk/res/android"
+         android:id="@+id/help_contents"
+         android:layout_width="fill_parent"
+         android:layout_height="fill_parent"
+         android:layout_weight="1"/>
\ No newline at end of file
diff --git a/BarCodeScanner/mobile/src/main/res/layout/history_list_item.xml b/BarCodeScanner/mobile/src/main/res/layout/history_list_item.xml
new file mode 100644 (file)
index 0000000..0c060b4
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:padding="@dimen/standard_padding">
+
+  <TextView android:id="@+id/history_title"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:singleLine="true"
+            android:textIsSelectable="false"/>
+
+  <TextView android:id="@+id/history_detail"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:singleLine="false"
+            android:textIsSelectable="false"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/BarCodeScanner/mobile/src/main/res/layout/search_book_contents.xml b/BarCodeScanner/mobile/src/main/res/layout/search_book_contents.xml
new file mode 100644 (file)
index 0000000..f572a0d
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent">
+
+  <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content"
+      android:layout_weight="0">
+
+    <EditText android:id="@+id/query_text_view"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:layout_gravity="left|center_vertical"
+              android:layout_weight="1"
+              android:singleLine="true"
+              android:selectAllOnFocus="true"
+              android:inputType="text"
+              tools:ignore="NestedWeights"/>
+
+    <Button android:id="@+id/query_button"
+            style="@android:style/Widget.Holo.Button.Borderless.Small"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:text="@string/button_search_book_contents"/>
+
+  </LinearLayout>
+
+
+  <ListView android:id="@+id/result_list_view"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"/>
+
+</LinearLayout>
diff --git a/BarCodeScanner/mobile/src/main/res/layout/search_book_contents_header.xml b/BarCodeScanner/mobile/src/main/res/layout/search_book_contents_header.xml
new file mode 100644 (file)
index 0000000..09d627e
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+          android:layout_width="fill_parent"
+          android:layout_height="wrap_content"
+          android:paddingLeft="@dimen/standard_padding"
+          android:paddingBottom="@dimen/half_padding"
+          android:enabled="false"
+          android:singleLine="true"
+          android:textIsSelectable="false"/>
diff --git a/BarCodeScanner/mobile/src/main/res/layout/search_book_contents_list_item.xml b/BarCodeScanner/mobile/src/main/res/layout/search_book_contents_list_item.xml
new file mode 100644 (file)
index 0000000..cf811f4
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<cz.cvut.fel.dce.barcodescanner.book.SearchBookContentsListItem
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:padding="@dimen/standard_padding">
+
+  <TextView android:id="@+id/page_number_view"
+            android:layout_width="75dip"
+            android:layout_height="wrap_content"
+            android:layout_gravity="left|top"
+            android:layout_marginRight="@dimen/standard_padding"
+            android:singleLine="false"
+            android:textStyle="bold"
+            android:textIsSelectable="false"/>
+
+  <TextView android:id="@+id/snippet_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="left|top"
+            android:singleLine="false"
+            android:textIsSelectable="false"/>
+
+</cz.cvut.fel.dce.barcodescanner.book.SearchBookContentsListItem>
diff --git a/BarCodeScanner/mobile/src/main/res/layout/share.xml b/BarCodeScanner/mobile/src/main/res/layout/share.xml
new file mode 100644 (file)
index 0000000..785cd0f
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+
+<!-- ScrollView wrapper is to accommodate small screens. -->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            xmlns:tools="http://schemas.android.com/tools"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:gravity="center">
+
+  <!-- Must wrap the rest in one layout -->
+  <LinearLayout
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:gravity="center"
+      android:orientation="vertical"
+      android:padding="@dimen/standard_padding">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:text="@string/msg_share_explanation"
+        android:paddingBottom="@dimen/standard_padding"
+        android:textIsSelectable="false"/>
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:scaleType="center"
+        android:src="@drawable/share_via_barcode"
+        android:paddingBottom="@dimen/standard_padding"
+        tools:ignore="ContentDescription"/>
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingBottom="@dimen/standard_padding">
+
+      <Button android:id="@+id/share_app_button"
+              style="@style/ShareButton"
+              android:layout_weight="1"
+              android:text="@string/button_share_app"/>
+
+      <Button android:id="@+id/share_bookmark_button"
+              style="@style/ShareButton"
+              android:layout_weight="1"
+              android:text="@string/button_share_bookmark"/>
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingBottom="@dimen/standard_padding">
+
+      <Button android:id="@+id/share_contact_button"
+              style="@style/ShareButton"
+              android:layout_weight="1"
+              android:text="@string/button_share_contact"/>
+
+      <Button android:id="@+id/share_clipboard_button"
+              style="@style/ShareButton"
+              android:layout_weight="1"
+              android:text="@string/button_share_clipboard"/>
+
+    </LinearLayout>
+
+    <EditText android:id="@+id/share_text_view"
+              android:layout_width="fill_parent"
+              android:layout_height="wrap_content"
+              android:hint="@string/msg_share_text"
+              android:singleLine="true"
+              android:selectAllOnFocus="true"/>
+
+  </LinearLayout>
+
+</ScrollView>
\ No newline at end of file
diff --git a/BarCodeScanner/mobile/src/main/res/menu/capture.xml b/BarCodeScanner/mobile/src/main/res/menu/capture.xml
new file mode 100644 (file)
index 0000000..466cbe3
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2012 ZXing authors
+
+ 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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:id="@+id/menu_settings"
+        android:title="@string/menu_settings"
+        android:icon="@android:drawable/ic_menu_preferences"
+        android:orderInCategory="3"
+        android:showAsAction="withText"/>
+  <item android:id="@+id/menu_help"
+        android:title="@string/menu_help"
+        android:icon="@android:drawable/ic_menu_help"
+        android:orderInCategory="4"
+        android:showAsAction="withText"/>
+</menu>
\ No newline at end of file
diff --git a/BarCodeScanner/mobile/src/main/res/menu/encode.xml b/BarCodeScanner/mobile/src/main/res/menu/encode.xml
new file mode 100644 (file)
index 0000000..b6b1237
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2012 ZXing authors
+
+ 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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:id="@+id/menu_share"
+        android:title="@string/menu_share"
+        android:icon="@android:drawable/ic_menu_share"
+        android:orderInCategory="1"
+        android:showAsAction="withText|ifRoom"/>
+  <item android:id="@+id/menu_encode"
+        android:title="@string/menu_encode_vcard"
+        android:icon="@android:drawable/ic_menu_sort_alphabetically"
+        android:orderInCategory="2"
+        android:showAsAction="withText|ifRoom"/>
+</menu>
\ No newline at end of file
diff --git a/BarCodeScanner/mobile/src/main/res/menu/history.xml b/BarCodeScanner/mobile/src/main/res/menu/history.xml
new file mode 100644 (file)
index 0000000..17faa05
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2012 ZXing authors
+
+ 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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:id="@+id/menu_history_send"
+        android:title="@string/history_send"
+        android:icon="@android:drawable/ic_menu_share"
+        android:orderInCategory="1"
+        android:showAsAction="withText|ifRoom"/>
+  <item android:id="@+id/menu_history_clear_text"
+        android:title="@string/history_clear_text"
+        android:icon="@android:drawable/ic_menu_delete"
+        android:orderInCategory="2"
+        android:showAsAction="withText|ifRoom"/>
+</menu>
\ No newline at end of file
diff --git a/BarCodeScanner/mobile/src/main/res/raw/beep.ogg b/BarCodeScanner/mobile/src/main/res/raw/beep.ogg
new file mode 100644 (file)
index 0000000..1419947
Binary files /dev/null and b/BarCodeScanner/mobile/src/main/res/raw/beep.ogg differ
diff --git a/BarCodeScanner/mobile/src/main/res/values-ar/strings.xml b/BarCodeScanner/mobile/src/main/res/values-ar/strings.xml
new file mode 100644 (file)
index 0000000..ba26b1c
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">ماسح الرمز الشريطي</string>
+  <string name="app_picker_name">تطبيقات</string>
+  <string name="bookmark_picker_name">إشارات مرجعية</string>
+  <string name="button_add_calendar">إضافة إلى التقويم</string>
+  <string name="button_add_contact">إضافة جهة اتصال</string>
+  <string name="button_book_search">بحث في الكتب</string>
+  <string name="button_cancel">إلغاء</string>
+  <string name="button_custom_product_search">بحث مخصص</string>
+  <string name="button_dial">طلب رقم</string>
+  <string name="button_email">إرسال بريد</string>
+  <string name="button_get_directions">معرفة الاتجاهات</string>
+  <string name="button_mms">إرسال MMS</string>
+  <string name="button_ok">موافق</string>
+  <string name="button_open_browser">فتح المتصفح</string>
+  <string name="button_product_search">بحث عن منتجات</string>
+  <string name="button_search_book_contents">بحث في المحتويات</string>
+  <string name="button_share_app">التطبيق</string>
+  <string name="button_share_bookmark">إشارة مرجعية</string>
+  <string name="button_share_by_email">مشاركة عبر البريد</string>
+  <string name="button_share_by_sms">مشاركة عبر SMS</string>
+  <string name="button_share_clipboard">حافظة</string>
+  <string name="button_share_contact">جهة اتصال</string>
+  <string name="button_show_map">عرض الخريطة</string>
+  <string name="button_sms">إرسال SMS</string>
+  <string name="button_web_search">بحث في الويب</string>
+  <string name="button_wifi">الاتصال بشبك</string>
+  <string name="contents_contact">معلومات جهة اتصال</string>
+  <string name="contents_email">عنوان البريد</string>
+  <string name="contents_location">إحداثيات جغرافية</string>
+  <string name="contents_phone">رقم الهاتف</string>
+  <string name="contents_sms">عنوان SMS</string>
+  <string name="contents_text">نص عادي</string>
+  <string name="history_clear_one_history_text">حذف</string>
+  <string name="history_clear_text">مسح السجل</string>
+  <string name="history_email_title">سجل ماسح الرموز الشريطية</string>
+  <string name="history_empty">فارغ</string>
+  <string name="history_empty_detail">لم تسجل حتى الآن بمسح الباركود</string>
+  <string name="history_send">إرسال السجل</string>
+  <string name="history_title">سجل</string>
+  <string name="menu_encode_mecard">استخدام MECARD</string>
+  <string name="menu_encode_vcard">استخدام vCard</string>
+  <string name="menu_help">تعليمات</string>
+  <string name="menu_history">سجل</string>
+  <string name="menu_settings">إعدادات</string>
+  <string name="menu_share">مشاركة</string>
+  <string name="msg_bulk_mode_scanned">معظم الدراسي : الباركود الممسوحة ضوئيا وحفظها</string>
+  <string name="msg_camera_framework_bug">عفوا، حدثت مشكلة في كاميرا جهاز Android. قد تحتاج إلى إعادة تشغيل الجهاز.</string>
+  <string name="msg_default_format">التنسيق</string>
+  <string name="msg_default_meta">البيانات الوصفية</string>
+  <string name="msg_default_mms_subject">أهلا</string>
+  <string name="msg_default_status">قم بوضع الرمز الشريطي داخل حدود صورة الكاميرا ليتم مسحه.</string>
+  <string name="msg_default_time">الوقت</string>
+  <string name="msg_default_type">النوع</string>
+  <string name="msg_encode_contents_failed">تعذر ترميز رمز شريطي من البيانات المتوفرة.</string>
+  <string name="msg_error">خطأ</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">عفوا، تعذر تشغيل التطبيق المطلوب. قد تكون محتويات الرمز الشريطي غير صحيحة.</string>
+  <string name="msg_invalid_value">قيمة غير صالحة</string>
+  <string name="msg_redirect">إعادة توجيه</string>
+  <string name="msg_sbc_book_not_searchable">عفوا، لا يمكن البحث في هذا الكتاب.</string>
+  <string name="msg_sbc_failed">عفوا، حدثت مشكلة في عملية البحث.</string>
+  <string name="msg_sbc_no_page_returned">لم يتم إرجاع أية صفحة</string>
+  <string name="msg_sbc_page">الصفحة</string>
+  <string name="msg_sbc_results">النتائج</string>
+  <string name="msg_sbc_searching_book">البحث في الكتاب</string>
+  <string name="msg_sbc_snippet_unavailable">الأجزاء غير متاحة</string>
+  <string name="msg_share_explanation">يمكنك مشاركة البيانات عن طريق عرض رمز شريطي على الشاشة ومسحه من خلال هاتف آخر.</string>
+  <string name="msg_share_text">أو اكتب بعض النص</string>
+  <string name="msg_sure">هل أنت متأكد؟</string>
+  <string name="msg_unmount_usb">رجاء إيقاف التخزين على USB للمتابعة.</string>
+  <string name="preferences_actions_title">عند العثور على رمز شريطي</string>
+  <string name="preferences_auto_focus_title">استخدام التركيز التلقائي</string>
+  <string name="preferences_auto_open_web_title">فتح صفحات الويب تلقائيا</string>
+  <string name="preferences_bulk_mode_summary">المسح الضوئي وحفظها بشكل مستمر العديد من الرموز الشريطية</string>
+  <string name="preferences_bulk_mode_title">جل وضع المسح الضوئي</string>
+  <string name="preferences_copy_to_clipboard_title">نسخ إلى الحافظة</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">التبديلات : s٪ = المحتويات ،  f٪ = الشكل ، اكتب t٪ =</string>
+  <string name="preferences_custom_product_search_title">عنوان بحث مخصص</string>
+  <string name="preferences_decode_1D_industrial_title">1D الصناعية</string>
+  <string name="preferences_decode_1D_product_title">1D المنتج</string>
+  <string name="preferences_decode_Aztec_title">ازتك</string>
+  <string name="preferences_decode_Data_Matrix_title">فك رموز البيانات ماتريكس</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">فك رموز QR</string>
+  <string name="preferences_device_bug_workarounds_title">الحلول جهاز علة</string>
+  <string name="preferences_disable_barcode_scene_mode_title">لا توجد طريقة الباركود المشهد</string>
+  <string name="preferences_disable_continuous_focus_summary">استخدام وضع معيار التركيز فقط</string>
+  <string name="preferences_disable_continuous_focus_title">لا التركيز المستمر</string>
+  <string name="preferences_disable_exposure_title">لا تعرض</string>
+  <string name="preferences_disable_metering_title">لا القياس</string>
+  <string name="preferences_front_light_auto">أوتوماتيكي</string>
+  <string name="preferences_front_light_off">غير فعال</string>
+  <string name="preferences_front_light_on">نشط</string>
+  <string name="preferences_front_light_summary">تقوم بتحسين عملية المسح في إضاءة ضعيفة في بعض الهواتف، ولكن يمكن أن يتسبب في حدوث سطوع</string>
+  <string name="preferences_front_light_title">استخدم إضاءة أمامية</string>
+  <string name="preferences_general_title">إعدادات عامة</string>
+  <string name="preferences_history_summary">تخزين عمليات الفحص الخاص بك في التاريخ</string>
+  <string name="preferences_history_title">أضف إلى التاريخ</string>
+  <string name="preferences_invert_scan_summary">مسح الباركود لأبيض على خلفية سوداء. لا تتوفر على بعض الأجهزة.</string>
+  <string name="preferences_invert_scan_title">عكس المسح الضوئي</string>
+  <string name="preferences_name">إعدادات</string>
+  <string name="preferences_orientation_title">أي التناوب التلقائي</string>
+  <string name="preferences_play_beep_title">صوت تنبيه</string>
+  <string name="preferences_remember_duplicates_summary">بفحص مخزن متعددة من نفس الباركود في التاريخ</string>
+  <string name="preferences_remember_duplicates_title">تذكر التكرارات</string>
+  <string name="preferences_result_title">إعدادات النتائج</string>
+  <string name="preferences_scanning_title">عندما لمسح الباركود</string>
+  <string name="preferences_search_country">ابحث عن بلد</string>
+  <string name="preferences_supplemental_summary">محاولة لاسترداد مزيد من المعلومات حول محتويات الباركود</string>
+  <string name="preferences_supplemental_title">استرداد مزيد من المعلومات</string>
+  <string name="preferences_vibrate_title">اهتزاز</string>
+  <string name="result_address_book">تم العثور على معلومات جهة الاتصال</string>
+  <string name="result_calendar">تم العثور على حدث التقويم</string>
+  <string name="result_email_address">تم العثور على عنوان البريد</string>
+  <string name="result_geo">تم العثور على الإحداثيات الجغرافية</string>
+  <string name="result_isbn">تم العثور على الكتاب</string>
+  <string name="result_product">تم العثور على المنتج</string>
+  <string name="result_sms">تم العثور على عنوان SMS</string>
+  <string name="result_tel">تم العثور على رقم الهاتف</string>
+  <string name="result_text">تم العثور على نص عادي</string>
+  <string name="result_uri">تم العثور على العنوان</string>
+  <string name="result_wifi">العثور على التكوين اللاسلك</string>
+  <string name="sbc_name">البحث في Google Book</string>
+  <string name="wifi_changing_network">طلب الاتصال بالشبكة\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-bg/strings.xml b/BarCodeScanner/mobile/src/main/res/values-bg/strings.xml
new file mode 100644 (file)
index 0000000..4c9eba2
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Баркод Скенер</string>
+  <string name="app_picker_name">Приложения</string>
+  <string name="bookmark_picker_name">Отметки</string>
+  <string name="button_add_calendar">Добави в календар</string>
+  <string name="button_add_contact">Добави контакт</string>
+  <string name="button_book_search">Търси Книга</string>
+  <string name="button_cancel">Отказ</string>
+  <string name="button_custom_product_search">Потребителско търсене</string>
+  <string name="button_dial">Набери телефон</string>
+  <string name="button_email">Изпрати поща</string>
+  <string name="button_get_directions">Навигация</string>
+  <string name="button_mms">Изпрати MMS</string>
+  <string name="button_ok">ОК</string>
+  <string name="button_open_browser">Отвори браузър</string>
+  <string name="button_product_search">Търсене на продукт</string>
+  <string name="button_search_book_contents">Търси в книга</string>
+  <string name="button_share_app">Приложение</string>
+  <string name="button_share_bookmark">Отметка</string>
+  <string name="button_share_by_email">Сподели по поща</string>
+  <string name="button_share_by_sms">Сподели чрез SMS</string>
+  <string name="button_share_clipboard">Клипборд</string>
+  <string name="button_share_contact">Контакт</string>
+  <string name="button_show_map">Покажи карта</string>
+  <string name="button_sms">Изпрати SMS</string>
+  <string name="button_web_search">Интернет търсене</string>
+  <string name="button_wifi">Свържи се в мрежата</string>
+  <string name="contents_contact">Информация за контакт</string>
+  <string name="contents_email">Електронна поща</string>
+  <string name="contents_location">Географски координати</string>
+  <string name="contents_phone">Телефон</string>
+  <string name="contents_sms">SMS адрес</string>
+  <string name="contents_text">Чист текст</string>
+  <string name="history_clear_one_history_text">Изчисти</string>
+  <string name="history_clear_text">Изчисти историята</string>
+  <string name="history_email_title">История на Баркод Скенера</string>
+  <string name="history_empty">Празно</string>
+  <string name="history_empty_detail">Няма сканирани и записани бар-кодове все още</string>
+  <string name="history_send">Изпрати историята</string>
+  <string name="history_title">История</string>
+  <string name="menu_encode_mecard">Използвай MECARD формат</string>
+  <string name="menu_encode_vcard">Използвай vCard формат</string>
+  <string name="menu_help">Помощ</string>
+  <string name="menu_history">История</string>
+  <string name="menu_settings">Настройки</string>
+  <string name="menu_share">Сподели</string>
+  <string name="msg_bulk_mode_scanned">Масов режим: баркодът е сканиран и записан</string>
+  <string name="msg_camera_framework_bug">Съжаляваме, срещнахме проблем с камерата. Може да се наложи да рестартирате устройството си.</string>
+  <string name="msg_default_format">Формат</string>
+  <string name="msg_default_meta">Допълнение</string>
+  <string name="msg_default_mms_subject">Здравейте</string>
+  <string name="msg_default_status">Сложете баркода вътре в правоъгълника за да го сканирате.</string>
+  <string name="msg_default_time">Време</string>
+  <string name="msg_default_type">Тип</string>
+  <string name="msg_encode_contents_failed">Неуспешно кодиране на подадените данни.</string>
+  <string name="msg_error">Грешка</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Съжаляваме, но нужното приложение не успя да се стартира. Възможно е баркода или съдържанието му да са невалидни.</string>
+  <string name="msg_invalid_value">Невалидна стойност</string>
+  <string name="msg_redirect">Пренасочване</string>
+  <string name="msg_sbc_book_not_searchable">Съжаляваме, тази книга не може да се претърсва.</string>
+  <string name="msg_sbc_failed">Съжаляваме, срещнахме проблем при търсенето.</string>
+  <string name="msg_sbc_no_page_returned">Няма страница</string>
+  <string name="msg_sbc_page">Страница</string>
+  <string name="msg_sbc_results">Резултати</string>
+  <string name="msg_sbc_searching_book">Търсене на книга\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Изрезката не е достъпна</string>
+  <string name="msg_share_explanation">Можете да споделяте информация като покажете баркод на екрана, и го сканирате от друг телефон.</string>
+  <string name="msg_share_text">Или въведете някакъв текст</string>
+  <string name="msg_sure">Сигурни ли сте?</string>
+  <string name="msg_unmount_usb">Съжаляваме, но SD картата не е достъпна.</string>
+  <string name="preferences_actions_title">При прочитане на баркод\u2026</string>
+  <string name="preferences_auto_focus_title">Използване на автоматично фокусиране</string>
+  <string name="preferences_auto_open_web_title">Отворете уеб страници автоматично</string>
+  <string name="preferences_bulk_mode_summary">Сканирай и запомняй множество баркодове без прекъсване</string>
+  <string name="preferences_bulk_mode_title">Масово сканиране</string>
+  <string name="preferences_copy_to_clipboard_title">Копиране в клипборда</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Използвайте: %s за съдържанието,%f за форматa, %t за типа</string>
+  <string name="preferences_custom_product_search_title">Потребителски адрес за търсене</string>
+  <string name="preferences_decode_1D_industrial_title">1D Индустриална</string>
+  <string name="preferences_decode_1D_product_title">1D продукта</string>
+  <string name="preferences_decode_Aztec_title">Ацтеките</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR Баркодове</string>
+  <string name="preferences_device_bug_workarounds_title">Заобикаляне на проблеми</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Никакъв режим баркод сцена</string>
+  <string name="preferences_disable_continuous_focus_summary">Използване само на стандартен режим за фокусиране</string>
+  <string name="preferences_disable_continuous_focus_title">Без непрекъснат фокус</string>
+  <string name="preferences_disable_exposure_title">Никоя експозиция</string>
+  <string name="preferences_disable_metering_title">Не измерване</string>
+  <string name="preferences_front_light_auto">Автоматичен</string>
+  <string name="preferences_front_light_off">Неактивен</string>
+  <string name="preferences_front_light_on">Активен</string>
+  <string name="preferences_front_light_summary">Подобрява четенето при лошо осветление, но предизвиква отблясъци. Само за някои модели.</string>
+  <string name="preferences_front_light_title">Използвай фенерче</string>
+  <string name="preferences_general_title">Общи настройки</string>
+  <string name="preferences_history_summary">Съхранявайте сканирания в историята</string>
+  <string name="preferences_history_title">Добави към История</string>
+  <string name="preferences_invert_scan_summary">Сканиране за бели баркодове на черен фон. Не е на разположение на някои устройства.</string>
+  <string name="preferences_invert_scan_title">Обръщане на сканиране</string>
+  <string name="preferences_name">Настройки</string>
+  <string name="preferences_orientation_title">Без автоматично завъртане</string>
+  <string name="preferences_play_beep_title">Издаване на звук</string>
+  <string name="preferences_remember_duplicates_summary">Записвай множество сканирания на един и същи баркод в историята</string>
+  <string name="preferences_remember_duplicates_title">Запомняне на повторенията</string>
+  <string name="preferences_result_title">Настройки за резултата</string>
+  <string name="preferences_scanning_title">При сканиране да се декодират\u2026</string>
+  <string name="preferences_search_country">Държава при търсене</string>
+  <string name="preferences_supplemental_summary">Опитай да получиш повече информация за баркода</string>
+  <string name="preferences_supplemental_title">Търсене на разширения</string>
+  <string name="preferences_vibrate_title">Вибрация</string>
+  <string name="result_address_book">Намерих информация за контакт</string>
+  <string name="result_calendar">Намерих календарно събитие</string>
+  <string name="result_email_address">Намерих адрес на електронна поща</string>
+  <string name="result_geo">Намерих географски координати</string>
+  <string name="result_isbn">Намерих книга</string>
+  <string name="result_product">Намерих продукт</string>
+  <string name="result_sms">Намерих адрес за SMS</string>
+  <string name="result_tel">Намерих телефонен номер</string>
+  <string name="result_text">Намерих чист текст</string>
+  <string name="result_uri">Намерих Интернет Адрес</string>
+  <string name="result_wifi">Намерих настройки за безжична мрежа</string>
+  <string name="sbc_name">Гугъл търсене на книга</string>
+  <string name="wifi_changing_network">Запитване свързване към мрежата\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-ca/strings.xml b/BarCodeScanner/mobile/src/main/res/values-ca/strings.xml
new file mode 100644 (file)
index 0000000..62e62c8
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Aplicacions</string>
+  <string name="bookmark_picker_name">Adreces d\'interès</string>
+  <string name="button_add_calendar">Afegeix a l\'agenda</string>
+  <string name="button_add_contact">Afegeix el contact</string>
+  <string name="button_book_search">Cerca el llibre</string>
+  <string name="button_cancel">Cancel·la</string>
+  <string name="button_custom_product_search">Cerca personalitzada</string>
+  <string name="button_dial">Marca el número</string>
+  <string name="button_email">Envia un correu electrònic</string>
+  <string name="button_get_directions">Obté direccions</string>
+  <string name="button_mms">Envia MMS</string>
+  <string name="button_ok">D\'acord</string>
+  <string name="button_open_browser">Obre el navegador</string>
+  <string name="button_product_search">Cerca un producte</string>
+  <string name="button_search_book_contents">Cerca continguts</string>
+  <string name="button_share_app">Aplicació</string>
+  <string name="button_share_bookmark">Adreça d\'interès</string>
+  <string name="button_share_by_email">Comparteix per correu-e</string>
+  <string name="button_share_by_sms">Comparteix per SMS</string>
+  <string name="button_share_clipboard">Porta-retalls</string>
+  <string name="button_share_contact">Contacte</string>
+  <string name="button_show_map">Mostra el mapa</string>
+  <string name="button_sms">Envia SMS</string>
+  <string name="button_web_search">Cerca al web</string>
+  <string name="button_wifi">Connecta a la xarxa</string>
+  <string name="contents_contact">Informació de contacte</string>
+  <string name="contents_email">Adreça electrònica</string>
+  <string name="contents_location">Coordenades geogràfiques</string>
+  <string name="contents_phone">Número de telèfon</string>
+  <string name="contents_sms">Adreça SMS</string>
+  <string name="contents_text">Text pla</string>
+  <string name="history_clear_one_history_text">Neteja</string>
+  <string name="history_clear_text">Neteja l\'historial</string>
+  <string name="history_email_title">Historial del Barcode Scanner</string>
+  <string name="history_empty">Buit</string>
+  <string name="history_empty_detail">No escaneja codis de barres s\'han registrat encara</string>
+  <string name="history_send">Envia l\'historial</string>
+  <string name="history_title">Historial</string>
+  <string name="menu_encode_mecard">Utilitza MECARD</string>
+  <string name="menu_encode_vcard">Utilitza vCard</string>
+  <string name="menu_help">Ajuda</string>
+  <string name="menu_history">Historial</string>
+  <string name="menu_settings">Configuració</string>
+  <string name="menu_share">Comparteix</string>
+  <string name="msg_bulk_mode_scanned">Mode en bloc: codi de barres escanejat i desat</string>
+  <string name="msg_camera_framework_bug">S\'ha produït un problema amb la càmera de l\'Android. Potser haureu de reiniciar el dispositiu.</string>
+  <string name="msg_default_format">Format</string>
+  <string name="msg_default_meta">Metadadades</string>
+  <string name="msg_default_mms_subject">Hola</string>
+  <string name="msg_default_status">Poseu un codi de barres dins el rectable per escanejar-lo.</string>
+  <string name="msg_default_time">Hora</string>
+  <string name="msg_default_type">Tipus</string>
+  <string name="msg_encode_contents_failed">No es pot codificar un codi de barres amb les dades proporcionades.</string>
+  <string name="msg_error">Error</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">No es pot executar l\'aplicació sol·licitada. És possible que el contingut del codi de barres no sigui vàlid.</string>
+  <string name="msg_invalid_value">Valor no vàlid</string>
+  <string name="msg_redirect">Redirecciona</string>
+  <string name="msg_sbc_book_not_searchable">No es pot cercar en aquest llibre.</string>
+  <string name="msg_sbc_failed">Hi ha hagut un problema en fer la cerca.</string>
+  <string name="msg_sbc_no_page_returned">No s\'ha retornat cap pàgina</string>
+  <string name="msg_sbc_page">Pàgina</string>
+  <string name="msg_sbc_results">Resultats</string>
+  <string name="msg_sbc_searching_book">S\'està cercant el llibre\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Fragment no disponible</string>
+  <string name="msg_share_explanation">Podeu compartir dades mostrant un codi de barres a la pantalla i escanejant-lo amb un altre dispositiu.</string>
+  <string name="msg_share_text">O escriviu un text i pitgeu Retorn</string>
+  <string name="msg_sure">N\'esteu segur?</string>
+  <string name="msg_unmount_usb">La targeta SD no es troba disponible.</string>
+  <string name="preferences_actions_title">En trobar un codi de barres\u2026</string>
+  <string name="preferences_auto_focus_title">Utilitzeu l\'enfocament automàtic</string>
+  <string name="preferences_auto_open_web_title">Obrir pàgines web automàticament</string>
+  <string name="preferences_bulk_mode_summary">Escaneja i desa molts codis de barres de forma contínua</string>
+  <string name="preferences_bulk_mode_title">Mode d\'escaneig en bloc</string>
+  <string name="preferences_copy_to_clipboard_title">Copia al porta-retalls</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Substitucions: %s = contingut, %f = format, %t = tipus</string>
+  <string name="preferences_custom_product_search_title">URL de cerca personalitzat</string>
+  <string name="preferences_decode_1D_industrial_title">1D Industrial</string>
+  <string name="preferences_decode_1D_product_title">Producte 1D</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Matriu de dades</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">Codis QR</string>
+  <string name="preferences_device_bug_workarounds_title">Solucions provisionals de dispositius d\'errors</string>
+  <string name="preferences_disable_barcode_scene_mode_title">No la manera d\'escena de codi de barres</string>
+  <string name="preferences_disable_continuous_focus_summary">Utilitzeu només la manera d\'enfocament estàndard</string>
+  <string name="preferences_disable_continuous_focus_title">No enfocament continu</string>
+  <string name="preferences_disable_exposure_title">No hi ha exposició</string>
+  <string name="preferences_disable_metering_title">No dosificadora</string>
+  <string name="preferences_front_light_auto">Automàtic</string>
+  <string name="preferences_front_light_off">Inactiu</string>
+  <string name="preferences_front_light_on">Actiu</string>
+  <string name="preferences_front_light_summary">Millora l\'escaneig amb poca llum en alguns dispositius, però pot produir enlluernament. No funciona en tots els dispositius.</string>
+  <string name="preferences_front_light_title">Usa el llum frontal</string>
+  <string name="preferences_general_title">Configuració general</string>
+  <string name="preferences_history_summary">Emmagatzemi les seves exploracions de la història</string>
+  <string name="preferences_history_title">Afegir a la Història</string>
+  <string name="preferences_invert_scan_summary">Escanejar codis de barres blanques sobre fons negre. No disponible en alguns dispositius.</string>
+  <string name="preferences_invert_scan_title">Invertir exploració</string>
+  <string name="preferences_name">Configuració</string>
+  <string name="preferences_orientation_title">No hi ha rotació automàtica</string>
+  <string name="preferences_play_beep_title">Beep</string>
+  <string name="preferences_remember_duplicates_summary">Desa diversos escanejos del mateix codi de barres a l\'historial</string>
+  <string name="preferences_remember_duplicates_title">Recorda els duplicats</string>
+  <string name="preferences_result_title">Configuració dels resultats</string>
+  <string name="preferences_scanning_title">En escanejar codis de barres, descodifica\u2026</string>
+  <string name="preferences_search_country">Cerca per país</string>
+  <string name="preferences_supplemental_summary">Intenta obtenir més informació sobre els continguts del codi de barres</string>
+  <string name="preferences_supplemental_title">Aconsegueix més informació</string>
+  <string name="preferences_vibrate_title">Vibració</string>
+  <string name="result_address_book">S\'ha trobat informació de contacte</string>
+  <string name="result_calendar">S\'ha trobat un esdeveniment</string>
+  <string name="result_email_address">S\'ha trobat una adreça electrònica</string>
+  <string name="result_geo">S\'han trobat coordenades geogràfiques</string>
+  <string name="result_isbn">S\'ha trobat un llibre</string>
+  <string name="result_product">S\'ha trobat un producte</string>
+  <string name="result_sms">S\'ha trobat una adreça SMS</string>
+  <string name="result_tel">S\'ha trobat un número de telèfon</string>
+  <string name="result_text">S\'ha trobat text pla</string>
+  <string name="result_uri">S\'ha trobat un URL</string>
+  <string name="result_wifi">S\'ha trobat configuració WLAN</string>
+  <string name="sbc_name">Cerca a Google Llibres</string>
+  <string name="wifi_changing_network">Sollicitant connexió a la xarxa\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-cs/strings.xml b/BarCodeScanner/mobile/src/main/res/values-cs/strings.xml
new file mode 100644 (file)
index 0000000..bd7afda
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Aplikace</string>
+  <string name="bookmark_picker_name">Záložky</string>
+  <string name="button_add_calendar">Přidat do kalendáře</string>
+  <string name="button_add_contact">Přidat kontakt</string>
+  <string name="button_book_search">Hledat knihu</string>
+  <string name="button_cancel">Zrušit</string>
+  <string name="button_custom_product_search">Vlastní vyhledávání</string>
+  <string name="button_dial">Číselník</string>
+  <string name="button_email">Poslat emailem</string>
+  <string name="button_get_directions">Získat nastavení</string>
+  <string name="button_mms">Zaslat přes MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Otevřít prohlížeč</string>
+  <string name="button_product_search">Vyhledat produkt</string>
+  <string name="button_search_book_contents">Hledat obsah knihy</string>
+  <string name="button_share_app">Aplikace</string>
+  <string name="button_share_bookmark">Záložky</string>
+  <string name="button_share_by_email">Sdílet pomocí emailu</string>
+  <string name="button_share_by_sms">Sdílet pomocí SMS</string>
+  <string name="button_share_clipboard">Schránka</string>
+  <string name="button_share_contact">Kontakty</string>
+  <string name="button_show_map">Ukázat na mapě</string>
+  <string name="button_sms">Poslat SMS</string>
+  <string name="button_web_search">Hledat na webu</string>
+  <string name="button_wifi">Připojení k síti</string>
+  <string name="contents_contact">Kontakty, informace</string>
+  <string name="contents_email">Emailová adresa</string>
+  <string name="contents_location">Zeměpisné údaje</string>
+  <string name="contents_phone">Telefonní číslo</string>
+  <string name="contents_sms">SMS číslo</string>
+  <string name="contents_text">Ostatní</string>
+  <string name="history_clear_one_history_text">Vyčistit</string>
+  <string name="history_clear_text">Vyčistit historii</string>
+  <string name="history_email_title">Barcode Scanner historie</string>
+  <string name="history_empty">Prázdný</string>
+  <string name="history_empty_detail">Žádný čárové kódy nebyly ještě zaznamenány</string>
+  <string name="history_send">Zaslat historii</string>
+  <string name="history_title">Historie</string>
+  <string name="menu_encode_mecard">Použij MECARD</string>
+  <string name="menu_encode_vcard">Použij vCard</string>
+  <string name="menu_help">Pomoc!</string>
+  <string name="menu_history">Historie</string>
+  <string name="menu_settings">Nastavení</string>
+  <string name="menu_share">Sdílet</string>
+  <string name="msg_bulk_mode_scanned">Dávkový režim: čárové kódy naskenované a uložené</string>
+  <string name="msg_camera_framework_bug">Omlouváme se, zjistili jsem problém s fotoaparátem. Možná bude nutné restartovat zařízení.</string>
+  <string name="msg_default_format">Formát</string>
+  <string name="msg_default_meta">Metadata</string>
+  <string name="msg_default_mms_subject">Ahoj</string>
+  <string name="msg_default_status">Zaměřte čtvercem na čárový kód</string>
+  <string name="msg_default_time">Čas</string>
+  <string name="msg_default_type">Typ</string>
+  <string name="msg_encode_contents_failed">Z poskytnutých údajů se nepodařilo rozkódovat čárový kód.</string>
+  <string name="msg_error">Chyba</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Litujeme, požadovanou aplikaci nelze spustit. Čárový kód není funkční.</string>
+  <string name="msg_invalid_value">Neplatná hodnota</string>
+  <string name="msg_redirect">Přesměrování</string>
+  <string name="msg_sbc_book_not_searchable">Omlouváme se, tuto knihu nelze nalézt.</string>
+  <string name="msg_sbc_failed">Omlouváme se, objevil se problém.</string>
+  <string name="msg_sbc_no_page_returned">Stránka nenalezena.</string>
+  <string name="msg_sbc_page">Stránka</string>
+  <string name="msg_sbc_results">Výsledky</string>
+  <string name="msg_sbc_searching_book">Hledání knihy\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Snippet není k dispozici</string>
+  <string name="msg_share_explanation">Můžete sdílet čárový kód na vaší obrazovce a načíst jej jiným telefonem.</string>
+  <string name="msg_share_text">Nebo zadejte nějaký text a zmáčkněte Enter</string>
+  <string name="msg_sure">Jste si jisti?</string>
+  <string name="msg_unmount_usb">Omlouváme se, karta SD není přístupná.</string>
+  <string name="preferences_actions_title">Byl nalezen čárový kód.\u2026</string>
+  <string name="preferences_auto_focus_title">Automatické zaostření</string>
+  <string name="preferences_auto_open_web_title">Otevřete webové stránky automaticky</string>
+  <string name="preferences_bulk_mode_summary">Skenování více čárových kódú bez přerušení, vhodné na dávkové zpracování velkého množství čárových kódú</string>
+  <string name="preferences_bulk_mode_title">Dávkový režim skenování</string>
+  <string name="preferences_copy_to_clipboard_title">Kopírovat do schránky.</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Použijte: %s = obsah, %f = formát, %t = typ</string>
+  <string name="preferences_custom_product_search_title">Vlastní vyhledávání URL</string>
+  <string name="preferences_decode_1D_industrial_title">1D průmyslové</string>
+  <string name="preferences_decode_1D_product_title">1D produktu</string>
+  <string name="preferences_decode_Aztec_title">Aztécký</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR kódy</string>
+  <string name="preferences_device_bug_workarounds_title">Možná zástupná řešení chyb zařízení</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Nevybrán žádný režim snímání čárovného kódu</string>
+  <string name="preferences_disable_continuous_focus_summary">Používejte pouze standardní zaostřování</string>
+  <string name="preferences_disable_continuous_focus_title">Soustavné ostření</string>
+  <string name="preferences_disable_exposure_title">Vypnuta expozice</string>
+  <string name="preferences_disable_metering_title">Vypnuto měření</string>
+  <string name="preferences_front_light_auto">Automatický</string>
+  <string name="preferences_front_light_off">Neaktivní</string>
+  <string name="preferences_front_light_on">Aktivní</string>
+  <string name="preferences_front_light_summary">Zlepšuje skenování při slabém osvětlení na některých telefonech, ale může způsobit oslnění. Nefunguje na všech telefonech.</string>
+  <string name="preferences_front_light_title">Použít světlo</string>
+  <string name="preferences_general_title">Hlavní nastavení</string>
+  <string name="preferences_history_summary">Uložte si skeny v historii</string>
+  <string name="preferences_history_title">Přidat do dějin</string>
+  <string name="preferences_invert_scan_summary">Skenování čárových kódů - bílé na černém pozadí. Není k dispozici v některých zařízeních.</string>
+  <string name="preferences_invert_scan_title">Obrátit skenování</string>
+  <string name="preferences_name">Nastavení</string>
+  <string name="preferences_orientation_title">Vypnout automatické otáčení</string>
+  <string name="preferences_play_beep_title">Zvuky</string>
+  <string name="preferences_remember_duplicates_summary">Duplicity čárových kódú v historii ukládat samostatně, nebo jako jeden čárový kód</string>
+  <string name="preferences_remember_duplicates_title">Zapomatovat všechny duplicity</string>
+  <string name="preferences_result_title">Výsledek nastavení</string>
+  <string name="preferences_scanning_title">Během skenování čárových kódů, dekódovat\u2026</string>
+  <string name="preferences_search_country">Hledání země</string>
+  <string name="preferences_supplemental_summary">Získat více informací o obsahu čárového kódu</string>
+  <string name="preferences_supplemental_title">Získat více informací</string>
+  <string name="preferences_vibrate_title">Vibrace</string>
+  <string name="result_address_book">Kontakt nalezen</string>
+  <string name="result_calendar">Kalendář nalezen</string>
+  <string name="result_email_address">Email nalezen</string>
+  <string name="result_geo">Nalezeny zeměpisné informace</string>
+  <string name="result_isbn">Nalezena Kniha</string>
+  <string name="result_product">Nalezen produkt</string>
+  <string name="result_sms">Nalezena SMS adresa</string>
+  <string name="result_tel">Nalezeno telefoní číslo</string>
+  <string name="result_text">Nalezen nějaký text</string>
+  <string name="result_uri">Nalezeno URL</string>
+  <string name="result_wifi">Nalezeno bezdrátová konfigurace</string>
+  <string name="sbc_name">Google Book Search</string>
+  <string name="wifi_changing_network">Vyžaduje připojení k síti\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-da/strings.xml b/BarCodeScanner/mobile/src/main/res/values-da/strings.xml
new file mode 100644 (file)
index 0000000..82c8fc2
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Applikationer</string>
+  <string name="bookmark_picker_name">Bogmærker</string>
+  <string name="button_add_calendar">Tilføj til kalendar</string>
+  <string name="button_add_contact">Tilføj kontaktperson</string>
+  <string name="button_book_search">Bogsøgning</string>
+  <string name="button_cancel">Annullér</string>
+  <string name="button_custom_product_search">Brugerdefineret søgning</string>
+  <string name="button_dial">Ring til nummeret</string>
+  <string name="button_email">Send e-mail</string>
+  <string name="button_get_directions">Få kørselsanvisninger</string>
+  <string name="button_mms">Send MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Åben browser</string>
+  <string name="button_product_search">Produktsøgning</string>
+  <string name="button_search_book_contents">Søg efter indhold</string>
+  <string name="button_share_app">Applikationer</string>
+  <string name="button_share_bookmark">Bogmærker</string>
+  <string name="button_share_by_email">Del via e-mail</string>
+  <string name="button_share_by_sms">Del via SMS</string>
+  <string name="button_share_clipboard">Udklipsholder</string>
+  <string name="button_share_contact">Kontakter</string>
+  <string name="button_show_map">Vis kort</string>
+  <string name="button_sms">Send SMS</string>
+  <string name="button_web_search">Internetsøgning</string>
+  <string name="button_wifi">Forbind til netværk</string>
+  <string name="contents_contact">Kontaktinfo</string>
+  <string name="contents_email">E-mailadresse</string>
+  <string name="contents_location">Geografiske koordinater</string>
+  <string name="contents_phone">Telefonnummer</string>
+  <string name="contents_sms">SMS-adresse</string>
+  <string name="contents_text">Almindelig tekst</string>
+  <string name="history_clear_one_history_text">Ryd</string>
+  <string name="history_clear_text">Ryd historik</string>
+  <string name="history_email_title">Barcode Scanner-historik</string>
+  <string name="history_empty">Tom</string>
+  <string name="history_empty_detail">Ingen stregkodescanninger er blevet registreret endnu</string>
+  <string name="history_send">Send historik</string>
+  <string name="history_title">Historik</string>
+  <string name="menu_encode_mecard">Brug MECARD</string>
+  <string name="menu_encode_vcard">Brug vCard</string>
+  <string name="menu_help">Hjælp</string>
+  <string name="menu_history">Historik</string>
+  <string name="menu_settings">Indstillinger</string>
+  <string name="menu_share">Del</string>
+  <string name="msg_bulk_mode_scanned">Massetilstand: stregkode scannet og gemt</string>
+  <string name="msg_camera_framework_bug">Beklager, Android-kameraet er stødt på et problem. Du skal muligvis genstarte enheden.</string>
+  <string name="msg_default_format">Format</string>
+  <string name="msg_default_meta">Metadata</string>
+  <string name="msg_default_mms_subject">Hej</string>
+  <string name="msg_default_status">Placér en stregkode inden i firkanten for at aflæse den.</string>
+  <string name="msg_default_time">Tid</string>
+  <string name="msg_default_type">Type</string>
+  <string name="msg_encode_contents_failed">Kunne ikke indkode en stregkode fra oplysningerne givet.</string>
+  <string name="msg_error">Fejl</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Beklager, den ønskede applikation kunne ikke blive startet. Stregkodeindholdet er måsket ugyldigt.</string>
+  <string name="msg_invalid_value">Ugyldig værdi</string>
+  <string name="msg_redirect">Omdirigér</string>
+  <string name="msg_sbc_book_not_searchable">Beklager, denne bog er ikke søgbar.</string>
+  <string name="msg_sbc_failed">Beklager, søgningen er stødt på et problem.</string>
+  <string name="msg_sbc_no_page_returned">Ingen side returnerede</string>
+  <string name="msg_sbc_page">Side</string>
+  <string name="msg_sbc_results">Resultater</string>
+  <string name="msg_sbc_searching_book">Søger bog\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Uddragsvisning ikke tilgængelig</string>
+  <string name="msg_share_explanation">Du kan dele data ved at vise en stregkode på denne skærm, og derefter scanne den med en anden telefon.</string>
+  <string name="msg_share_text">Eller skriv noget tekst</string>
+  <string name="msg_sure">Er du sikker?</string>
+  <string name="msg_unmount_usb">Beklager, SD-kortet er ikke tilgængelig.</string>
+  <string name="preferences_actions_title">Når en stregkode er fundet\u2026</string>
+  <string name="preferences_auto_focus_title">Brug autofokus</string>
+  <string name="preferences_auto_open_web_title">Åbn websider automatisk</string>
+  <string name="preferences_bulk_mode_summary">Scan og gem mange stregkoder uden afbrydelser</string>
+  <string name="preferences_bulk_mode_title">Massescanningstilstand</string>
+  <string name="preferences_copy_to_clipboard_title">Kopiér til udklipsholder</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Udskiftninger: %s = indhold, %f = format, %t = type</string>
+  <string name="preferences_custom_product_search_title">Brugerdefineret søge-URL</string>
+  <string name="preferences_decode_1D_industrial_title">1D Industriel</string>
+  <string name="preferences_decode_1D_product_title">1D Produkt</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Afkod Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">Afkod QR-koder</string>
+  <string name="preferences_device_bug_workarounds_title">Device Bug Løsninger</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Ingen stregkode scenetilstand</string>
+  <string name="preferences_disable_continuous_focus_summary">Brug kun standard fokusindstilling</string>
+  <string name="preferences_disable_continuous_focus_title">Ingen løbende fokus</string>
+  <string name="preferences_disable_exposure_title">Ingen eksponering</string>
+  <string name="preferences_disable_metering_title">Ingen måling</string>
+  <string name="preferences_front_light_auto">Automatisk</string>
+  <string name="preferences_front_light_off">Inaktiv</string>
+  <string name="preferences_front_light_on">Aktiv</string>
+  <string name="preferences_front_light_summary">Forbedrer aflæsning i svagt lys på nogle telefoner, men kan medføre genskær. Virker ikke på alle telefoner.</string>
+  <string name="preferences_front_light_title">Brug frontlys</string>
+  <string name="preferences_general_title">Generelle indstillinger</string>
+  <string name="preferences_history_summary">Gem dine scanninger i Historie</string>
+  <string name="preferences_history_title">Tilføj til Historie</string>
+  <string name="preferences_invert_scan_summary">Scan for hvide stregkoder på sort baggrund. Ikke tilgængelig på nogle enheder.</string>
+  <string name="preferences_invert_scan_title">Inverter scanning</string>
+  <string name="preferences_name">Indstillinger</string>
+  <string name="preferences_orientation_title">Ingen automatisk rotation</string>
+  <string name="preferences_play_beep_title">Bip</string>
+  <string name="preferences_remember_duplicates_summary">Gem flere scanninger af de samme stregkoder i Historik</string>
+  <string name="preferences_remember_duplicates_title">Husk dubletter</string>
+  <string name="preferences_result_title">Resultatindstillinger</string>
+  <string name="preferences_scanning_title">Når der scannes efter stregkoder\u2026</string>
+  <string name="preferences_search_country">Søg efter land</string>
+  <string name="preferences_supplemental_summary">Prøv at få flere oplysninger om stregkodens indhold</string>
+  <string name="preferences_supplemental_title">Hent mere info</string>
+  <string name="preferences_vibrate_title">Vibrér</string>
+  <string name="result_address_book">Kontaktinfo fundet</string>
+  <string name="result_calendar">Kalendarbegivenhed fundet</string>
+  <string name="result_email_address">E-mailadresse fundet</string>
+  <string name="result_geo">Geografiske koordinater fundet</string>
+  <string name="result_isbn">Bog fundet</string>
+  <string name="result_product">Produkt fundet</string>
+  <string name="result_sms">SMS-adresse fundet</string>
+  <string name="result_tel">Telefonnummer fundet</string>
+  <string name="result_text">Almindelig tekst fundet</string>
+  <string name="result_uri">URL fundet</string>
+  <string name="result_wifi">WLAN-forbindelse fundet</string>
+  <string name="sbc_name">Google Bøger-søgning</string>
+  <string name="wifi_changing_network">Anmoder om tilslutning til netværk\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-de/strings.xml b/BarCodeScanner/mobile/src/main/res/values-de/strings.xml
new file mode 100644 (file)
index 0000000..8c167ba
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Anwendungen</string>
+  <string name="bookmark_picker_name">Lesezeichen</string>
+  <string name="button_add_calendar">Termin hinzufügen</string>
+  <string name="button_add_contact">Kontakt hinzufügen</string>
+  <string name="button_book_search">Büchersuche</string>
+  <string name="button_cancel">Abbruch</string>
+  <string name="button_custom_product_search">Benutzersuche</string>
+  <string name="button_dial">Nummer wählen</string>
+  <string name="button_email">E-Mail senden</string>
+  <string name="button_get_directions">Route berechnen</string>
+  <string name="button_mms">MMS senden</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Browser öffnen</string>
+  <string name="button_product_search">Produktsuche</string>
+  <string name="button_search_book_contents">Buchinhalt durchsuchen</string>
+  <string name="button_share_app">Anwendung</string>
+  <string name="button_share_bookmark">Lesezeichen</string>
+  <string name="button_share_by_email">Als E-Mail weitergeben</string>
+  <string name="button_share_by_sms">Als SMS weitergeben</string>
+  <string name="button_share_clipboard">Zwischenablage</string>
+  <string name="button_share_contact">Kontakt</string>
+  <string name="button_show_map">Karte anzeigen</string>
+  <string name="button_sms">SMS senden</string>
+  <string name="button_web_search">Im Web suchen</string>
+  <string name="button_wifi">Mit diesem WLAN verbinden</string>
+  <string name="contents_contact">Kontaktinfo</string>
+  <string name="contents_email">E-Mail Adresse</string>
+  <string name="contents_location">Koordinaten</string>
+  <string name="contents_phone">Telefonnummer</string>
+  <string name="contents_sms">SMS Adresse</string>
+  <string name="contents_text">Text</string>
+  <string name="history_clear_one_history_text">Löschen</string>
+  <string name="history_clear_text">Verlauf löschen</string>
+  <string name="history_email_title">Barcode Scanner Verlauf</string>
+  <string name="history_empty">Leer</string>
+  <string name="history_empty_detail">Es wurden keine Barcodes aufgezeichnet.</string>
+  <string name="history_send">Verlauf senden</string>
+  <string name="history_title">Verlauf</string>
+  <string name="menu_encode_mecard">MECARD verwenden</string>
+  <string name="menu_encode_vcard">vCard verwenden</string>
+  <string name="menu_help">Hilfe</string>
+  <string name="menu_history">Verlauf</string>
+  <string name="menu_settings">Einstellungen</string>
+  <string name="menu_share">Senden</string>
+  <string name="msg_bulk_mode_scanned">Bulk-Modus: Barcode gescannt und gespeichert</string>
+  <string name="msg_camera_framework_bug">Mit der Android-Kamera ist leider ein Fehler aufgetreten. Es könnte sein, dass Sie das Gerät neu starten müssen.</string>
+  <string name="msg_default_format">Format</string>
+  <string name="msg_default_meta">Metadaten</string>
+  <string name="msg_default_mms_subject">Hi</string>
+  <string name="msg_default_status">Positionieren Sie den Barcode innerhalb des Rechteckes.</string>
+  <string name="msg_default_time">Zeit</string>
+  <string name="msg_default_type">Typ</string>
+  <string name="msg_encode_contents_failed">Aus den Daten kann kein Barcode erzeugt werden.</string>
+  <string name="msg_error">Fehler</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Die gewünschte Applikation kann nicht geöffnet werden. Der Barcode könnte ungültig sein.</string>
+  <string name="msg_invalid_value">Ungültiger Wert</string>
+  <string name="msg_redirect">Umleiten</string>
+  <string name="msg_sbc_book_not_searchable">Dieses Buch kann nicht durchsucht werden.</string>
+  <string name="msg_sbc_failed">Bei der Suche ist ein Fehler aufgetreten.</string>
+  <string name="msg_sbc_no_page_returned">Keine Seite zurückgeliefert.</string>
+  <string name="msg_sbc_page">Seite</string>
+  <string name="msg_sbc_results">Ergebnisse</string>
+  <string name="msg_sbc_searching_book">Durchsuche Buch\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Textschnipsel nicht verfügbar.</string>
+  <string name="msg_share_explanation">Sie können Daten weitergeben, indem Sie einen Barcode auf Ihrem Bildschirm erzeugen und mit einem anderen Handy einscannen.</string>
+  <string name="msg_share_text">Oder geben Sie hier einen Text ein</string>
+  <string name="msg_sure">Sind Sie sicher?</string>
+  <string name="msg_unmount_usb">Leider kann nicht auf die SD-Karte zugegriffen werden.</string>
+  <string name="preferences_actions_title">Wenn ein Barcode erkannt wurde\u2026</string>
+  <string name="preferences_auto_focus_title">Autofokus verwenden</string>
+  <string name="preferences_auto_open_web_title">Öffnen Sie Webseiten automatisch</string>
+  <string name="preferences_bulk_mode_summary">Scannt und speichert mehrere Barcodes nacheinander</string>
+  <string name="preferences_bulk_mode_title">Massenscan</string>
+  <string name="preferences_copy_to_clipboard_title">In die Zwischenablage kopieren</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Platzhalter: %s = Inhalt, %f = Format, %t = Typ</string>
+  <string name="preferences_custom_product_search_title">Eigene Such-URL</string>
+  <string name="preferences_decode_1D_industrial_title">1D-Industrie</string>
+  <string name="preferences_decode_1D_product_title">1D-Produkt</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR Codes</string>
+  <string name="preferences_device_bug_workarounds_title">Geräteabhängige Problemumgehung</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Kein Barcode-Szene-Modus</string>
+  <string name="preferences_disable_continuous_focus_summary">Nur Standard-Fokus-Modus verwenden</string>
+  <string name="preferences_disable_continuous_focus_title">Kein kontinuierlicher Fokus</string>
+  <string name="preferences_disable_exposure_title">Keine Belichtungsmessung</string>
+  <string name="preferences_disable_metering_title">Keine Dosierung</string>
+  <string name="preferences_front_light_auto">Automatisch</string>
+  <string name="preferences_front_light_off">Aus</string>
+  <string name="preferences_front_light_on">Ein</string>
+  <string name="preferences_front_light_summary">Verbessert bei einigen Mobiltelefonen das Scannen bei schwachem Licht, kann aber Überbelichtung verursachen. Funktioniert nicht mit allen Handys.</string>
+  <string name="preferences_front_light_title">Foto LED einschalten</string>
+  <string name="preferences_general_title">Allgemeine Einstellungen</string>
+  <string name="preferences_history_summary">Speichern Sie Ihre Scans im Verlauf</string>
+  <string name="preferences_history_title">Speichern im Verlauf</string>
+  <string name="preferences_invert_scan_summary">Für weiße Barcodes auf schwarzem Hintergrund. Nicht bei allen Geräten verfügbar.</string>
+  <string name="preferences_invert_scan_title">Negativ-Scan</string>
+  <string name="preferences_name">Einstellungen</string>
+  <string name="preferences_orientation_title">Nicht automatisch drehen</string>
+  <string name="preferences_play_beep_title">Piepsen</string>
+  <string name="preferences_remember_duplicates_summary">Speichern mehrerer Scans des gleichen Barcodes im Verlauf</string>
+  <string name="preferences_remember_duplicates_title">Duplikate speichern</string>
+  <string name="preferences_result_title">Ergebnis-Einstellungen</string>
+  <string name="preferences_scanning_title">Beim Scannen von Barcodes, dekodieren\u2026</string>
+  <string name="preferences_search_country">Land für die Suche</string>
+  <string name="preferences_supplemental_summary">Erfahren Sie mehr über den Barcode</string>
+  <string name="preferences_supplemental_title">Weitere Informationen abrufen</string>
+  <string name="preferences_vibrate_title">Vibrieren</string>
+  <string name="result_address_book">Kontakt gefunden</string>
+  <string name="result_calendar">Termin gefunden</string>
+  <string name="result_email_address">E-Mail-Adresse gefunden</string>
+  <string name="result_geo">Koordinaten gefunden</string>
+  <string name="result_isbn">Buch gefunden</string>
+  <string name="result_product">Produkt gefunden</string>
+  <string name="result_sms">SMS-Adresse gefunden</string>
+  <string name="result_tel">Telefonnummer gefunden</string>
+  <string name="result_text">Text gefunden</string>
+  <string name="result_uri">URL gefunden</string>
+  <string name="result_wifi">WLAN-Konfiguration gefunden</string>
+  <string name="sbc_name">Google Book Search</string>
+  <string name="wifi_changing_network">Verbindung zum Netzwerk anfordern\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-el/strings.xml b/BarCodeScanner/mobile/src/main/res/values-el/strings.xml
new file mode 100644 (file)
index 0000000..dc09ff6
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Εφαρμογές</string>
+  <string name="bookmark_picker_name">Σελιδοδείκτες</string>
+  <string name="button_add_calendar">Προσθήκη στο ημερολόγιο</string>
+  <string name="button_add_contact">Προσθήκη στις επαφές</string>
+  <string name="button_book_search">Αναζήτηση βιβλίων</string>
+  <string name="button_cancel">Ακύρωση</string>
+  <string name="button_custom_product_search">Σύνθετη αναζήτηση</string>
+  <string name="button_dial">Κλήση αριθμού</string>
+  <string name="button_email">Αποστολή email</string>
+  <string name="button_get_directions">Λάβετε κατευθύνσεις</string>
+  <string name="button_mms">Αποστολή MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Άνοιγμα browser</string>
+  <string name="button_product_search">Αναζήτηση προϊόντων</string>
+  <string name="button_search_book_contents">Αναζήτηση περιεχομένων</string>
+  <string name="button_share_app">Εφαρμογή</string>
+  <string name="button_share_bookmark">Σελιδοδείκτης</string>
+  <string name="button_share_by_email">Μοιράσου με email</string>
+  <string name="button_share_by_sms">Μοιράσου με SMS</string>
+  <string name="button_share_clipboard">Πρόχειρο</string>
+  <string name="button_share_contact">Επαφή</string>
+  <string name="button_show_map">Δείξε χάρτη</string>
+  <string name="button_sms">Στείλε SMS</string>
+  <string name="button_web_search">Αναζήτηση ιστού</string>
+  <string name="button_wifi">Σύνδεση σε Δίκτυο</string>
+  <string name="contents_contact">Πληροφορίες επαφής</string>
+  <string name="contents_email">Διεύθυνση email</string>
+  <string name="contents_location">Γεωγραφικές συντεταγμένες</string>
+  <string name="contents_phone">Τηλέφωνο</string>
+  <string name="contents_sms">Διεύθνση SMS</string>
+  <string name="contents_text">Απλό κείμενο</string>
+  <string name="history_clear_one_history_text">Διαγραφή</string>
+  <string name="history_clear_text">Διαγραφή ιστορικού</string>
+  <string name="history_email_title">Ιστορικό Barcode Scanner</string>
+  <string name="history_empty">Κενό</string>
+  <string name="history_empty_detail">Δεν έχουν καταγραφεί σαρώσεις barcode</string>
+  <string name="history_send">Αποστολή ιστορικού</string>
+  <string name="history_title">Ιστορικό</string>
+  <string name="menu_encode_mecard">Χρησιμοποιήστε MECARD</string>
+  <string name="menu_encode_vcard">Χρησιμοποιήστε vCard</string>
+  <string name="menu_help">Βοήθεια</string>
+  <string name="menu_history">Ιστορικό</string>
+  <string name="menu_settings">Ρυθμίσεις</string>
+  <string name="menu_share">Κοινή χρήση</string>
+  <string name="msg_bulk_mode_scanned">Μαζική λειτουργία: barcode σκαναρίστηκε και αποθηκεύτηκε</string>
+  <string name="msg_camera_framework_bug">Συγνώμη, προέκυψε ένα πρόβλημα με την κάμερα. Ίσως χρειαστεί να επανεκιννήσετε τη συσκευή.</string>
+  <string name="msg_default_format">Διαμόρφωση</string>
+  <string name="msg_default_meta">Metadata</string>
+  <string name="msg_default_mms_subject">Γεια</string>
+  <string name="msg_default_status">Τοποθετήστε ένα barcode μέσα στο πλαίσιο για να το σκανάρετε.</string>
+  <string name="msg_default_time">Ωρα</string>
+  <string name="msg_default_type">Τύπος</string>
+  <string name="msg_encode_contents_failed">Δεν γίνεται να παραχθεί barcode από αυτά τα δεδομένα.</string>
+  <string name="msg_error">Σφάλμα</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Συγνώμη, η ζητούμενη εφαρμογή δεν μπορεί να εκιννηθεί. Τα δεδομληνα του barcode ίσως δεν είναι έγκυρα.</string>
+  <string name="msg_invalid_value">Μη έγκυρη τιμή</string>
+  <string name="msg_redirect">Ανακατεύθυνση</string>
+  <string name="msg_sbc_book_not_searchable">Συγνώμη, αυτό το βιβλίο δεν βρέθηκε.</string>
+  <string name="msg_sbc_failed">Συγνώμη, η αναζήτηση παρουσίασε πρόβλημα.</string>
+  <string name="msg_sbc_no_page_returned">Δεν βρέθηκε σελίδα</string>
+  <string name="msg_sbc_page">Σελίδα</string>
+  <string name="msg_sbc_results">Αποτελέσματα</string>
+  <string name="msg_sbc_searching_book">Άναζήτηση βιβλίου\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Απόσπασμα μη διαθέσιμο</string>
+  <string name="msg_share_explanation">Μπορείς να μοιραστείς δεδομένα εμφανίζοντας ένα barcode στην οθόνη σου και σκανάροντάς το με ένα άλλο κινητό.</string>
+  <string name="msg_share_text">Ή πληκτολογήστε εδώ κείμενο και πατήστε Enter</string>
+  <string name="msg_sure">Είσαι σίγουρος;</string>
+  <string name="msg_unmount_usb">Συγνώμη, η κάρτα SD δεν είναι προσβάσιμη.</string>
+  <string name="preferences_actions_title">Όταν ένα barcode ανιχνεύεται\u2026</string>
+  <string name="preferences_auto_focus_title">Χρησιμοποιήστε την αυτόματη εστίαση</string>
+  <string name="preferences_auto_open_web_title">Ανοίξτε ιστοσελίδες αυτόματα</string>
+  <string name="preferences_bulk_mode_summary">Σκανάρετε και αποθηκεύστε συνεχόμενα πολλά barcodes</string>
+  <string name="preferences_bulk_mode_title">Λειτουργία μαζικού σκαναρίσματος</string>
+  <string name="preferences_copy_to_clipboard_title">Αντιγραφή στο πρόχειρο</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Αντικαταστάσεις: %s = περιεχόμενο, %f = μορφή, %t = τύπος</string>
+  <string name="preferences_custom_product_search_title">Σύνθετη αναζήτηση</string>
+  <string name="preferences_decode_1D_industrial_title">1D Βιομηχανικά</string>
+  <string name="preferences_decode_1D_product_title">1D Προϊόντος</string>
+  <string name="preferences_decode_Aztec_title">Αζτέκων</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR Codes</string>
+  <string name="preferences_device_bug_workarounds_title">Λύσεις Bug συσκευής</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Δεν λειτουργία σκηνής barcode</string>
+  <string name="preferences_disable_continuous_focus_summary">Χρησιμοποιείτε μόνο τυπική λειτουργία εστίασης</string>
+  <string name="preferences_disable_continuous_focus_title">Δεν συνεχής εστίαση</string>
+  <string name="preferences_disable_exposure_title">Δεν έκθεση</string>
+  <string name="preferences_disable_metering_title">Δεν μέτρησης</string>
+  <string name="preferences_front_light_auto">Αυτόματο</string>
+  <string name="preferences_front_light_off">Αδρανής</string>
+  <string name="preferences_front_light_on">Ενεργός</string>
+  <string name="preferences_front_light_summary">Βελτιώνει το σκανάρισμα με χαμηλο φωτισμό σε μερικά κινητά, ίσως όμως προκαλέσει λάμψη. Δουλεύει σε μερικά κινητά.</string>
+  <string name="preferences_front_light_title">Χρήση μπροστινού φακού</string>
+  <string name="preferences_general_title">Γενικές ρυθμίσεις</string>
+  <string name="preferences_history_summary">Αποθηκεύστε τις σαρώσεις σας στην Ιστορία</string>
+  <string name="preferences_history_title">Προσθήκη στην Ιστορία</string>
+  <string name="preferences_invert_scan_summary">Σάρωση για τη λευκή barcodes σε μαύρο φόντο. Δεν διατίθεται σε ορισμένες συσκευές.</string>
+  <string name="preferences_invert_scan_title">Αντιστροφή της σάρωσης</string>
+  <string name="preferences_name">Ρυθμίσεις</string>
+  <string name="preferences_orientation_title">Όχι αυτόματη περιστροφή</string>
+  <string name="preferences_play_beep_title">Μπιπ</string>
+  <string name="preferences_remember_duplicates_summary">Αποθήκευση πολλαπλών σκαναρισμάτων του ίδιου barcode στο ιστορικό</string>
+  <string name="preferences_remember_duplicates_title">Απομνημόνευση διπλότυπων</string>
+  <string name="preferences_result_title">Ρυθμίσεις αποτελεσμάτων</string>
+  <string name="preferences_scanning_title">Όταν σκανάρεις barcodes, ψάχνε για\u2026</string>
+  <string name="preferences_search_country">Χώρα Αναζήτησης</string>
+  <string name="preferences_supplemental_summary">Προσπάθησε να βρείς περισσότερες πληροφορίες για τα περιεχόμενα του barcode</string>
+  <string name="preferences_supplemental_title">Αναζήτηση για επιπλέον πληροφορίες</string>
+  <string name="preferences_vibrate_title">Δόνηση</string>
+  <string name="result_address_book">Βρέθηκαν πληροφορίες επαφής</string>
+  <string name="result_calendar">Βρέθηκε συμβάν ημερολογίου</string>
+  <string name="result_email_address">Βρέθηκε email</string>
+  <string name="result_geo">Βρέθηκαν γεωγραφικές συντεταγμένες</string>
+  <string name="result_isbn">Βρέθηκε βιβλίο</string>
+  <string name="result_product">Βρέθηκε προϊόν</string>
+  <string name="result_sms">Βρέθηκε διεύθυνση SMS</string>
+  <string name="result_tel">Βρέθηκε τηλέφωνο</string>
+  <string name="result_text">Βρέθηκε κείμενο</string>
+  <string name="result_uri">Βρέθηκε ηλ. διεύθυνση</string>
+  <string name="result_wifi">Βρέθηκαν ρυθμίσεις Wi-Fi</string>
+  <string name="sbc_name">Αναζήτηση βιβλίων Google</string>
+  <string name="wifi_changing_network">Αίτηση σύνδεσης με το δίκτυο\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-es/strings.xml b/BarCodeScanner/mobile/src/main/res/values-es/strings.xml
new file mode 100644 (file)
index 0000000..8d41842
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Aplicaciones</string>
+  <string name="bookmark_picker_name">Marcadores</string>
+  <string name="button_add_calendar">Añadir al calendario</string>
+  <string name="button_add_contact">Añadir contacto</string>
+  <string name="button_book_search">Búsqueda de libros</string>
+  <string name="button_cancel">Cancelar</string>
+  <string name="button_custom_product_search">Búsqueda personalizada</string>
+  <string name="button_dial">Marcar número</string>
+  <string name="button_email">Enviar correo electrónico</string>
+  <string name="button_get_directions">Obtener direcciones</string>
+  <string name="button_mms">Enviar MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Abrir navegador</string>
+  <string name="button_product_search">Búsqueda de productos</string>
+  <string name="button_search_book_contents">Buscar contenido del libro</string>
+  <string name="button_share_app">Aplicación</string>
+  <string name="button_share_bookmark">Marcador</string>
+  <string name="button_share_by_email">Compartir por correo electrónico</string>
+  <string name="button_share_by_sms">Compartir por SMS</string>
+  <string name="button_share_clipboard">Portapapeles</string>
+  <string name="button_share_contact">Contacto</string>
+  <string name="button_show_map">Mostrar mapa</string>
+  <string name="button_sms">Enviar SMS</string>
+  <string name="button_web_search">Búsqueda Web</string>
+  <string name="button_wifi">Conectarse a la red</string>
+  <string name="contents_contact">Información de contacto</string>
+  <string name="contents_email">Dirección de correo electrónico</string>
+  <string name="contents_location">Coordenadas geográficas</string>
+  <string name="contents_phone">Número de teléfono</string>
+  <string name="contents_sms">Dirección SMS</string>
+  <string name="contents_text">Texto</string>
+  <string name="history_clear_one_history_text">Borrar</string>
+  <string name="history_clear_text">Borrar historial</string>
+  <string name="history_email_title">Historial de Escáner de código de barras</string>
+  <string name="history_empty">Vacío</string>
+  <string name="history_empty_detail">Ningún escanea de códigos de barras se han registrado aún</string>
+  <string name="history_send">Enviar historial</string>
+  <string name="history_title">Historial</string>
+  <string name="menu_encode_mecard">Usar MECARD</string>
+  <string name="menu_encode_vcard">Usar vCard</string>
+  <string name="menu_help">Ayuda</string>
+  <string name="menu_history">Historial</string>
+  <string name="menu_settings">Configuración</string>
+  <string name="menu_share">Compartir</string>
+  <string name="msg_bulk_mode_scanned">Modo Masivo: código de barras escaneado y guardado</string>
+  <string name="msg_camera_framework_bug">Lo sentimos, la cámara de Android ha encontrado un problema. Es posible que necesite reiniciar el dispositivo.</string>
+  <string name="msg_default_format">Formato</string>
+  <string name="msg_default_meta">Metadata</string>
+  <string name="msg_default_mms_subject">Hola</string>
+  <string name="msg_default_status">Coloque un código de barras en el interior del rectángulo del visor para escanear.</string>
+  <string name="msg_default_time">Tiempo</string>
+  <string name="msg_default_type">Tipo</string>
+  <string name="msg_encode_contents_failed">No se pudo codificar un código de barras a partir de los datos facilitados.</string>
+  <string name="msg_error">Error</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Lo sentimos, la aplicación solicitada no pudo ser lanzada. El contenido de código de barras puede ser inválida.</string>
+  <string name="msg_invalid_value">Valor no válido</string>
+  <string name="msg_redirect">Redirigir</string>
+  <string name="msg_sbc_book_not_searchable">Lo sentimos, no se puede buscar en este libro.</string>
+  <string name="msg_sbc_failed">Lo sentimos, la búsqueda ha detectado un problema.</string>
+  <string name="msg_sbc_no_page_returned">Página no encontrada</string>
+  <string name="msg_sbc_page">Página</string>
+  <string name="msg_sbc_results">Resultados</string>
+  <string name="msg_sbc_searching_book">Buscando libro\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Fragmentos no están disponibles</string>
+  <string name="msg_share_explanation">Usted puede compartir los datos mostrando un código de barras en su pantalla y escanearlo con otro teléfono.</string>
+  <string name="msg_share_text">O escriba algún texto y presione Enter</string>
+  <string name="msg_sure">¿Está seguro?</string>
+  <string name="msg_unmount_usb">Lo sentimos, la tarjeta SD no está accesible.</string>
+  <string name="preferences_actions_title">Cuando encuentra un código de barras\u2026</string>
+  <string name="preferences_auto_focus_title">Utilizar el enfoque automático</string>
+  <string name="preferences_auto_open_web_title">Abrir páginas web automáticamente</string>
+  <string name="preferences_bulk_mode_summary">Escanear y guardar muchos códigos de barras de forma continua</string>
+  <string name="preferences_bulk_mode_title">Modo masivo de escaneo</string>
+  <string name="preferences_copy_to_clipboard_title">Copiar al portapapeles</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Sustituciones: %s = contenido, %f = formato, %t = tipo</string>
+  <string name="preferences_custom_product_search_title">Búsqueda de productos con URL personalizada</string>
+  <string name="preferences_decode_1D_industrial_title">1D Industrial</string>
+  <string name="preferences_decode_1D_product_title">1D Producto</string>
+  <string name="preferences_decode_Aztec_title">Azteca</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">Códigos QR</string>
+  <string name="preferences_device_bug_workarounds_title">Soluciones provisionales para dispositivos con errores</string>
+  <string name="preferences_disable_barcode_scene_mode_title">No modo de la escena de código de barras</string>
+  <string name="preferences_disable_continuous_focus_summary">Utilice sólo el modo de enfoque estándar</string>
+  <string name="preferences_disable_continuous_focus_title">No enfoque continuo</string>
+  <string name="preferences_disable_exposure_title">No exposición</string>
+  <string name="preferences_disable_metering_title">No dosificadora</string>
+  <string name="preferences_front_light_auto">Automático</string>
+  <string name="preferences_front_light_off">Inactivo</string>
+  <string name="preferences_front_light_on">Activo</string>
+  <string name="preferences_front_light_summary">Mejora la exploración en condiciones de poca luz en algunos teléfonos, pero puede causar deslumbramiento. No funciona en todos los teléfonos.</string>
+  <string name="preferences_front_light_title">Utilizar luz delantera</string>
+  <string name="preferences_general_title">Configuración general</string>
+  <string name="preferences_history_summary">Almacene escáneres en la historia</string>
+  <string name="preferences_history_title">Añadir a Historia</string>
+  <string name="preferences_invert_scan_summary">Escanear códigos de barras blancas sobre fondo negro. No disponible en algunos dispositivos.</string>
+  <string name="preferences_invert_scan_title">Invertir exploración</string>
+  <string name="preferences_name">Configuración</string>
+  <string name="preferences_orientation_title">Sin rotación automática</string>
+  <string name="preferences_play_beep_title">Bip</string>
+  <string name="preferences_remember_duplicates_summary">Almacenar múltiples escáneres del mismo código de barras en el Historial.</string>
+  <string name="preferences_remember_duplicates_title">Recuerde duplicados</string>
+  <string name="preferences_result_title">Configuración de resultados</string>
+  <string name="preferences_scanning_title">Al escanear códigos de barras, descodificar\u2026</string>
+  <string name="preferences_search_country">Buscar país</string>
+  <string name="preferences_supplemental_summary">Trata de recuperar más información sobre el contenido del código de barras.</string>
+  <string name="preferences_supplemental_title">Recuperar más información</string>
+  <string name="preferences_vibrate_title">Vibrar</string>
+  <string name="result_address_book">Información de contacto encontrada</string>
+  <string name="result_calendar">Evento de calendario encontrado</string>
+  <string name="result_email_address">Dirección de correo electrónico encontrado</string>
+  <string name="result_geo">Coordenadas geográficas encontradas</string>
+  <string name="result_isbn">Libro encontrado</string>
+  <string name="result_product">Producto encontrado</string>
+  <string name="result_sms">Dirección de SMS encontrado</string>
+  <string name="result_tel">Número de teléfono encontrado</string>
+  <string name="result_text">Texto encontrado</string>
+  <string name="result_uri">URL encontrada</string>
+  <string name="result_wifi">Configuración de WLAN encontrada</string>
+  <string name="sbc_name">Búsqueda de libros de Google</string>
+  <string name="wifi_changing_network">Solicitando conexión a la red\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-eu/strings.xml b/BarCodeScanner/mobile/src/main/res/values-eu/strings.xml
new file mode 100644 (file)
index 0000000..9ff3c34
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barra-kode Eskanerra</string>
+  <string name="app_picker_name">Aplikazioak</string>
+  <string name="bookmark_picker_name">Laster-markak</string>
+  <string name="button_add_calendar">Gehitu egutegian</string>
+  <string name="button_add_contact">Gehitu kontaktua</string>
+  <string name="button_book_search">Bilatu liburua</string>
+  <string name="button_cancel">Utzi</string>
+  <string name="button_custom_product_search">Bilaketa pertsonalizatua</string>
+  <string name="button_dial">Markatu zenbakia</string>
+  <string name="button_email">Bidali e-posta</string>
+  <string name="button_get_directions">Lortu jarraibideak</string>
+  <string name="button_mms">Bidali MMS-a</string>
+  <string name="button_ok">Ados</string>
+  <string name="button_open_browser">Ireki arakatzailea</string>
+  <string name="button_product_search">Produktu bilaketa</string>
+  <string name="button_search_book_contents">Bilatu edukiak</string>
+  <string name="button_share_app">Aplikazioa</string>
+  <string name="button_share_bookmark">Laster-marka</string>
+  <string name="button_share_by_email">Partekatu e-posta bidez</string>
+  <string name="button_share_by_sms">Partekatu SMS bidez</string>
+  <string name="button_share_clipboard">Arbela</string>
+  <string name="button_share_contact">Kontaktua</string>
+  <string name="button_show_map">Erakutsi mapa</string>
+  <string name="button_sms">Bidali SMS-a</string>
+  <string name="button_web_search">Web bilaketa</string>
+  <string name="button_wifi">Konektatu sarera</string>
+  <string name="contents_contact">Kontaktuaren informazioa</string>
+  <string name="contents_email">E-posta helbidea</string>
+  <string name="contents_location">Koordenatu geografikoak</string>
+  <string name="contents_phone">Telefono zenbakia</string>
+  <string name="contents_sms">SMS helbidea</string>
+  <string name="contents_text">Testu laua</string>
+  <string name="history_clear_one_history_text">Garbitu</string>
+  <string name="history_clear_text">Garbitu historia</string>
+  <string name="history_email_title">Barra-kode Eskanerraren historia</string>
+  <string name="history_empty">Hutsik</string>
+  <string name="history_empty_detail">Ez da inoiz barra-koderik gorde</string>
+  <string name="history_send">Bidali historia</string>
+  <string name="history_title">Historia</string>
+  <string name="menu_encode_mecard">Erabili MECARD</string>
+  <string name="menu_encode_vcard">Erabili vCard</string>
+  <string name="menu_help">Laguntza</string>
+  <string name="menu_history">Historia</string>
+  <string name="menu_settings">Ezarpenak</string>
+  <string name="menu_share">Partekatu</string>
+  <string name="msg_bulk_mode_scanned">Handizkako modua: barra-kodea eskaneatuta eta gordeta</string>
+  <string name="msg_camera_framework_bug">Barkatu, Android kamerak arazo bat izan du. Behar bada gailua berrabiarazi beharko duzu.</string>
+  <string name="msg_default_format">Formatua</string>
+  <string name="msg_default_meta">Metadatuak</string>
+  <string name="msg_default_mms_subject">Kaixo</string>
+  <string name="msg_default_status">Kokatu barra-kode bat laukizuzenaren barruan eskaneatzeko.</string>
+  <string name="msg_default_time">Denbora</string>
+  <string name="msg_default_type">Mota</string>
+  <string name="msg_encode_contents_failed">Ezin izan da barra-kode bat kodetu emandako datuetatik.</string>
+  <string name="msg_error">Error</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Barkatu, eskatutako aplikazioa ezin izan da abiarazi. Behar bada barra-kodearen edukiak baliogabeak dira.</string>
+  <string name="msg_invalid_value">Balio baliogabea</string>
+  <string name="msg_redirect">Berbideratu</string>
+  <string name="msg_sbc_book_not_searchable">Barkatu, liburu honetan ezin da bilaketarik egin.</string>
+  <string name="msg_sbc_failed">Barkatu, bilaketak arazo bat izan du.</string>
+  <string name="msg_sbc_no_page_returned">Ez da orririk itzuli</string>
+  <string name="msg_sbc_page">Orria</string>
+  <string name="msg_sbc_results">Emaitzak</string>
+  <string name="msg_sbc_searching_book">Liburua arakatzen\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Lagina ez dago eskuragarri</string>
+  <string name="msg_share_explanation">Datuak parteka ditzakezu zure pantailan barra-kode bat bistaratu eta beste telefono batekin eskaneatuz.</string>
+  <string name="msg_share_text">Edo idatzi zerbait eta sakatu Enter</string>
+  <string name="msg_sure">Ziur zaude?</string>
+  <string name="msg_unmount_usb">Barkatu, SD txartela ez dago eskuragarri.</string>
+  <string name="preferences_actions_title">Barra kode bat aurkitzean\u2026</string>
+  <string name="preferences_auto_focus_title">Erabili auto foku</string>
+  <string name="preferences_auto_open_web_title">Ireki web orriak automatikoki</string>
+  <string name="preferences_bulk_mode_summary">Eskaneatu eta gorde hainbat barra-kode jarraian</string>
+  <string name="preferences_bulk_mode_title">Handizkako eskaneatze modua</string>
+  <string name="preferences_copy_to_clipboard_title">Kopiatu arbelera</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Ordezkapenak: %s = edukiak, %f = formatua, %t = mota</string>
+  <string name="preferences_custom_product_search_title">Bilaketa URL pertsonalizatua</string>
+  <string name="preferences_decode_1D_industrial_title">1D Industrial</string>
+  <string name="preferences_decode_1D_product_title">1D Product</string>
+  <string name="preferences_decode_Aztec_title">Azteken</string>
+  <string name="preferences_decode_Data_Matrix_title">Datu Matrizeak</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR Kodeak</string>
+  <string name="preferences_device_bug_workarounds_title">Gailuak Bug konponbidea</string>
+  <string name="preferences_disable_barcode_scene_mode_title">No barra eszena modua</string>
+  <string name="preferences_disable_continuous_focus_summary">Erabili estandarrean soilik fokuaren modua</string>
+  <string name="preferences_disable_continuous_focus_title">Etengabeko foku No</string>
+  <string name="preferences_disable_exposure_title">Esposizio No</string>
+  <string name="preferences_disable_metering_title">Neurtzeko No</string>
+  <string name="preferences_front_light_auto">Automatikoa</string>
+  <string name="preferences_front_light_off">Ezgaitutako</string>
+  <string name="preferences_front_light_on">Aktiboak</string>
+  <string name="preferences_front_light_summary">Eskaneatzea hobetzen du zenbait telefonotan argiztapena txikia denean, baina distirak eragin ditzake. Ez du telefono guztietan funtzionatzen.</string>
+  <string name="preferences_front_light_title">Erabili aurreko argia</string>
+  <string name="preferences_general_title">Ezarpen orokorrak</string>
+  <string name="preferences_history_summary">Biltegiratu bilaketen Historian</string>
+  <string name="preferences_history_title">Historia Gehitu</string>
+  <string name="preferences_invert_scan_summary">Atzeko plano beltzean kodeak zuri eskaneatzeko. Zenbait gailuk ez dago eskuragarri.</string>
+  <string name="preferences_invert_scan_title">Alderantzikatu eskaneatzeko</string>
+  <string name="preferences_name">Ezarpenak</string>
+  <string name="preferences_orientation_title">Biraketa No automatikoa</string>
+  <string name="preferences_play_beep_title">Soinu-seinalea</string>
+  <string name="preferences_remember_duplicates_summary">Gorde barra-kode beraren hainbat eskaneatze Historian</string>
+  <string name="preferences_remember_duplicates_title">Gogoratu errepikatuak</string>
+  <string name="preferences_result_title">Emaitzen ezarpenak</string>
+  <string name="preferences_scanning_title">Barra-kodeak eskaneatzean, deskodetu\u2026</string>
+  <string name="preferences_search_country">Bilatu herrialdea</string>
+  <string name="preferences_supplemental_summary">Saiatu barra-kodearen edukiei buruzko informazio gehiago eskuratzen</string>
+  <string name="preferences_supplemental_title">Eskuratu informazio gehiago</string>
+  <string name="preferences_vibrate_title">Bibratu</string>
+  <string name="result_address_book">Kontaktu-informazioa aurkitu da</string>
+  <string name="result_calendar">Egutegiko gertaera aurkitu da</string>
+  <string name="result_email_address">E-posta helbidea aurkitu da</string>
+  <string name="result_geo">Koordenatu geografikoak aurkitu dira</string>
+  <string name="result_isbn">Liburua aurkitu da</string>
+  <string name="result_product">Produktua aurkitu da</string>
+  <string name="result_sms">SMS helbidea aurkitu da</string>
+  <string name="result_tel">Telefono zenbakia aurkitu da</string>
+  <string name="result_text">Testu laua aurkitu da</string>
+  <string name="result_uri">URL-a aurkitu da</string>
+  <string name="result_wifi">WLAN Konfigurazioa aurkitu da</string>
+  <string name="sbc_name">Google Book Bilaketa</string>
+  <string name="wifi_changing_network">Sarerako konexioa eskatzen\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-fi/strings.xml b/BarCodeScanner/mobile/src/main/res/values-fi/strings.xml
new file mode 100644 (file)
index 0000000..2c29b7b
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Ohjelmat</string>
+  <string name="bookmark_picker_name">Kirjanmerkit</string>
+  <string name="button_add_calendar">Lisää kalenteriin</string>
+  <string name="button_add_contact">Lisää yhteystieto</string>
+  <string name="button_book_search">Kirjahaku</string>
+  <string name="button_cancel">Peruuta</string>
+  <string name="button_custom_product_search">Mukautettu haku</string>
+  <string name="button_dial">Soita numeroon</string>
+  <string name="button_email">Lähetä sähköpostia</string>
+  <string name="button_get_directions">Hae ajo-ohjeet</string>
+  <string name="button_mms">Lähetä multimediaviesti</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Avaa selain</string>
+  <string name="button_product_search">Tuotehaku</string>
+  <string name="button_search_book_contents">Hae kirjan sisältö</string>
+  <string name="button_share_app">Ohjelma</string>
+  <string name="button_share_bookmark">Kirjanmerkki</string>
+  <string name="button_share_by_email">Jaa sähköpostilla</string>
+  <string name="button_share_by_sms">Jaa tekstiviestillä</string>
+  <string name="button_share_clipboard">Leikepöytä</string>
+  <string name="button_share_contact">Kontakti</string>
+  <string name="button_show_map">Näytä kartta</string>
+  <string name="button_sms">Lähetä tekstiviesti</string>
+  <string name="button_web_search">Haku netistä</string>
+  <string name="button_wifi">Yhdistä verkkoon</string>
+  <string name="contents_contact">Yhteystiedot</string>
+  <string name="contents_email">Sähköpostiosoite</string>
+  <string name="contents_location">Karttakoordinaatit</string>
+  <string name="contents_phone">Puhelinnumero</string>
+  <string name="contents_sms">Tekstiviestin osoite</string>
+  <string name="contents_text">Teksti</string>
+  <string name="history_clear_one_history_text">Tyhjennä</string>
+  <string name="history_clear_text">Tyhjennä historia</string>
+  <string name="history_email_title">Viivakoodien historia</string>
+  <string name="history_empty">Tyhjä</string>
+  <string name="history_empty_detail">Ei tallennettuja viivakoodeja</string>
+  <string name="history_send">Lähetä historia</string>
+  <string name="history_title">Historia</string>
+  <string name="menu_encode_mecard">Käytä MECARD:ia</string>
+  <string name="menu_encode_vcard">Käytä vCard:ia</string>
+  <string name="menu_help">Ohje</string>
+  <string name="menu_history">Historia</string>
+  <string name="menu_settings">Asetukset</string>
+  <string name="menu_share">Jaa</string>
+  <string name="msg_bulk_mode_scanned">Toistotila: viivakoodi luettu ja tallennetttu</string>
+  <string name="msg_camera_framework_bug">Valitettavasti Androidin kameran toimiinta häiriintyi. Joudut ehkä käynnistämään laitteen uudelleen.</string>
+  <string name="msg_default_format">Muoto</string>
+  <string name="msg_default_meta">Metatiedot</string>
+  <string name="msg_default_mms_subject">Hei</string>
+  <string name="msg_default_status">Aseta viivakoodi neliön sisälle skannataksesi sen.</string>
+  <string name="msg_default_time">Aika</string>
+  <string name="msg_default_type">Tyyppi</string>
+  <string name="msg_encode_contents_failed">Viivakoodia ei voitu muodostaa annetusta datasta.</string>
+  <string name="msg_error">Virhe</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Valitettavasti pyydettyä sovellusta ei voitu käynnistää. Viivakoodin sisältö voi olla virheellinen.</string>
+  <string name="msg_invalid_value">Virheellinen arvo</string>
+  <string name="msg_redirect">Uudelleenohjaus</string>
+  <string name="msg_sbc_book_not_searchable">Valitettavasti tämä kirja ei ole haettavissa.</string>
+  <string name="msg_sbc_failed">Valitettavasti haussa tapahtui virhe.</string>
+  <string name="msg_sbc_no_page_returned">Sivua ei löydy/ei vastausta</string>
+  <string name="msg_sbc_page">Sivu</string>
+  <string name="msg_sbc_results">Tulokset</string>
+  <string name="msg_sbc_searching_book">Haetaan kirjaa\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Kappaletta ei saatavilla</string>
+  <string name="msg_share_explanation">Voit jakaa dataa näyttämällä viivakoodin laitteesi näytöllä ja lukemalla sen toisella laitteella.</string>
+  <string name="msg_share_text">Tai kirjoita tekstiä ja lopeta Enterillä</string>
+  <string name="msg_sure">Oletko varma?</string>
+  <string name="msg_unmount_usb">SD-kortti ei ole käytettävissä.</string>
+  <string name="preferences_actions_title">Kun viivakoodi löytyy\u2026</string>
+  <string name="preferences_auto_focus_title">Käytä automaattista tarkennusta</string>
+  <string name="preferences_auto_open_web_title">Avaa Web-sivujen automaattisesti</string>
+  <string name="preferences_bulk_mode_summary">Skannaa ja tallenna viivakoodeja jatkuvasti</string>
+  <string name="preferences_bulk_mode_title">Jatkuva skannaus</string>
+  <string name="preferences_copy_to_clipboard_title">Kopioi leikepöydälle</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Seuraavat korvataan: %s = sisältö, %f = formaatti, %t = tyyppi</string>
+  <string name="preferences_custom_product_search_title">Mukautettu hakukone</string>
+  <string name="preferences_decode_1D_industrial_title">1D Industrial</string>
+  <string name="preferences_decode_1D_product_title">1D Tuote</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR-koodit</string>
+  <string name="preferences_device_bug_workarounds_title">Laitteen vikojen kiertäminen</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Ei viivakoodin näkymätilaa</string>
+  <string name="preferences_disable_continuous_focus_summary">Käytä vain vakiotarkennusta</string>
+  <string name="preferences_disable_continuous_focus_title">Ei jatkuvaa tarkennusta</string>
+  <string name="preferences_disable_exposure_title">Ei valotusta</string>
+  <string name="preferences_disable_metering_title">Ei mittausta</string>
+  <string name="preferences_front_light_auto">Automaattinen</string>
+  <string name="preferences_front_light_off">Pois</string>
+  <string name="preferences_front_light_on">Päällä</string>
+  <string name="preferences_front_light_summary">Parantaa joissain laitteissa hämärässä skannaamista, mutta voi aiheuttaa häikäisyongelmia. Ei toimi kaikissa puhelimissa.</string>
+  <string name="preferences_front_light_title">Käytä etuosan valoa</string>
+  <string name="preferences_general_title">Yleiset asetukset</string>
+  <string name="preferences_history_summary">Säilytä skannaa historia</string>
+  <string name="preferences_history_title">Lisää Historia</string>
+  <string name="preferences_invert_scan_summary">Etsi valkoisia viivakoodeja mustalla taustalla. Ei toimi kaikilla laitteilla.</string>
+  <string name="preferences_invert_scan_title">Käänteinen (negatiivin) skannaus</string>
+  <string name="preferences_name">Asetukset</string>
+  <string name="preferences_orientation_title">Ei automaattista kiertoa</string>
+  <string name="preferences_play_beep_title">Piippaus</string>
+  <string name="preferences_remember_duplicates_summary">Jos sama viivakoodi skannetaan useasti, tallenna jokainen skannauskerta historiaan</string>
+  <string name="preferences_remember_duplicates_title">Muista kaksoiskappaleet</string>
+  <string name="preferences_result_title">Tuloksien asetukset</string>
+  <string name="preferences_scanning_title">Kun skannataan viivakoodeja, dekoodaa\u2026</string>
+  <string name="preferences_search_country">Etsi maasta</string>
+  <string name="preferences_supplemental_summary">Yritä hakea lisätietoja viivakoodin sisällöstä</string>
+  <string name="preferences_supplemental_title">Hae lisää tietoa</string>
+  <string name="preferences_vibrate_title">Värinä</string>
+  <string name="result_address_book">Löydettiin yhteystietoja</string>
+  <string name="result_calendar">Löydettiin kalenteritapahtuma</string>
+  <string name="result_email_address">Löydettiin sähköpostiosoite</string>
+  <string name="result_geo">Löydettiin koordinaatteja</string>
+  <string name="result_isbn">Löydettiin kirja</string>
+  <string name="result_product">Löydettiin tuote</string>
+  <string name="result_sms">Löydettiin tekstiviestinumero</string>
+  <string name="result_tel">Löydettiin puhelinnumero</string>
+  <string name="result_text">Löydettiin teksti</string>
+  <string name="result_uri">Löydettin URL-osoite</string>
+  <string name="result_wifi">Löydettiin asetukset langattomalle yhteydelle</string>
+  <string name="sbc_name">Googlen kirjahaku</string>
+  <string name="wifi_changing_network">Pyydetään yhteyttä verkkoon\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-fr/strings.xml b/BarCodeScanner/mobile/src/main/res/values-fr/strings.xml
new file mode 100644 (file)
index 0000000..6951a5e
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Applications</string>
+  <string name="bookmark_picker_name">Marque-pages</string>
+  <string name="button_add_calendar">Ajouter à l\'agenda</string>
+  <string name="button_add_contact">Ajouter un contact</string>
+  <string name="button_book_search">Recherche de livre</string>
+  <string name="button_cancel">Annuler</string>
+  <string name="button_custom_product_search">Recherche personnalisée de produit</string>
+  <string name="button_dial">Composer un numéro</string>
+  <string name="button_email">Envoyer un courriel</string>
+  <string name="button_get_directions">Obtenir un itinéraire</string>
+  <string name="button_mms">Envoyer MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Ouvrir le navigateur</string>
+  <string name="button_product_search">Recherche de produit</string>
+  <string name="button_search_book_contents">Rechercher dans le contenu</string>
+  <string name="button_share_app">Application</string>
+  <string name="button_share_bookmark">Marque-page</string>
+  <string name="button_share_by_email">Partager par courriel</string>
+  <string name="button_share_by_sms">Partager par texto</string>
+  <string name="button_share_clipboard">Presse-papiers</string>
+  <string name="button_share_contact">Contact</string>
+  <string name="button_show_map">Afficher la carte</string>
+  <string name="button_sms">Envoyer un texto</string>
+  <string name="button_web_search">Recherche Web</string>
+  <string name="button_wifi">Se connecter au réseau</string>
+  <string name="contents_contact">Informations de contact</string>
+  <string name="contents_email">Adresse courriel</string>
+  <string name="contents_location">Coordonnées géographiques</string>
+  <string name="contents_phone">Numéro de téléphone</string>
+  <string name="contents_sms">Adresse SMS</string>
+  <string name="contents_text">Texte en clair</string>
+  <string name="history_clear_one_history_text">Effacer</string>
+  <string name="history_clear_text">Effacer l\'historique</string>
+  <string name="history_email_title">Historique de Barcode Scanner</string>
+  <string name="history_empty">Vide</string>
+  <string name="history_empty_detail">Aucun code-barre balayé n\'a encore été enregistré</string>
+  <string name="history_send">Envoyer historique</string>
+  <string name="history_title">Historique</string>
+  <string name="menu_encode_mecard">Utiliser MECARD</string>
+  <string name="menu_encode_vcard">Utiliser vCard</string>
+  <string name="menu_help">Aide</string>
+  <string name="menu_history">Historique</string>
+  <string name="menu_settings">Paramètres</string>
+  <string name="menu_share">Partager</string>
+  <string name="msg_bulk_mode_scanned">Balayage en rafale\u00A0: code-barres balayés et enregistrés</string>
+  <string name="msg_camera_framework_bug">Désolé, la caméra Android a rencontré un problème. Un redémarrage de l\'appareil est peut-être nécessaire.</string>
+  <string name="msg_default_format">Format</string>
+  <string name="msg_default_meta">Métadonnées</string>
+  <string name="msg_default_mms_subject">Salut</string>
+  <string name="msg_default_status">Encadrez un code-barres avec le viseur pour le balayer.</string>
+  <string name="msg_default_time">Heure</string>
+  <string name="msg_default_type">Type</string>
+  <string name="msg_encode_contents_failed">Impossible d\'encoder un code-barres à partir des données fournies.</string>
+  <string name="msg_error">Erreur</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Désolé, l\'application demandée n\'a pas pu être lancée. Le contenu du code-barres est peut-être invalide.</string>
+  <string name="msg_invalid_value">Valeur invalide</string>
+  <string name="msg_redirect">Réacheminement</string>
+  <string name="msg_sbc_book_not_searchable">Désolé, ce livre ne peut pas être cherché.</string>
+  <string name="msg_sbc_failed">Désolé, la recherche a rencontré un problème.</string>
+  <string name="msg_sbc_no_page_returned">Aucun résultat</string>
+  <string name="msg_sbc_page">Page</string>
+  <string name="msg_sbc_results">Résultats</string>
+  <string name="msg_sbc_searching_book">Recherche du livre\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Extrait non disponible</string>
+  <string name="msg_share_explanation">Vous pouvez partager des données en affichant un code-barres sur votre écran et en le balayant avec un autre téléphone.</string>
+  <string name="msg_share_text">Ou tapez du texte et appuyez sur Entrée</string>
+  <string name="msg_sure">Le voulez-vous vraiment\u00A0?</string>
+  <string name="msg_unmount_usb">Désolé, la carte SD n\'est pas accessible.</string>
+  <string name="preferences_actions_title">Quand un code-barres est trouvé\u2026</string>
+  <string name="preferences_auto_focus_title">Utiliser la mise au point automatique</string>
+  <string name="preferences_auto_open_web_title">Ouvrir les pages Web automatiquement</string>
+  <string name="preferences_bulk_mode_summary">Balayer et enregistrer des codes-barres en rafale</string>
+  <string name="preferences_bulk_mode_title">Mode de lecture en rafale</string>
+  <string name="preferences_copy_to_clipboard_title">Copier dans le presse-papiers</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Remplacements\u00A0: %s = contenu, %f = format, %t = type</string>
+  <string name="preferences_custom_product_search_title">URL de recherche personnalisée</string>
+  <string name="preferences_decode_1D_industrial_title">1D industrielle</string>
+  <string name="preferences_decode_1D_product_title">1D produit</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">Codes QR</string>
+  <string name="preferences_device_bug_workarounds_title">Paliatifs des bogues de l\'appareil</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Pas de mode scène de code-barres</string>
+  <string name="preferences_disable_continuous_focus_summary">Utiliser uniquement le mode de mise au point standard</string>
+  <string name="preferences_disable_continuous_focus_title">Pas de mise au point continue</string>
+  <string name="preferences_disable_exposure_title">Pas d\'exposition</string>
+  <string name="preferences_disable_metering_title">Pas de mesure</string>
+  <string name="preferences_front_light_auto">Automatique</string>
+  <string name="preferences_front_light_off">Éteinte</string>
+  <string name="preferences_front_light_on">Allumée</string>
+  <string name="preferences_front_light_summary">Améliore le balayage lors d\'une faible luminosité sur certains téléphone, mais peut causer un reflet. Ne fonctionne pas sur tous les téléphones.</string>
+  <string name="preferences_front_light_title">Utiliser la lumière frontale</string>
+  <string name="preferences_general_title">Paramètres généraux</string>
+  <string name="preferences_history_summary">Stockez vos scans dans l\'histoire</string>
+  <string name="preferences_history_title">Ajouter à Histoire</string>
+  <string name="preferences_invert_scan_summary">Balayer des codes-barres blancs sur fond noir. Non disponible sur certains appareils.</string>
+  <string name="preferences_invert_scan_title">Balayage négatif</string>
+  <string name="preferences_name">Paramètres</string>
+  <string name="preferences_orientation_title">Pas de rotation automatique</string>
+  <string name="preferences_play_beep_title">Bip</string>
+  <string name="preferences_remember_duplicates_summary">Enregistrer dans l\'historique les lectures multiples d\'un même code-barres</string>
+  <string name="preferences_remember_duplicates_title">Enregistrer les doublons</string>
+  <string name="preferences_result_title">Paramètres de résultat</string>
+  <string name="preferences_scanning_title">Pendant le balayage de codes-barres, décoder\u2026</string>
+  <string name="preferences_search_country">Pays de recherche</string>
+  <string name="preferences_supplemental_summary">Essayer d\'obtenir plus d\'informations sur le contenu du code-barres</string>
+  <string name="preferences_supplemental_title">Obtenir plus d\'infos</string>
+  <string name="preferences_vibrate_title">Vibreur</string>
+  <string name="result_address_book">Informations de contact trouvées</string>
+  <string name="result_calendar">Événement d\'agenda trouvé</string>
+  <string name="result_email_address">Adresse courriel trouvée</string>
+  <string name="result_geo">Coordonnées géographiques trouvées</string>
+  <string name="result_isbn">Livre trouvé</string>
+  <string name="result_product">Produit trouvé</string>
+  <string name="result_sms">Adresse SMS trouvée</string>
+  <string name="result_tel">Numéro de téléphone trouvé</string>
+  <string name="result_text">Texte en clair trouvé</string>
+  <string name="result_uri">URL trouvée</string>
+  <string name="result_wifi">Configuration WLAN trouvée</string>
+  <string name="sbc_name">Recherche Google Livres</string>
+  <string name="wifi_changing_network">Demande de connexion au réseau\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-he/strings.xml b/BarCodeScanner/mobile/src/main/res/values-he/strings.xml
new file mode 100644 (file)
index 0000000..07a8dc1
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">סורק ברקודים</string>
+  <string name="app_picker_name">יישומים</string>
+  <string name="bookmark_picker_name">סימניות</string>
+  <string name="button_add_calendar">הוסף ללוח שנה</string>
+  <string name="button_add_contact">הוספת איש קשר</string>
+  <string name="button_book_search">חיפוש ספר</string>
+  <string name="button_cancel">ביטול</string>
+  <string name="button_custom_product_search">חיפוש מותאם אישית</string>
+  <string name="button_dial">חייג מספר</string>
+  <string name="button_email">שלח דואר אלקטרוני</string>
+  <string name="button_get_directions">קבל הוראות הגעה</string>
+  <string name="button_mms">שלח הודעת מולטימדיה</string>
+  <string name="button_ok">אישור</string>
+  <string name="button_open_browser">פתח את הדפדפן</string>
+  <string name="button_product_search">חיפוש מוצר</string>
+  <string name="button_search_book_contents">חיפוש בתוכן</string>
+  <string name="button_share_app">יישום</string>
+  <string name="button_share_bookmark">סימניה</string>
+  <string name="button_share_by_email">שתף בדואר אלקטרוני</string>
+  <string name="button_share_by_sms">שתף בהודעה</string>
+  <string name="button_share_clipboard">לוח עריכה</string>
+  <string name="button_share_contact">איש קשר</string>
+  <string name="button_show_map">הצג מפה</string>
+  <string name="button_sms">שלח הודעה</string>
+  <string name="button_web_search">חיפוש באינטרנט</string>
+  <string name="button_wifi">התחבר לרשת</string>
+  <string name="contents_contact">פרטי איש קשר</string>
+  <string name="contents_email">כתובת דואר אלקטרוני</string>
+  <string name="contents_location">קואורדינטות גאוגרפיות</string>
+  <string name="contents_phone">מספר טלפון</string>
+  <string name="contents_sms">כתובת SMS</string>
+  <string name="contents_text">טקסט רגיל</string>
+  <string name="history_clear_one_history_text">נקה</string>
+  <string name="history_clear_text">נקה היסטוריה</string>
+  <string name="history_email_title">היסטוריית סורק הברקודים</string>
+  <string name="history_empty">ריק</string>
+  <string name="history_empty_detail">ברקודים לא נרשמו</string>
+  <string name="history_send">שלח היסטוריה</string>
+  <string name="history_title">היסטוריה</string>
+  <string name="menu_encode_mecard">השתמש MECARD</string>
+  <string name="menu_encode_vcard">השתמש vCard</string>
+  <string name="menu_help">עזרה</string>
+  <string name="menu_history">היסטוריה</string>
+  <string name="menu_settings">הגדרות</string>
+  <string name="menu_share">שתף</string>
+  <string name="msg_bulk_mode_scanned">מצב קבוצה: ברקוד נסרק ונשמר</string>
+  <string name="msg_camera_framework_bug">סליחה, מצלמת האנדרואיד נתקלה בבעיה. ייתכן שיהיה עליך להפעיל מחדש את המכשיר.</string>
+  <string name="msg_default_format">פורמט</string>
+  <string name="msg_default_meta">מטה-נתונים</string>
+  <string name="msg_default_mms_subject">היי</string>
+  <string name="msg_default_status">הצב ברקוד בתוך המלבן כדי לסרוק אותו.</string>
+  <string name="msg_default_time">זמן</string>
+  <string name="msg_default_type">סוג</string>
+  <string name="msg_encode_contents_failed">לא היתה אפשרות לקודד ברקוד מהנתונים שסופקו.</string>
+  <string name="msg_error">שגיאה</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">סליחה, לא ניתן להפעיל את היישום המבוקש. ייתכן שתוכן הברקוד לא תקין.</string>
+  <string name="msg_invalid_value">ערך לא חוקי</string>
+  <string name="msg_redirect">נתב מחדש</string>
+  <string name="msg_sbc_book_not_searchable">סליחה, ספר זה אינו ניתן לחיפוש.</string>
+  <string name="msg_sbc_failed">סליחה, החיפוש נתקל בבעיה.</string>
+  <string name="msg_sbc_no_page_returned">לא הוחזר דף</string>
+  <string name="msg_sbc_page">דף</string>
+  <string name="msg_sbc_results">תוצאות</string>
+  <string name="msg_sbc_searching_book">מחפש ספר\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">גזיר לא זמין</string>
+  <string name="msg_share_explanation">באפשרותך לשתף נתונים על-ידי הצגת ברקוד על המסך וסריקתו עם טלפון אחר.</string>
+  <string name="msg_share_text">או הקלד טקסט כלשהו</string>
+  <string name="msg_sure">האם אתה בטוח?</string>
+  <string name="msg_unmount_usb">סליחה, כרטיס הזכרון אינו נגיש.</string>
+  <string name="preferences_actions_title">כאשר ברקוד נמצא\u2026</string>
+  <string name="preferences_auto_focus_title">להשתמש במיקוד האוטומטי</string>
+  <string name="preferences_auto_open_web_title">לפתוח דפי אינטרנט באופן אוטומטי</string>
+  <string name="preferences_bulk_mode_summary">סורק ושומר ברקודים באופן רציף</string>
+  <string name="preferences_bulk_mode_title">מצב סריקה מרובה</string>
+  <string name="preferences_copy_to_clipboard_title">העתק ללוח</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">החלפות: s% = התוכן, f% = הפורמט, t% = סוג</string>
+  <string name="preferences_custom_product_search_title">כתובת לחיפוש מותאם אישית</string>
+  <string name="preferences_decode_1D_industrial_title">1D תעשייתי</string>
+  <string name="preferences_decode_1D_product_title">1D מוצר</string>
+  <string name="preferences_decode_Aztec_title">האצטקים</string>
+  <string name="preferences_decode_Data_Matrix_title">מטריצת נתונים</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">קודי QR</string>
+  <string name="preferences_device_bug_workarounds_title">באג במכשיר דרכים לעקיפת הבעיה</string>
+  <string name="preferences_disable_barcode_scene_mode_title">אין מצב סצנה ברקוד</string>
+  <string name="preferences_disable_continuous_focus_summary">השתמש רק במצב רגיל פוקוס</string>
+  <string name="preferences_disable_continuous_focus_title">המיקוד לא רציפה</string>
+  <string name="preferences_disable_exposure_title">אין חשיפה</string>
+  <string name="preferences_disable_metering_title">אין מדידה</string>
+  <string name="preferences_front_light_auto">אוטומטי</string>
+  <string name="preferences_front_light_off">לא פעיל</string>
+  <string name="preferences_front_light_on">פעיל</string>
+  <string name="preferences_front_light_summary">משפר את הסריקה בתאורה נמוכה בטלפונים מסוימים, אך עשוי לגרום לסנוור. לא עובד בכל הטלפונים.</string>
+  <string name="preferences_front_light_title">השתמש באור הקדמי</string>
+  <string name="preferences_general_title">הגדרות כלליות</string>
+  <string name="preferences_history_summary">אחסן הסריקות שלך בהיסטוריה</string>
+  <string name="preferences_history_title">הוסף להיסטוריה</string>
+  <string name="preferences_invert_scan_summary">סרוק ברקודים לבן על רקע שחור. לא זמין על התקנים מסוימים.</string>
+  <string name="preferences_invert_scan_title">היפוך לסרוק</string>
+  <string name="preferences_name">הגדרות</string>
+  <string name="preferences_orientation_title">סיבוב לא אוטומטי</string>
+  <string name="preferences_play_beep_title">צפצוף</string>
+  <string name="preferences_remember_duplicates_summary">אחסן מספר סריקות של אותו הברקוד בהיסטוריה</string>
+  <string name="preferences_remember_duplicates_title">זכור כפילויות</string>
+  <string name="preferences_result_title">הגדרות תוצאה</string>
+  <string name="preferences_scanning_title">בעת סריקת ברקודים, קודד\u2026</string>
+  <string name="preferences_search_country">חיפוש הארץ</string>
+  <string name="preferences_supplemental_summary">נסה למצא מידע נוסף על תוכן הברקוד</string>
+  <string name="preferences_supplemental_title">מצא מידע נוסף</string>
+  <string name="preferences_vibrate_title">רטט</string>
+  <string name="result_address_book">נמצא מידע של איש קשר</string>
+  <string name="result_calendar">נמצא אירוע</string>
+  <string name="result_email_address">נמצאה כתובת דוא"ל</string>
+  <string name="result_geo">נמצאו קואורדינטות גיאוגרפיות</string>
+  <string name="result_isbn">נמצא ספר</string>
+  <string name="result_product">נמצא מוצר</string>
+  <string name="result_sms">נמצאה כתובת הודעה</string>
+  <string name="result_tel">נמצא מספר טלפון</string>
+  <string name="result_text">נמצא טקסט</string>
+  <string name="result_uri">נמצאה כתובת אינטרנט</string>
+  <string name="result_wifi">נמצאו הגדרות רשת אל חוטית</string>
+  <string name="sbc_name">Google חיפוש ספרים</string>
+  <string name="wifi_changing_network">בקשת חיבור לרשת \u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-hi/strings.xml b/BarCodeScanner/mobile/src/main/res/values-hi/strings.xml
new file mode 100644 (file)
index 0000000..c8e4cb0
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">बारकोड स्कैनर</string>
+  <string name="app_picker_name">अनुप्रयोगों</string>
+  <string name="bookmark_picker_name">बुकमार्क्स</string>
+  <string name="button_add_calendar">कैलेंडर के लिए जोड़ें</string>
+  <string name="button_add_contact">संपर्क जोड़ें</string>
+  <string name="button_book_search">पुस्तक खोज</string>
+  <string name="button_cancel">रद्द करना</string>
+  <string name="button_custom_product_search">कस्टम खोज</string>
+  <string name="button_dial">डायल नंबर</string>
+  <string name="button_email">ईमेल भेजें</string>
+  <string name="button_get_directions">निर्देश प्राप्त करें</string>
+  <string name="button_mms">एमएमएस भेजें</string>
+  <string name="button_ok">ठीक है</string>
+  <string name="button_open_browser">ओपन ब्राउज़र</string>
+  <string name="button_product_search">उत्पाद खोज</string>
+  <string name="button_search_book_contents">खोज सामग्री</string>
+  <string name="button_share_app">आवेदन</string>
+  <string name="button_share_bookmark">बुकमार्क</string>
+  <string name="button_share_by_email">ईमेल के माध्यम से साझा करें</string>
+  <string name="button_share_by_sms">एसएमएस के जरिए शेयर</string>
+  <string name="button_share_clipboard">क्लिपबोर्ड</string>
+  <string name="button_share_contact">संपर्क</string>
+  <string name="button_show_map">नक्शा दिखाएँ</string>
+  <string name="button_sms">एसएमएस भेजें</string>
+  <string name="button_web_search">वेब खोज</string>
+  <string name="button_wifi">नेटवर्क कनेक्ट करें</string>
+  <string name="contents_contact">संपर्क जानकारी</string>
+  <string name="contents_email">ईमेल पता</string>
+  <string name="contents_location">भौगोलिक निर्देशांक</string>
+  <string name="contents_phone">फ़ोन नंबर</string>
+  <string name="contents_sms">एसएमएस पता</string>
+  <string name="contents_text">सादा पाठ</string>
+  <string name="history_clear_one_history_text">हटाएँ</string>
+  <string name="history_clear_text">इतिहास हटाएँ</string>
+  <string name="history_email_title">बारकोड स्कैनर इतिहास</string>
+  <string name="history_empty">खाली</string>
+  <string name="history_empty_detail">अभी तक कोई बारकोड स्कैन दर्ज किया गया है</string>
+  <string name="history_send">इतिहास भेजें</string>
+  <string name="history_title">इतिहास</string>
+  <string name="menu_encode_mecard">MECARD का प्रयोग करें</string>
+  <string name="menu_encode_vcard">vCard का प्रयोग करें</string>
+  <string name="menu_help">मदद</string>
+  <string name="menu_history">इतिहास</string>
+  <string name="menu_settings">सेटिंग्स</string>
+  <string name="menu_share">शेयर</string>
+  <string name="msg_bulk_mode_scanned">थोक मोड: बारकोड स्कैन और बचाया</string>
+  <string name="msg_camera_framework_bug">क्षमा करें, Android कैमरा एक समस्या का सामना करना पड़ा. आप डिवाइस को पुनरारंभ करने की आवश्यकता हो सकती है.</string>
+  <string name="msg_default_format">प्रारूप</string>
+  <string name="msg_default_meta">मेटाडाटा</string>
+  <string name="msg_default_mms_subject">हाय</string>
+  <string name="msg_default_status">दृश्यदर्शी आयत के अंदर एक बारकोड प्लेस इसे स्कैन.</string>
+  <string name="msg_default_time">समय</string>
+  <string name="msg_default_type">टाइप</string>
+  <string name="msg_encode_contents_failed">उपलब्ध कराए गए आंकड़ों से एक बारकोड सांकेतिक शब्दों में बदलना नहीं कर सका.</string>
+  <string name="msg_error">त्रुटि</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">क्षमा करें, अनुरोध आवेदन शुरू नहीं किया जा सका. बारकोड सामग्री अमान्य हो सकता है.</string>
+  <string name="msg_invalid_value">अवैध मान</string>
+  <string name="msg_redirect">पुनर्निर्देशन</string>
+  <string name="msg_sbc_book_not_searchable">क्षमा करें, इस किताब को खोजा नहीं है.</string>
+  <string name="msg_sbc_failed">क्षमा करें, खोज एक समस्या का सामना करना पड़ा.</string>
+  <string name="msg_sbc_no_page_returned">कोई पृष्ठ लौटे</string>
+  <string name="msg_sbc_page">पेज</string>
+  <string name="msg_sbc_results">परिणाम</string>
+  <string name="msg_sbc_searching_book">खोज पुस्तक\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">उपलब्ध स्निपेट नहीं</string>
+  <string name="msg_share_explanation">आप अपनी स्क्रीन पर प्रदर्शित बारकोड और यह अन्य फोन के साथ स्कैनिंग द्वारा डेटा साझा कर सकते हैं.</string>
+  <string name="msg_share_text">या कुछ पाठ टाइप करें और प्रेस दर्ज करें</string>
+  <string name="msg_sure">तुम्हें यकीन है?</string>
+  <string name="msg_unmount_usb">क्षमा करें, एसडी कार्ड सुलभ नहीं है.</string>
+  <string name="preferences_actions_title">जब एक बारकोड पाया जाता है\u2026</string>
+  <string name="preferences_auto_focus_title">ऑटो फोकस का उपयोग करें</string>
+  <string name="preferences_auto_open_web_title">वेब पृष्ठों को स्वचालित रूप से खोलें</string>
+  <string name="preferences_bulk_mode_summary">स्कैन और कई बारकोड लगातार बचाने के</string>
+  <string name="preferences_bulk_mode_title">थोक स्कैन मोड</string>
+  <string name="preferences_copy_to_clipboard_title">क्लिपबोर्ड पर कॉपी</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">स्थानापन्न: %s = सामग्री, %f = प्रारूप, %t = टाइप</string>
+  <string name="preferences_custom_product_search_title">कस्टम खोज यूआरएल</string>
+  <string name="preferences_decode_1D_industrial_title">1D औद्योगिक</string>
+  <string name="preferences_decode_1D_product_title">1D उत्पाद</string>
+  <string name="preferences_decode_Aztec_title">एज़्टेक</string>
+  <string name="preferences_decode_Data_Matrix_title">डाटा मैट्रिक्स</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR कोड</string>
+  <string name="preferences_device_bug_workarounds_title">युक्ति बग वर्कअराउन्ड</string>
+  <string name="preferences_disable_barcode_scene_mode_title">कोई बारकोड दृश्य विधा</string>
+  <string name="preferences_disable_continuous_focus_summary">केवल मानक फोकस मोड का उपयोग करें</string>
+  <string name="preferences_disable_continuous_focus_title">कोई निरंतर ध्यान</string>
+  <string name="preferences_disable_exposure_title">कोई जोखिम</string>
+  <string name="preferences_disable_metering_title">कोई पैमाइश</string>
+  <string name="preferences_front_light_auto">स्वचालित</string>
+  <string name="preferences_front_light_off">निष्क्रिय</string>
+  <string name="preferences_front_light_on">सक्रिय</string>
+  <string name="preferences_front_light_summary">कुछ फोन पर कम रोशनी में स्कैनिंग बढ़ाता है, लेकिन चमक का कारण हो सकता है. सभी फोन पर काम नहीं करता.</string>
+  <string name="preferences_front_light_title">सामने प्रकाश का उपयोग करें</string>
+  <string name="preferences_general_title">सामान्य सेटिंग्स</string>
+  <string name="preferences_history_summary">इतिहास में अपने स्कैन स्टोर</string>
+  <string name="preferences_history_title">इतिहास में जोड़ें</string>
+  <string name="preferences_invert_scan_summary">काली पृष्ठभूमि पर सफेद बारकोड के लिए स्कैन करें. कुछ उपकरणों पर उपलब्ध नहीं है.</string>
+  <string name="preferences_invert_scan_title">स्कैन उलटें</string>
+  <string name="preferences_name">सेटिंग्स</string>
+  <string name="preferences_orientation_title">कोई स्वचालित रोटेशन</string>
+  <string name="preferences_play_beep_title">भोंपू</string>
+  <string name="preferences_remember_duplicates_summary">इतिहास में एक ही बारकोड के स्टोर एकाधिक स्कैन</string>
+  <string name="preferences_remember_duplicates_title">डुप्लिकेट याद रखें</string>
+  <string name="preferences_result_title">नतीजे सेटिंग्स</string>
+  <string name="preferences_scanning_title">जब बारकोड स्कैनिंग के लिए व्याख्या करना\u2026</string>
+  <string name="preferences_search_country">खोज देश</string>
+  <string name="preferences_supplemental_summary">बारकोड सामग्री के बारे में में अधिक जानकारी पुनः प्राप्त करने की कोशिश करो</string>
+  <string name="preferences_supplemental_title">अधिक जानकारी पुनर्प्राप्त</string>
+  <string name="preferences_vibrate_title">कांपना</string>
+  <string name="result_address_book">मिला संपर्क जानकारी</string>
+  <string name="result_calendar">मिला कैलेंडर घटना</string>
+  <string name="result_email_address">मिला ईमेल पते</string>
+  <string name="result_geo">मिला भौगोलिक निर्देशांक</string>
+  <string name="result_isbn">मिला किताब</string>
+  <string name="result_product">मिला उत्पाद</string>
+  <string name="result_sms">मिला एसएमएस पता</string>
+  <string name="result_tel">मिला फोन नंबर</string>
+  <string name="result_text">मिला सादा पाठ</string>
+  <string name="result_uri">मिला यूआरएल</string>
+  <string name="result_wifi">मिला WLAN विन्यास</string>
+  <string name="sbc_name">Google पुस्तक खोज</string>
+  <string name="wifi_changing_network">नेटवर्क के लिए कनेक्शन का अनुरोध कर रहा है \u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-hu/strings.xml b/BarCodeScanner/mobile/src/main/res/values-hu/strings.xml
new file mode 100644 (file)
index 0000000..e14f9ed
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Alkalmazások</string>
+  <string name="bookmark_picker_name">Könyvjelzők</string>
+  <string name="button_add_calendar">Hozzáadás a naptárhoz</string>
+  <string name="button_add_contact">Névjegy hozzáadása</string>
+  <string name="button_book_search">Könyv keresése</string>
+  <string name="button_cancel">Mégse</string>
+  <string name="button_custom_product_search">Egyedi keresés</string>
+  <string name="button_dial">Telefonszám tárcsázása</string>
+  <string name="button_email">E-mail küldése</string>
+  <string name="button_get_directions">Útvonaltervezés</string>
+  <string name="button_mms">MMS küldése</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Böngésző megnyitása</string>
+  <string name="button_product_search">Termék keresése</string>
+  <string name="button_search_book_contents">Tartalom keresése</string>
+  <string name="button_share_app">Alkalmazás</string>
+  <string name="button_share_bookmark">Könyvjelző</string>
+  <string name="button_share_by_email">Megosztás e-mailben</string>
+  <string name="button_share_by_sms">Megosztás SMS-ben</string>
+  <string name="button_share_clipboard">Vágólap</string>
+  <string name="button_share_contact">Névjegy</string>
+  <string name="button_show_map">Térkép mutatása</string>
+  <string name="button_sms">SMS küldése</string>
+  <string name="button_web_search">Keresés a weben</string>
+  <string name="button_wifi">Kapcsolódás hálózathoz</string>
+  <string name="contents_contact">Névjegy információ</string>
+  <string name="contents_email">E-mail cím</string>
+  <string name="contents_location">Földrajzi koordináták</string>
+  <string name="contents_phone">Telefonszám</string>
+  <string name="contents_sms">SMS szám</string>
+  <string name="contents_text">Egyszerű szöveg</string>
+  <string name="history_clear_one_history_text">Törlése</string>
+  <string name="history_clear_text">Előzmények törlése</string>
+  <string name="history_email_title">Barcode Scanner előzmények</string>
+  <string name="history_empty">Üres</string>
+  <string name="history_empty_detail">Nem vonalkód szkennelés lett felvéve még</string>
+  <string name="history_send">Előzmények küldése</string>
+  <string name="history_title">Előzmények</string>
+  <string name="menu_encode_mecard">Használja MECARD</string>
+  <string name="menu_encode_vcard">Használja vCard</string>
+  <string name="menu_help">Súgó</string>
+  <string name="menu_history">Előzmények</string>
+  <string name="menu_settings">Beállítások</string>
+  <string name="menu_share">Megosztás</string>
+  <string name="msg_bulk_mode_scanned">Tömeges beolvasás: vonalkód beszkennelve és mentve</string>
+  <string name="msg_camera_framework_bug">Android kamera hiba. Lehet, hogy újra kell indítania a készüléket.</string>
+  <string name="msg_default_format">Formátum</string>
+  <string name="msg_default_meta">Metaadatok</string>
+  <string name="msg_default_mms_subject">Szia</string>
+  <string name="msg_default_status">Pozícionálja a vonalkódot a kereső téglalapba a szkenneléshez.</string>
+  <string name="msg_default_time">Idő</string>
+  <string name="msg_default_type">Típus</string>
+  <string name="msg_encode_contents_failed">Nem sikerült létrehozni a vonalkódot a megadott adatokból.</string>
+  <string name="msg_error">Hiba</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">A kért alkalmazást nem lehet elindítani. A vonalkód tartalma lehet, hogy érvénytelen.</string>
+  <string name="msg_invalid_value">Érvénytelen érték</string>
+  <string name="msg_redirect">Átirányítás</string>
+  <string name="msg_sbc_book_not_searchable">Ez a könyv nem kereshető.</string>
+  <string name="msg_sbc_failed">A keresés problémába ütközött.</string>
+  <string name="msg_sbc_no_page_returned">Nincs visszakapott oldal</string>
+  <string name="msg_sbc_page">Oldal</string>
+  <string name="msg_sbc_results">Eredmények</string>
+  <string name="msg_sbc_searching_book">Könyv keresése\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Kódrészlet nem elérhető</string>
+  <string name="msg_share_explanation">Meg tud osztani adatot úgy, hogy egy vonalkódot jelenít meg a képernyőjén, melyet egy másik telefon beszkennel.</string>
+  <string name="msg_share_text">Vagy írja be a szöveget és nyomjon Enter-t</string>
+  <string name="msg_sure">Biztos benne?</string>
+  <string name="msg_unmount_usb">Az SD kártya nem elérhető.</string>
+  <string name="preferences_actions_title">Amikor a vonalkód megvan\u2026</string>
+  <string name="preferences_auto_focus_title">Használja autofókusz</string>
+  <string name="preferences_auto_open_web_title">Nyissa meg a weboldalak automatikusan</string>
+  <string name="preferences_bulk_mode_summary">Több vonalkód folyamatos szkennelése és mentése</string>
+  <string name="preferences_bulk_mode_title">Tömeges beolvasás</string>
+  <string name="preferences_copy_to_clipboard_title">Másolás a vágólapra</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Használjon: %s = tartalom, %f = formátum, %t = típus</string>
+  <string name="preferences_custom_product_search_title">Egyedi kereső URL</string>
+  <string name="preferences_decode_1D_industrial_title">1D ipari</string>
+  <string name="preferences_decode_1D_product_title">1D termék</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR kódok</string>
+  <string name="preferences_device_bug_workarounds_title">Eszköz Bug Lehetséges megoldások</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Nincs vonalkód motívumprogram</string>
+  <string name="preferences_disable_continuous_focus_summary">Csak a normál élességállítási mód</string>
+  <string name="preferences_disable_continuous_focus_title">Nincs folyamatos fókusz</string>
+  <string name="preferences_disable_exposure_title">No expozíció</string>
+  <string name="preferences_disable_metering_title">No mérés</string>
+  <string name="preferences_front_light_auto">Automatikus</string>
+  <string name="preferences_front_light_off">Tétlen</string>
+  <string name="preferences_front_light_on">Aktív</string>
+  <string name="preferences_front_light_summary">Javítja a szkennelést kevés fény mellett néhány telefonon, de csillogást okozhat. Nem minden telefonon működik.</string>
+  <string name="preferences_front_light_title">Kamera LED használata</string>
+  <string name="preferences_general_title">Általános beállítások</string>
+  <string name="preferences_history_summary">Tárolja a beolvasott történelem</string>
+  <string name="preferences_history_title">Add hozzá a History</string>
+  <string name="preferences_invert_scan_summary">Scan fehér vonalkódok a fekete háttér. Nem csak egyes eszközöket.</string>
+  <string name="preferences_invert_scan_title">Invert szkennelés</string>
+  <string name="preferences_name">Beállítások</string>
+  <string name="preferences_orientation_title">Nincs automatikus forgatás</string>
+  <string name="preferences_play_beep_title">Sípolás</string>
+  <string name="preferences_remember_duplicates_summary">Ugyanannak a vonalkódnak több szkennelt képét is tárolja az Előzményekben</string>
+  <string name="preferences_remember_duplicates_title">Duplikációk megjegyzése</string>
+  <string name="preferences_result_title">Találati beállítások</string>
+  <string name="preferences_scanning_title">Vonalkód szkennelésekor, dekódoláskor\u2026</string>
+  <string name="preferences_search_country">Ország keresése</string>
+  <string name="preferences_supplemental_summary">A vonalkóddal jelzett tartalomról megpróbál több információt letölteni.</string>
+  <string name="preferences_supplemental_title">További információk letöltése</string>
+  <string name="preferences_vibrate_title">Rezgés</string>
+  <string name="result_address_book">Névjegy találat</string>
+  <string name="result_calendar">Naptár esemény találat</string>
+  <string name="result_email_address">E-mail cím találat</string>
+  <string name="result_geo">Földrajzi koordináták találat</string>
+  <string name="result_isbn">Könyv találat</string>
+  <string name="result_product">Termék találat</string>
+  <string name="result_sms">SMS szám találat</string>
+  <string name="result_tel">Telefonszám találat</string>
+  <string name="result_text">Egyszerű szöveg találat</string>
+  <string name="result_uri">URL találat</string>
+  <string name="result_wifi">WLAN konfiguráció találat</string>
+  <string name="sbc_name">Google Könyvek keresés</string>
+  <string name="wifi_changing_network">Kérése kapcsolat hálózati\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-id/strings.xml b/BarCodeScanner/mobile/src/main/res/values-id/strings.xml
new file mode 100644 (file)
index 0000000..cdd2f14
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Aplikasi</string>
+  <string name="bookmark_picker_name">Bookmarks</string>
+  <string name="button_add_calendar">Tambah ke kalendar</string>
+  <string name="button_add_contact">Tambah kontak</string>
+  <string name="button_book_search">Cari Buku</string>
+  <string name="button_cancel">Batal</string>
+  <string name="button_custom_product_search">Pencarian kustom</string>
+  <string name="button_dial">Menghubungi nomor</string>
+  <string name="button_email">Kirim email</string>
+  <string name="button_get_directions">Dapatkan petunjuk arah</string>
+  <string name="button_mms">Kirim MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Buka browser</string>
+  <string name="button_product_search">Cari Produk</string>
+  <string name="button_search_book_contents">Cari isi</string>
+  <string name="button_share_app">Aplikasi</string>
+  <string name="button_share_bookmark">Bookmark</string>
+  <string name="button_share_by_email">Bagikan melalui email</string>
+  <string name="button_share_by_sms">Bagikan melalui SMS</string>
+  <string name="button_share_clipboard">Clipboard</string>
+  <string name="button_share_contact">Kontak</string>
+  <string name="button_show_map">Lihat peta</string>
+  <string name="button_sms">Kirim SMS</string>
+  <string name="button_web_search">Pencarian web</string>
+  <string name="button_wifi">Hubungkan ke Jaringan</string>
+  <string name="contents_contact">Informasi kontak</string>
+  <string name="contents_email">Alamat email</string>
+  <string name="contents_location">Koordinat geografis</string>
+  <string name="contents_phone">Nomor telepon</string>
+  <string name="contents_sms">Alamat SMS</string>
+  <string name="contents_text">Teks biasa</string>
+  <string name="history_clear_one_history_text">Hapus</string>
+  <string name="history_clear_text">Hapus riwayat</string>
+  <string name="history_email_title">Riwayat Barcode Scanner</string>
+  <string name="history_empty">Kosong</string>
+  <string name="history_empty_detail">Tidak ada pemindaian barcode yang pernah dicatat</string>
+  <string name="history_send">Kirim riwayat</string>
+  <string name="history_title">Riwayat</string>
+  <string name="menu_encode_mecard">Gunakan MECARD</string>
+  <string name="menu_encode_vcard">Gunakan vCard</string>
+  <string name="menu_help">Bantuan</string>
+  <string name="menu_history">Riwayat</string>
+  <string name="menu_settings">Pengaturan</string>
+  <string name="menu_share">Bagikan</string>
+  <string name="msg_bulk_mode_scanned">Bulk mode: barcode sudah dipindai dan disimpan</string>
+  <string name="msg_camera_framework_bug">Maaf, kamera mengalami masalah. Anda mungkin perlu me-restart perangkat.</string>
+  <string name="msg_default_format">Format</string>
+  <string name="msg_default_meta">Metadata</string>
+  <string name="msg_default_mms_subject">Hai</string>
+  <string name="msg_default_status">Letakkan barcode di dalam kotak jendela untuk memindai.</string>
+  <string name="msg_default_time">Waktu</string>
+  <string name="msg_default_type">Tipe</string>
+  <string name="msg_encode_contents_failed">Tidak dapat meng-encode barcode dari data yang diberikan.</string>
+  <string name="msg_error">Kesalahan</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Maaf, aplikasi yang diminta tidak dapat dijalankan. Mungkin ada kesalahan isi barcode.</string>
+  <string name="msg_invalid_value">Nilai tidak valid</string>
+  <string name="msg_redirect">Pengalihan</string>
+  <string name="msg_sbc_book_not_searchable">Maaf, buku ini tidak dapat dicari.</string>
+  <string name="msg_sbc_failed">Maaf, pencarian mengalami masalah.</string>
+  <string name="msg_sbc_no_page_returned">Tidak ada halaman kembali</string>
+  <string name="msg_sbc_page">Halaman</string>
+  <string name="msg_sbc_results">Hasil</string>
+  <string name="msg_sbc_searching_book">Mencari buku\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Snippet tidak tersedia</string>
+  <string name="msg_share_explanation">Anda dapat berbagi data dengan menampilkan barcode di layar Anda dan dapat dipindai oleh phone lain.</string>
+  <string name="msg_share_text">Atau masukkan beberapa kata dan tekan Enter</string>
+  <string name="msg_sure">Apakah Anda yakin?</string>
+  <string name="msg_unmount_usb">Maaf, SD card tidak dapat diakses.</string>
+  <string name="preferences_actions_title">Ketika barcode sudah ditemukan\u2026</string>
+  <string name="preferences_auto_focus_title">Menggunakan fokus otomatis</string>
+  <string name="preferences_auto_open_web_title">Membuka halaman web secara otomatis</string>
+  <string name="preferences_bulk_mode_summary">Pindai dan simpan beberapa barcode terus-menerus</string>
+  <string name="preferences_bulk_mode_title">Mode pemindaian bulk</string>
+  <string name="preferences_copy_to_clipboard_title">Salin ke clipboard</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Substitusi: %s = isi, %f = format, %t = jenis</string>
+  <string name="preferences_custom_product_search_title">Pencarian URL kustom</string>
+  <string name="preferences_decode_1D_industrial_title">1D Industri</string>
+  <string name="preferences_decode_1D_product_title">1D Produk</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matriks</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR Codes</string>
+  <string name="preferences_device_bug_workarounds_title">Device Bug Workarounds</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Tidak ada modus tempat kejadian barcode</string>
+  <string name="preferences_disable_continuous_focus_summary">Hanya gunakan mode fokus standar</string>
+  <string name="preferences_disable_continuous_focus_title">Jangan gunakan fokus terus menerus</string>
+  <string name="preferences_disable_exposure_title">Tanpa eksposur</string>
+  <string name="preferences_disable_metering_title">Tanpa pengukuran</string>
+  <string name="preferences_front_light_auto">Otomatis</string>
+  <string name="preferences_front_light_off">Non-aktif</string>
+  <string name="preferences_front_light_on">Aktif</string>
+  <string name="preferences_front_light_summary">Meningkatkan pemindaian dalam cahaya rendah pada beberapa ponsel, namun dapat menyebabkan silau. Tidak dapat bekerja pada semua ponsel.</string>
+  <string name="preferences_front_light_title">Gunakan lampu depan</string>
+  <string name="preferences_general_title">Pengaturan umum</string>
+  <string name="preferences_history_summary">Simpan hasil pemindaian Anda dalam riwayat</string>
+  <string name="preferences_history_title">Tambahkan ke riwayat</string>
+  <string name="preferences_invert_scan_summary">Memindai barcode putih pada latar belakang hitam. Tidak tersedia pada beberapa perangkat.</string>
+  <string name="preferences_invert_scan_title">Membalikkan pemindaian</string>
+  <string name="preferences_name">Pengaturan</string>
+  <string name="preferences_orientation_title">Jangan rotasi otomatis</string>
+  <string name="preferences_play_beep_title">Bunyi</string>
+  <string name="preferences_remember_duplicates_summary">Simpan beberapa pindaian dari barcode yang sama di dalam Riwayat</string>
+  <string name="preferences_remember_duplicates_title">Ingat duplikasi</string>
+  <string name="preferences_result_title">Hasil pengaturan</string>
+  <string name="preferences_scanning_title">Ketika memindai barcode, decode\u2026</string>
+  <string name="preferences_search_country">Pilih negara</string>
+  <string name="preferences_supplemental_summary">Mencoba mendapatkan beberapa informasi mengenai isi barcode</string>
+  <string name="preferences_supplemental_title">Ambil informasi lebih lanjut</string>
+  <string name="preferences_vibrate_title">Bergetar</string>
+  <string name="result_address_book">Informasi kontak ditemukan</string>
+  <string name="result_calendar">Kalendar acara ditemukan</string>
+  <string name="result_email_address">Alamat email ditemukan</string>
+  <string name="result_geo">Koordinat geografis ditemukan</string>
+  <string name="result_isbn">Buku ditemukan</string>
+  <string name="result_product">Produk ditemukan</string>
+  <string name="result_sms">Alamat SMS ditemukan</string>
+  <string name="result_tel">Nomor telepon ditemukan</string>
+  <string name="result_text">Teks ditemukan</string>
+  <string name="result_uri">URL ditemukan</string>
+  <string name="result_wifi">Konfigurasi WLAN ditemukan</string>
+  <string name="sbc_name">Pencarian Google Book</string>
+  <string name="wifi_changing_network">Meminta koneksi ke jaringan\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-it/strings.xml b/BarCodeScanner/mobile/src/main/res/values-it/strings.xml
new file mode 100644 (file)
index 0000000..6bbb696
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Applicazioni</string>
+  <string name="bookmark_picker_name">Segnalibri</string>
+  <string name="button_add_calendar">Aggiungi al calendario</string>
+  <string name="button_add_contact">Aggiungi ai contatti</string>
+  <string name="button_book_search">Cerca libro</string>
+  <string name="button_cancel">Annulla</string>
+  <string name="button_custom_product_search">Ricerca personalizzata</string>
+  <string name="button_dial">Componi numero</string>
+  <string name="button_email">Invia email</string>
+  <string name="button_get_directions">Ottieni indirizzi</string>
+  <string name="button_mms">Invia MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Apri browser</string>
+  <string name="button_product_search">Cerca prodotto</string>
+  <string name="button_search_book_contents">Cerca contenuti</string>
+  <string name="button_share_app">Applicazione</string>
+  <string name="button_share_bookmark">Segnalibro</string>
+  <string name="button_share_by_email">Condividi tramite email</string>
+  <string name="button_share_by_sms">Condividi tramite SMS</string>
+  <string name="button_share_clipboard">Appunti</string>
+  <string name="button_share_contact">Contatti</string>
+  <string name="button_show_map">Mostra mappa</string>
+  <string name="button_sms">Invia SMS</string>
+  <string name="button_web_search">Ricerca web</string>
+  <string name="button_wifi">Connessione a rete</string>
+  <string name="contents_contact">Info contatto</string>
+  <string name="contents_email">Indirizzo email</string>
+  <string name="contents_location">Coordinate geografiche</string>
+  <string name="contents_phone">Numero di telefono</string>
+  <string name="contents_sms">Numero SMS</string>
+  <string name="contents_text">Testo puro</string>
+  <string name="history_clear_one_history_text">Cancella</string>
+  <string name="history_clear_text">Cancella cronologia</string>
+  <string name="history_email_title">Cronologia scansioni codici a barre</string>
+  <string name="history_empty">Vuoto</string>
+  <string name="history_empty_detail">Nessuna scansione di codici a barre è stata registrata</string>
+  <string name="history_send">Invia cronologia</string>
+  <string name="history_title">Cronologia</string>
+  <string name="menu_encode_mecard">Usa MECARD</string>
+  <string name="menu_encode_vcard">Usa vCard</string>
+  <string name="menu_help">Aiuto</string>
+  <string name="menu_history">Cronologia</string>
+  <string name="menu_settings">Impostazioni</string>
+  <string name="menu_share">Condividi</string>
+  <string name="msg_bulk_mode_scanned">Modalità di gruppo: codici a barre scansionati e salvati</string>
+  <string name="msg_camera_framework_bug">Spiacenti, la fotocamera Android ha riscontrato un problema. Potrebbe essere necessario riavviare il dispositivo.</string>
+  <string name="msg_default_format">Formato</string>
+  <string name="msg_default_meta">Metadati</string>
+  <string name="msg_default_mms_subject">Ciao</string>
+  <string name="msg_default_status">Posiziona un codice a barre dentro il mirino rettangolare per la scansione.</string>
+  <string name="msg_default_time">Tempo</string>
+  <string name="msg_default_type">Tipo</string>
+  <string name="msg_encode_contents_failed">Impossibile codificare un codice a barre dai dati forniti.</string>
+  <string name="msg_error">Errore</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Spiacenti, l\'applicazione richiesta non può essere avviata. Il contenuto del codice a barre può essere non valido.</string>
+  <string name="msg_invalid_value">Valore non valido</string>
+  <string name="msg_redirect">Inoltra</string>
+  <string name="msg_sbc_book_not_searchable">Spiacenti, questo libro non è ricercabile.</string>
+  <string name="msg_sbc_failed">Spiacenti, la ricerca ha avuto un problema.</string>
+  <string name="msg_sbc_no_page_returned">Nessuna pagina restitiuta</string>
+  <string name="msg_sbc_page">Pagina</string>
+  <string name="msg_sbc_results">Risultati</string>
+  <string name="msg_sbc_searching_book">Ricerca libro\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Ritaglio non disponibile</string>
+  <string name="msg_share_explanation">Puoi condividere i dati mostrando un codice a barre sullo schermo e facendo la scansione con un altro telefono.</string>
+  <string name="msg_share_text">O digitare un testo</string>
+  <string name="msg_sure">Sei sicuro?</string>
+  <string name="msg_unmount_usb">Spiacenti, la scheda SD non è accessibile.</string>
+  <string name="preferences_actions_title">Quando viene trovato un codice a barre\u2026</string>
+  <string name="preferences_auto_focus_title">Utilizzare messa a fuoco automatica</string>
+  <string name="preferences_auto_open_web_title">Aprire le pagine web automaticamente</string>
+  <string name="preferences_bulk_mode_summary">Scansiona e salva diversi codici a barre in sequenza</string>
+  <string name="preferences_bulk_mode_title">Modalità scansione di gruppo</string>
+  <string name="preferences_copy_to_clipboard_title">Copia negli appunti</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Sostituzioni: %s = contenuti, %f = formato, %t = tipo</string>
+  <string name="preferences_custom_product_search_title">URL ricerca personalizzata</string>
+  <string name="preferences_decode_1D_industrial_title">1D industriali</string>
+  <string name="preferences_decode_1D_product_title">1D prodotto</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Matrice Dati</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">Codici QR</string>
+  <string name="preferences_device_bug_workarounds_title">Soluzioni alternative dispositivo Bug</string>
+  <string name="preferences_disable_barcode_scene_mode_title">No modalità scena codice a barre</string>
+  <string name="preferences_disable_continuous_focus_summary">Utilizzare solo modalità standard messa a fuoco</string>
+  <string name="preferences_disable_continuous_focus_title">No messa a fuoco continua</string>
+  <string name="preferences_disable_exposure_title">Nessuna esposizione</string>
+  <string name="preferences_disable_metering_title">Nessuna misurazione</string>
+  <string name="preferences_front_light_auto">Automatico</string>
+  <string name="preferences_front_light_off">Inattivo</string>
+  <string name="preferences_front_light_on">Attivo</string>
+  <string name="preferences_front_light_summary">Migliora la scansione con poca luminosità su alcuni telefoni, ma può provocare abbagliamento. Non funziona su tutti i telefoni.</string>
+  <string name="preferences_front_light_title">Usa luce frontale</string>
+  <string name="preferences_general_title">Impostazioni generali</string>
+  <string name="preferences_history_summary">Mantieni le tue scansioni nella Cronologia</string>
+  <string name="preferences_history_title">Aggiungi alla Cronologia</string>
+  <string name="preferences_invert_scan_summary">Scansione dei codici a barre bianche su sfondo nero. Non disponibile su alcuni dispositivi.</string>
+  <string name="preferences_invert_scan_title">Invertire la scansione</string>
+  <string name="preferences_name">Impostazioni</string>
+  <string name="preferences_orientation_title">Nessuna rotazione automatica</string>
+  <string name="preferences_play_beep_title">Suona</string>
+  <string name="preferences_remember_duplicates_summary">Mantieni scansioni multiple del codice a barre nella stessa Cronologia</string>
+  <string name="preferences_remember_duplicates_title">Ricorda duplicati</string>
+  <string name="preferences_result_title">Impostazioni risultato</string>
+  <string name="preferences_scanning_title">Durante la scansione di codici a barre, decodifica\u2026</string>
+  <string name="preferences_search_country">Cerca paese</string>
+  <string name="preferences_supplemental_summary">Prova a cercare ulteriori informazioni sul contenuto del codice a barre</string>
+  <string name="preferences_supplemental_title">Recupera altre informazioni</string>
+  <string name="preferences_vibrate_title">Vibra</string>
+  <string name="result_address_book">Info contatto trovata</string>
+  <string name="result_calendar">Evento calendario trovato</string>
+  <string name="result_email_address">Indirizzo email trovato</string>
+  <string name="result_geo">Coordinate geografiche trovate</string>
+  <string name="result_isbn">Libro trovato</string>
+  <string name="result_product">Prodotto trovato</string>
+  <string name="result_sms">Numero SMS trovato</string>
+  <string name="result_tel">Numero di telefono trovato</string>
+  <string name="result_text">Testo puro trovato</string>
+  <string name="result_uri">URL trovato</string>
+  <string name="result_wifi">Configurazione WLAN trovata</string>
+  <string name="sbc_name">Ricerca Google Book</string>
+  <string name="wifi_changing_network">Richiesta di connessione alla rete\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-iw/strings.xml b/BarCodeScanner/mobile/src/main/res/values-iw/strings.xml
new file mode 100644 (file)
index 0000000..07a8dc1
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">סורק ברקודים</string>
+  <string name="app_picker_name">יישומים</string>
+  <string name="bookmark_picker_name">סימניות</string>
+  <string name="button_add_calendar">הוסף ללוח שנה</string>
+  <string name="button_add_contact">הוספת איש קשר</string>
+  <string name="button_book_search">חיפוש ספר</string>
+  <string name="button_cancel">ביטול</string>
+  <string name="button_custom_product_search">חיפוש מותאם אישית</string>
+  <string name="button_dial">חייג מספר</string>
+  <string name="button_email">שלח דואר אלקטרוני</string>
+  <string name="button_get_directions">קבל הוראות הגעה</string>
+  <string name="button_mms">שלח הודעת מולטימדיה</string>
+  <string name="button_ok">אישור</string>
+  <string name="button_open_browser">פתח את הדפדפן</string>
+  <string name="button_product_search">חיפוש מוצר</string>
+  <string name="button_search_book_contents">חיפוש בתוכן</string>
+  <string name="button_share_app">יישום</string>
+  <string name="button_share_bookmark">סימניה</string>
+  <string name="button_share_by_email">שתף בדואר אלקטרוני</string>
+  <string name="button_share_by_sms">שתף בהודעה</string>
+  <string name="button_share_clipboard">לוח עריכה</string>
+  <string name="button_share_contact">איש קשר</string>
+  <string name="button_show_map">הצג מפה</string>
+  <string name="button_sms">שלח הודעה</string>
+  <string name="button_web_search">חיפוש באינטרנט</string>
+  <string name="button_wifi">התחבר לרשת</string>
+  <string name="contents_contact">פרטי איש קשר</string>
+  <string name="contents_email">כתובת דואר אלקטרוני</string>
+  <string name="contents_location">קואורדינטות גאוגרפיות</string>
+  <string name="contents_phone">מספר טלפון</string>
+  <string name="contents_sms">כתובת SMS</string>
+  <string name="contents_text">טקסט רגיל</string>
+  <string name="history_clear_one_history_text">נקה</string>
+  <string name="history_clear_text">נקה היסטוריה</string>
+  <string name="history_email_title">היסטוריית סורק הברקודים</string>
+  <string name="history_empty">ריק</string>
+  <string name="history_empty_detail">ברקודים לא נרשמו</string>
+  <string name="history_send">שלח היסטוריה</string>
+  <string name="history_title">היסטוריה</string>
+  <string name="menu_encode_mecard">השתמש MECARD</string>
+  <string name="menu_encode_vcard">השתמש vCard</string>
+  <string name="menu_help">עזרה</string>
+  <string name="menu_history">היסטוריה</string>
+  <string name="menu_settings">הגדרות</string>
+  <string name="menu_share">שתף</string>
+  <string name="msg_bulk_mode_scanned">מצב קבוצה: ברקוד נסרק ונשמר</string>
+  <string name="msg_camera_framework_bug">סליחה, מצלמת האנדרואיד נתקלה בבעיה. ייתכן שיהיה עליך להפעיל מחדש את המכשיר.</string>
+  <string name="msg_default_format">פורמט</string>
+  <string name="msg_default_meta">מטה-נתונים</string>
+  <string name="msg_default_mms_subject">היי</string>
+  <string name="msg_default_status">הצב ברקוד בתוך המלבן כדי לסרוק אותו.</string>
+  <string name="msg_default_time">זמן</string>
+  <string name="msg_default_type">סוג</string>
+  <string name="msg_encode_contents_failed">לא היתה אפשרות לקודד ברקוד מהנתונים שסופקו.</string>
+  <string name="msg_error">שגיאה</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">סליחה, לא ניתן להפעיל את היישום המבוקש. ייתכן שתוכן הברקוד לא תקין.</string>
+  <string name="msg_invalid_value">ערך לא חוקי</string>
+  <string name="msg_redirect">נתב מחדש</string>
+  <string name="msg_sbc_book_not_searchable">סליחה, ספר זה אינו ניתן לחיפוש.</string>
+  <string name="msg_sbc_failed">סליחה, החיפוש נתקל בבעיה.</string>
+  <string name="msg_sbc_no_page_returned">לא הוחזר דף</string>
+  <string name="msg_sbc_page">דף</string>
+  <string name="msg_sbc_results">תוצאות</string>
+  <string name="msg_sbc_searching_book">מחפש ספר\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">גזיר לא זמין</string>
+  <string name="msg_share_explanation">באפשרותך לשתף נתונים על-ידי הצגת ברקוד על המסך וסריקתו עם טלפון אחר.</string>
+  <string name="msg_share_text">או הקלד טקסט כלשהו</string>
+  <string name="msg_sure">האם אתה בטוח?</string>
+  <string name="msg_unmount_usb">סליחה, כרטיס הזכרון אינו נגיש.</string>
+  <string name="preferences_actions_title">כאשר ברקוד נמצא\u2026</string>
+  <string name="preferences_auto_focus_title">להשתמש במיקוד האוטומטי</string>
+  <string name="preferences_auto_open_web_title">לפתוח דפי אינטרנט באופן אוטומטי</string>
+  <string name="preferences_bulk_mode_summary">סורק ושומר ברקודים באופן רציף</string>
+  <string name="preferences_bulk_mode_title">מצב סריקה מרובה</string>
+  <string name="preferences_copy_to_clipboard_title">העתק ללוח</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">החלפות: s% = התוכן, f% = הפורמט, t% = סוג</string>
+  <string name="preferences_custom_product_search_title">כתובת לחיפוש מותאם אישית</string>
+  <string name="preferences_decode_1D_industrial_title">1D תעשייתי</string>
+  <string name="preferences_decode_1D_product_title">1D מוצר</string>
+  <string name="preferences_decode_Aztec_title">האצטקים</string>
+  <string name="preferences_decode_Data_Matrix_title">מטריצת נתונים</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">קודי QR</string>
+  <string name="preferences_device_bug_workarounds_title">באג במכשיר דרכים לעקיפת הבעיה</string>
+  <string name="preferences_disable_barcode_scene_mode_title">אין מצב סצנה ברקוד</string>
+  <string name="preferences_disable_continuous_focus_summary">השתמש רק במצב רגיל פוקוס</string>
+  <string name="preferences_disable_continuous_focus_title">המיקוד לא רציפה</string>
+  <string name="preferences_disable_exposure_title">אין חשיפה</string>
+  <string name="preferences_disable_metering_title">אין מדידה</string>
+  <string name="preferences_front_light_auto">אוטומטי</string>
+  <string name="preferences_front_light_off">לא פעיל</string>
+  <string name="preferences_front_light_on">פעיל</string>
+  <string name="preferences_front_light_summary">משפר את הסריקה בתאורה נמוכה בטלפונים מסוימים, אך עשוי לגרום לסנוור. לא עובד בכל הטלפונים.</string>
+  <string name="preferences_front_light_title">השתמש באור הקדמי</string>
+  <string name="preferences_general_title">הגדרות כלליות</string>
+  <string name="preferences_history_summary">אחסן הסריקות שלך בהיסטוריה</string>
+  <string name="preferences_history_title">הוסף להיסטוריה</string>
+  <string name="preferences_invert_scan_summary">סרוק ברקודים לבן על רקע שחור. לא זמין על התקנים מסוימים.</string>
+  <string name="preferences_invert_scan_title">היפוך לסרוק</string>
+  <string name="preferences_name">הגדרות</string>
+  <string name="preferences_orientation_title">סיבוב לא אוטומטי</string>
+  <string name="preferences_play_beep_title">צפצוף</string>
+  <string name="preferences_remember_duplicates_summary">אחסן מספר סריקות של אותו הברקוד בהיסטוריה</string>
+  <string name="preferences_remember_duplicates_title">זכור כפילויות</string>
+  <string name="preferences_result_title">הגדרות תוצאה</string>
+  <string name="preferences_scanning_title">בעת סריקת ברקודים, קודד\u2026</string>
+  <string name="preferences_search_country">חיפוש הארץ</string>
+  <string name="preferences_supplemental_summary">נסה למצא מידע נוסף על תוכן הברקוד</string>
+  <string name="preferences_supplemental_title">מצא מידע נוסף</string>
+  <string name="preferences_vibrate_title">רטט</string>
+  <string name="result_address_book">נמצא מידע של איש קשר</string>
+  <string name="result_calendar">נמצא אירוע</string>
+  <string name="result_email_address">נמצאה כתובת דוא"ל</string>
+  <string name="result_geo">נמצאו קואורדינטות גיאוגרפיות</string>
+  <string name="result_isbn">נמצא ספר</string>
+  <string name="result_product">נמצא מוצר</string>
+  <string name="result_sms">נמצאה כתובת הודעה</string>
+  <string name="result_tel">נמצא מספר טלפון</string>
+  <string name="result_text">נמצא טקסט</string>
+  <string name="result_uri">נמצאה כתובת אינטרנט</string>
+  <string name="result_wifi">נמצאו הגדרות רשת אל חוטית</string>
+  <string name="sbc_name">Google חיפוש ספרים</string>
+  <string name="wifi_changing_network">בקשת חיבור לרשת \u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-ja/strings.xml b/BarCodeScanner/mobile/src/main/res/values-ja/strings.xml
new file mode 100644 (file)
index 0000000..173a9bb
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">QRコードスキャナー</string>
+  <string name="app_picker_name">アプリケーション</string>
+  <string name="bookmark_picker_name">ブックマーク</string>
+  <string name="button_add_calendar">予定を追加</string>
+  <string name="button_add_contact">連絡先を追加</string>
+  <string name="button_book_search">書籍を検索</string>
+  <string name="button_cancel">キャンセル</string>
+  <string name="button_custom_product_search">カスタムサーチ</string>
+  <string name="button_dial">電話をかける</string>
+  <string name="button_email">メールの送信</string>
+  <string name="button_get_directions">経路を検索</string>
+  <string name="button_mms">MMSの送信</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">ブラウザで表示</string>
+  <string name="button_product_search">商品検索</string>
+  <string name="button_search_book_contents">書籍の中身を検索</string>
+  <string name="button_share_app">アプリを共有</string>
+  <string name="button_share_bookmark">ブックマーク</string>
+  <string name="button_share_by_email">メールで共有</string>
+  <string name="button_share_by_sms">SMSで共有</string>
+  <string name="button_share_clipboard">クリップボードを共有</string>
+  <string name="button_share_contact">連絡先を共有</string>
+  <string name="button_show_map">地図を表示</string>
+  <string name="button_sms">SMSの送信</string>
+  <string name="button_web_search">インターネット検索</string>
+  <string name="button_wifi">ネットワークに接続</string>
+  <string name="contents_contact">連絡先</string>
+  <string name="contents_email">メールアドレス</string>
+  <string name="contents_location">位置情報</string>
+  <string name="contents_phone">電話番号</string>
+  <string name="contents_sms">SMSアドレス</string>
+  <string name="contents_text">テキストデータ</string>
+  <string name="history_clear_one_history_text">削除</string>
+  <string name="history_clear_text">履歴の削除</string>
+  <string name="history_email_title">QRコードスキャナーの履歴</string>
+  <string name="history_empty">履歴なし</string>
+  <string name="history_empty_detail">スキャン履歴がありません</string>
+  <string name="history_send">履歴を送信</string>
+  <string name="history_title">履歴</string>
+  <string name="menu_encode_mecard">MECARDを使用</string>
+  <string name="menu_encode_vcard">vCardを使用</string>
+  <string name="menu_help">ヘルプ</string>
+  <string name="menu_history">履歴</string>
+  <string name="menu_settings">設定</string>
+  <string name="menu_share">共有</string>
+  <string name="msg_bulk_mode_scanned">連続スキャン:スキャン結果を保存しました</string>
+  <string name="msg_camera_framework_bug">Androidのカメラに問題が発生しました。デバイスを再起動する必要があります。</string>
+  <string name="msg_default_format">フォーマット</string>
+  <string name="msg_default_meta">メタデータ</string>
+  <string name="msg_default_mms_subject">こんにちは</string>
+  <string name="msg_default_status">QRコードを画面の読み取り範囲内に写すとスキャンします。</string>
+  <string name="msg_default_time">時間</string>
+  <string name="msg_default_type">タイプ</string>
+  <string name="msg_encode_contents_failed">このデータからQRコードを作成できませんでした</string>
+  <string name="msg_error">エラー</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">指定されたアプリケーションを起動できませんでした。QRコードの内容が無効である可能性があります。</string>
+  <string name="msg_invalid_value">無効値</string>
+  <string name="msg_redirect">リダイレクト</string>
+  <string name="msg_sbc_book_not_searchable">この書籍は検索できません</string>
+  <string name="msg_sbc_failed">検索中に問題が発生しました</string>
+  <string name="msg_sbc_no_page_returned">検索結果はありません</string>
+  <string name="msg_sbc_page">ページ</string>
+  <string name="msg_sbc_results">結果</string>
+  <string name="msg_sbc_searching_book">書籍を検索中</string>
+  <string name="msg_sbc_snippet_unavailable">要約文はありません</string>
+  <string name="msg_share_explanation">画面にQRコードを表示させて別の端末でスキャンすれば、データを共有することができます。</string>
+  <string name="msg_share_text">またはテキストを入力してください</string>
+  <string name="msg_sure">よろしいですか?</string>
+  <string name="msg_unmount_usb">SDカードにアクセスできません</string>
+  <string name="preferences_actions_title">スキャン時の動作</string>
+  <string name="preferences_auto_focus_title">オートフォーカスを使用</string>
+  <string name="preferences_auto_open_web_title">自動的にWebを開く</string>
+  <string name="preferences_bulk_mode_summary">QRコードを連続スキャンして保存します</string>
+  <string name="preferences_bulk_mode_title">連続スキャンモード</string>
+  <string name="preferences_copy_to_clipboard_title">クリップボードにコピー</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">引数:%s=コンテンツ、%f=フォーマット、%t=タイプ</string>
+  <string name="preferences_custom_product_search_title">カスタムサーチ URL</string>
+  <string name="preferences_decode_1D_industrial_title">1次元バーコード(産業用)</string>
+  <string name="preferences_decode_1D_product_title">1次元バーコード(商品用)</string>
+  <string name="preferences_decode_Aztec_title">Aztec Code</string>
+  <string name="preferences_decode_Data_Matrix_title">データマトリクスコード</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QRコード</string>
+  <string name="preferences_device_bug_workarounds_title">不具合対策</string>
+  <string name="preferences_disable_barcode_scene_mode_title">バーコードシーン自動認識をOFF</string>
+  <string name="preferences_disable_continuous_focus_summary">標準フォーカスモードのみ使用します</string>
+  <string name="preferences_disable_continuous_focus_title">追従フォーカスしない</string>
+  <string name="preferences_disable_exposure_title">露出しない</string>
+  <string name="preferences_disable_metering_title">測光しない</string>
+  <string name="preferences_front_light_auto">自動</string>
+  <string name="preferences_front_light_off">ライトOFF</string>
+  <string name="preferences_front_light_on">ライトON</string>
+  <string name="preferences_front_light_summary">スキャン時のライトを制御します</string>
+  <string name="preferences_front_light_title">ライトの制御</string>
+  <string name="preferences_general_title">一般設定</string>
+  <string name="preferences_history_summary">歴史の中のあなたのスキャンを保管してください</string>
+  <string name="preferences_history_title">歴史に追加</string>
+  <string name="preferences_invert_scan_summary">黒地に白のバーコードをスキャン。一部のデバイスでは使用できません。</string>
+  <string name="preferences_invert_scan_title">スキャンを反転</string>
+  <string name="preferences_name">設定</string>
+  <string name="preferences_orientation_title">自動回転しない</string>
+  <string name="preferences_play_beep_title">通知音</string>
+  <string name="preferences_remember_duplicates_summary">同じ内容でも重複して履歴に記録します</string>
+  <string name="preferences_remember_duplicates_title">重複するスキャン結果の記録</string>
+  <string name="preferences_result_title">検索結果の設定</string>
+  <string name="preferences_scanning_title">QRコードスキャン時</string>
+  <string name="preferences_search_country">検索国コード</string>
+  <string name="preferences_supplemental_summary">QRコード内容の詳細情報を取得します</string>
+  <string name="preferences_supplemental_title">詳細情報を取得</string>
+  <string name="preferences_vibrate_title">バイブレーション</string>
+  <string name="result_address_book">連絡先がヒットしました</string>
+  <string name="result_calendar">カレンダーの予定がヒットしました</string>
+  <string name="result_email_address">メールアドレスがヒットしました</string>
+  <string name="result_geo">地理座標がヒットしました</string>
+  <string name="result_isbn">書籍がヒットしました</string>
+  <string name="result_product">商品がヒットしました</string>
+  <string name="result_sms">SMS 連絡先がヒットしました</string>
+  <string name="result_tel">電話番号がヒットしました</string>
+  <string name="result_text">テキストデータがヒットしました</string>
+  <string name="result_uri">URL がヒットしました</string>
+  <string name="result_wifi">ネットワーク設定がヒットしました</string>
+  <string name="sbc_name">Googleブックス</string>
+  <string name="wifi_changing_network">ネットワークへ接続しています…</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-ko/strings.xml b/BarCodeScanner/mobile/src/main/res/values-ko/strings.xml
new file mode 100644 (file)
index 0000000..29e43ba
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">바코드 스캐너</string>
+  <string name="app_picker_name">어플리케이션</string>
+  <string name="bookmark_picker_name">즐겨찾기</string>
+  <string name="button_add_calendar">일정에 추가하기</string>
+  <string name="button_add_contact">연락처에 추가하기</string>
+  <string name="button_book_search">책 검색</string>
+  <string name="button_cancel">취소</string>
+  <string name="button_custom_product_search">사용자 지정 검색</string>
+  <string name="button_dial">전화 걸기</string>
+  <string name="button_email">이메일 보내기</string>
+  <string name="button_get_directions">방향을 찾기</string>
+  <string name="button_mms">MMS 보내기</string>
+  <string name="button_ok">확인</string>
+  <string name="button_open_browser">웹브라우저로 열기</string>
+  <string name="button_product_search">제품 검색</string>
+  <string name="button_search_book_contents">책 내용 검색</string>
+  <string name="button_share_app">어플리케이션</string>
+  <string name="button_share_bookmark">즐겨찾기</string>
+  <string name="button_share_by_email">이메일로 공유</string>
+  <string name="button_share_by_sms">SMS로 공유</string>
+  <string name="button_share_clipboard">복사된 항목</string>
+  <string name="button_share_contact">연락처</string>
+  <string name="button_show_map">지도 보기</string>
+  <string name="button_sms">SMS 보내기</string>
+  <string name="button_web_search">인터넷 검색</string>
+  <string name="button_wifi">네트워크에 연결</string>
+  <string name="contents_contact">연락처 정보</string>
+  <string name="contents_email">이메일 주소</string>
+  <string name="contents_location">GPS 좌표</string>
+  <string name="contents_phone">전화번호</string>
+  <string name="contents_sms">전화번호</string>
+  <string name="contents_text">단문</string>
+  <string name="history_clear_one_history_text">삭제</string>
+  <string name="history_clear_text">기록 삭제</string>
+  <string name="history_email_title">바코드 스캐너 기록</string>
+  <string name="history_empty">빈</string>
+  <string name="history_empty_detail">아무 바코드 스캔이 기록되지 않았습니다</string>
+  <string name="history_send">기록 보내기</string>
+  <string name="history_title">기록</string>
+  <string name="menu_encode_mecard">MECARD를 사용하여</string>
+  <string name="menu_encode_vcard">vCard를 사용하여</string>
+  <string name="menu_help">도움말</string>
+  <string name="menu_history">기록</string>
+  <string name="menu_settings">설정</string>
+  <string name="menu_share">공유</string>
+  <string name="msg_bulk_mode_scanned">일괄 스캔 모드: 바코드가 읽히고 저장됩니다.</string>
+  <string name="msg_camera_framework_bug">죄송합니다. 기기의 카메라에 오류가 생겼습니다. 기기를 재시작 해야될 수도 있습니다.</string>
+  <string name="msg_default_format">포맷</string>
+  <string name="msg_default_meta">메타데이터</string>
+  <string name="msg_default_mms_subject">안녕하세요</string>
+  <string name="msg_default_status">바코드를 사각형 안에 비춰주세요.</string>
+  <string name="msg_default_time">시간</string>
+  <string name="msg_default_type">종류</string>
+  <string name="msg_encode_contents_failed">주어진 데이터로 바코드를 만들지 못하였습니다.</string>
+  <string name="msg_error">오류</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">죄송합니다. 어플리케이션이 실행되지 않습니다. 바코드 내용이 잘못 되었을 수도 있습니다.</string>
+  <string name="msg_invalid_value">값이 잘못되었습니다</string>
+  <string name="msg_redirect">리디렉션</string>
+  <string name="msg_sbc_book_not_searchable">죄송합니다. 이 책은 검색이 되지 않습니다.</string>
+  <string name="msg_sbc_failed">죄송합니다. 검색 도중 문제가 발생했습니다.</string>
+  <string name="msg_sbc_no_page_returned">수신받은 페이지가 없습니다.</string>
+  <string name="msg_sbc_page">페이지</string>
+  <string name="msg_sbc_results">결과</string>
+  <string name="msg_sbc_searching_book">책 검색중\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">내용이 열람되지 않습니다.</string>
+  <string name="msg_share_explanation">해당 기기의 바코드를 다른 기기로 스캔해서 데이터를 공유할 수 있습니다.</string>
+  <string name="msg_share_text">입력하거나 텍스트</string>
+  <string name="msg_sure">계속하시겠습니까?</string>
+  <string name="msg_unmount_usb">죄송합니다. SD카드를 사용할 수 없습니다.</string>
+  <string name="preferences_actions_title">바코드를 스캔했을때\u2026</string>
+  <string name="preferences_auto_focus_title">자동 초점을 사용하여</string>
+  <string name="preferences_auto_open_web_title">자동으로 웹 페이지를 엽니 다</string>
+  <string name="preferences_bulk_mode_summary">다수의 바코드를 스캔하고 저장합니다.</string>
+  <string name="preferences_bulk_mode_title">일괄 스캔 모드</string>
+  <string name="preferences_copy_to_clipboard_title">복사하기</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">자리 표시자: %s = 내용, %f = 포맷, %t = 유형</string>
+  <string name="preferences_custom_product_search_title">사용자 지정 검색 주소</string>
+  <string name="preferences_decode_1D_industrial_title">1D 산업</string>
+  <string name="preferences_decode_1D_product_title">1D 제품</string>
+  <string name="preferences_decode_Aztec_title">아즈텍</string>
+  <string name="preferences_decode_Data_Matrix_title">데이터 행렬(Data Matrix)을 해석하기</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR 코드를 읽기</string>
+  <string name="preferences_device_bug_workarounds_title">장치 버그 해결</string>
+  <string name="preferences_disable_barcode_scene_mode_title">어떤 바코드 장면 모드 없음</string>
+  <string name="preferences_disable_continuous_focus_summary">전용 표준 초점 모드를 사용</string>
+  <string name="preferences_disable_continuous_focus_title">아무 연속 초점 없음</string>
+  <string name="preferences_disable_exposure_title">더 노출하지</string>
+  <string name="preferences_disable_metering_title">더 측광 없습니다</string>
+  <string name="preferences_front_light_auto">자동적 인</string>
+  <string name="preferences_front_light_off">비활성</string>
+  <string name="preferences_front_light_on">활동적인</string>
+  <string name="preferences_front_light_summary">특정 기기에서는 어두운 환경에서의 스캐닝 기능을 향상 시키지만 너무 밝을 수도 있습니다. 모든 기기에서 작동되지 않습니다.</string>
+  <string name="preferences_front_light_title">플래시 사용하기</string>
+  <string name="preferences_general_title">일반 설정</string>
+  <string name="preferences_history_summary">역사에서 스캔을 저장</string>
+  <string name="preferences_history_title">역사에 추가</string>
+  <string name="preferences_invert_scan_summary">검정 바탕에 흰색 바코드에 대한 스캔. 일부 장치에서 사용할 수 없습니다.</string>
+  <string name="preferences_invert_scan_title">스캔 반전</string>
+  <string name="preferences_name">설정</string>
+  <string name="preferences_orientation_title">아무도 자동 회전 없습니다</string>
+  <string name="preferences_play_beep_title">전자음</string>
+  <string name="preferences_remember_duplicates_summary">복수의 같은 바코드를 기록에 저장</string>
+  <string name="preferences_remember_duplicates_title">중복된 바코드 저장</string>
+  <string name="preferences_result_title">결과 설정</string>
+  <string name="preferences_scanning_title">바코드 스캐닝 시\u2026</string>
+  <string name="preferences_search_country">국가별 검색</string>
+  <string name="preferences_supplemental_summary">바코드 내용에 대한 자세한 정보를 검색하려고</string>
+  <string name="preferences_supplemental_title">검색 상세 정보</string>
+  <string name="preferences_vibrate_title">진동</string>
+  <string name="result_address_book">연락처 정보를 찾았습니다</string>
+  <string name="result_calendar">일정 이벤트를 찾았습니다</string>
+  <string name="result_email_address">이메일 주소를 찾았습니다</string>
+  <string name="result_geo">GPS 좌표를 찾았습니다</string>
+  <string name="result_isbn">책을 찾았습니다</string>
+  <string name="result_product">제품을 찾았습니</string>
+  <string name="result_sms">전화번호를 찾았습니다</string>
+  <string name="result_tel">전화번호를 찾았습니다</string>
+  <string name="result_text">단문을 찾았습니다</string>
+  <string name="result_uri">인터넷 주소를 찾았습니다</string>
+  <string name="result_wifi">WiFi 설정을 찾았습니다</string>
+  <string name="sbc_name">구글 책 검색</string>
+  <string name="wifi_changing_network">네트워크에 연결을 요청\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-nl/strings.xml b/BarCodeScanner/mobile/src/main/res/values-nl/strings.xml
new file mode 100644 (file)
index 0000000..52c7045
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Applicaties</string>
+  <string name="bookmark_picker_name">Bladwijzers</string>
+  <string name="button_add_calendar">Toevoegen aan agenda</string>
+  <string name="button_add_contact">Toevoegen aan contactpersonen</string>
+  <string name="button_book_search">Boeken zoeken</string>
+  <string name="button_cancel">Annuleren</string>
+  <string name="button_custom_product_search">Aangepast zoeken</string>
+  <string name="button_dial">Nummer bellen</string>
+  <string name="button_email">E-mail versturen</string>
+  <string name="button_get_directions">Routebeschrijving opvragen</string>
+  <string name="button_mms">MMS versturen</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Browser openen</string>
+  <string name="button_product_search">Producten zoeken</string>
+  <string name="button_search_book_contents">Boekinhoud zoeken</string>
+  <string name="button_share_app">Applicatie</string>
+  <string name="button_share_bookmark">Bladwijzer</string>
+  <string name="button_share_by_email">Delen via e-mail</string>
+  <string name="button_share_by_sms">Delen via sms</string>
+  <string name="button_share_clipboard">Klembord</string>
+  <string name="button_share_contact">Contactpersoon</string>
+  <string name="button_show_map">Kaart weergeven</string>
+  <string name="button_sms">Sms versturen</string>
+  <string name="button_web_search">Zoeken op internet</string>
+  <string name="button_wifi">Verbinden met netwerk</string>
+  <string name="contents_contact">Contactpersooninformatie</string>
+  <string name="contents_email">E-mailadres</string>
+  <string name="contents_location">Geografische coördinaten</string>
+  <string name="contents_phone">Telefoonnummer</string>
+  <string name="contents_sms">Sms-adres</string>
+  <string name="contents_text">Platte tekst</string>
+  <string name="history_clear_one_history_text">Wissen</string>
+  <string name="history_clear_text">Geschiedenis wissen</string>
+  <string name="history_email_title">Barcode Scanner-geschiedenis</string>
+  <string name="history_empty">Leeg</string>
+  <string name="history_empty_detail">Er zijn geen barcodes gescand</string>
+  <string name="history_send">Geschiedenis versturen</string>
+  <string name="history_title">Geschiedenis</string>
+  <string name="menu_encode_mecard">MECARD gebruiken</string>
+  <string name="menu_encode_vcard">vCard gebruiken</string>
+  <string name="menu_help">Help</string>
+  <string name="menu_history">Geschiedenis</string>
+  <string name="menu_settings">Instellingen</string>
+  <string name="menu_share">Delen</string>
+  <string name="msg_bulk_mode_scanned">Bulkmodus: barcode gescand en opgeslagen</string>
+  <string name="msg_camera_framework_bug">Sorry, er is een probleem met de Android-camera. Probeer je telefoon opnieuw op te starten.</string>
+  <string name="msg_default_format">Formaat</string>
+  <string name="msg_default_meta">Metadata</string>
+  <string name="msg_default_mms_subject">Hallo</string>
+  <string name="msg_default_status">Plaats een barcode binnen de rechthoek om deze te scannen.</string>
+  <string name="msg_default_time">Tijd</string>
+  <string name="msg_default_type">Type</string>
+  <string name="msg_encode_contents_failed">Kan geen barcode genereren op basis van de opgegeven gegevens.</string>
+  <string name="msg_error">Fout</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Sorry, de opgevraagde applicatie kan niet worden gestart. De barcode is mogelijk ongeldig.</string>
+  <string name="msg_invalid_value">Ongeldige waarde</string>
+  <string name="msg_redirect">Doorverwijzing</string>
+  <string name="msg_sbc_book_not_searchable">Sorry, dit boek kan niet worden doorzocht.</string>
+  <string name="msg_sbc_failed">Sorry, er is een fout opgetreden bij het zoeken.</string>
+  <string name="msg_sbc_no_page_returned">Geen pagina ontvangen</string>
+  <string name="msg_sbc_page">Pagina</string>
+  <string name="msg_sbc_results">Resultaten</string>
+  <string name="msg_sbc_searching_book">Boek doorzoeken\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Fragment niet beschikbaar</string>
+  <string name="msg_share_explanation">Je kunt gegevens delen door een barcode op je scherm te laten zien en deze met een andere telefoon te scannen.</string>
+  <string name="msg_share_text">Of typ wat tekst en druk op Enter</string>
+  <string name="msg_sure">Weet je het zeker?</string>
+  <string name="msg_unmount_usb">Sorry, de SD-kaart is niet toegankelijk.</string>
+  <string name="preferences_actions_title">Wanneer een barcode is gevonden\u2026</string>
+  <string name="preferences_auto_focus_title">Autofocus gebruiken</string>
+  <string name="preferences_auto_open_web_title">Automatisch open webpaginas</string>
+  <string name="preferences_bulk_mode_summary">Continu barcodes scannen en opslaan</string>
+  <string name="preferences_bulk_mode_title">Bulkmodus</string>
+  <string name="preferences_copy_to_clipboard_title">Kopiëren naar klembord</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Vervanginen: %s = inhoud, %f = formaat, %t = type</string>
+  <string name="preferences_custom_product_search_title">Aangepaste zoek-URL</string>
+  <string name="preferences_decode_1D_industrial_title">1D industrieel</string>
+  <string name="preferences_decode_1D_product_title">1D product</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Datamatrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR Codes</string>
+  <string name="preferences_device_bug_workarounds_title">Apparaat Bug Tijdelijke oplossingen</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Geen barcode scènemodus</string>
+  <string name="preferences_disable_continuous_focus_summary">Alleen standaard scherpstelfunctie gebruiken</string>
+  <string name="preferences_disable_continuous_focus_title">Niet doorlopend scherpstellen</string>
+  <string name="preferences_disable_exposure_title">Geen blootstelling</string>
+  <string name="preferences_disable_metering_title">Geen metingen</string>
+  <string name="preferences_front_light_auto">Automatisch</string>
+  <string name="preferences_front_light_off">Inactieve</string>
+  <string name="preferences_front_light_on">Actief</string>
+  <string name="preferences_front_light_summary">Verbetert het scannen bij weinig licht bij sommige telefoons, maar kan schittering veroorzaken. Werkt niet op alle telefoons.</string>
+  <string name="preferences_front_light_title">Flitser gebruiken</string>
+  <string name="preferences_general_title">Algemene instellingen</string>
+  <string name="preferences_history_summary">Bewaar uw scans in de Geschiedenis</string>
+  <string name="preferences_history_title">Toevoegen aan Geschiedenis</string>
+  <string name="preferences_invert_scan_summary">Scan naar witte barcodes op een zwarte achtergrond. Niet beschikbaar op sommige apparaten.</string>
+  <string name="preferences_invert_scan_title">Scan omkeren</string>
+  <string name="preferences_name">Instellingen</string>
+  <string name="preferences_orientation_title">Niet automatisch draaien</string>
+  <string name="preferences_play_beep_title">Piepen</string>
+  <string name="preferences_remember_duplicates_summary">Meerdere scans van dezelfde barcode opslaan in de geschiedenis</string>
+  <string name="preferences_remember_duplicates_title">Dubbele onthouden</string>
+  <string name="preferences_result_title">Instellingen voor resultaten</string>
+  <string name="preferences_scanning_title">Bij het scannen van barcodes, decodeer\u2026</string>
+  <string name="preferences_search_country">Zoeken op land</string>
+  <string name="preferences_supplemental_summary">Meer informatie over de inhoud van de barcode proberen op te halen</string>
+  <string name="preferences_supplemental_title">Meer informatie ophalen</string>
+  <string name="preferences_vibrate_title">Trillen</string>
+  <string name="result_address_book">Contactpersooninformatie gevonden</string>
+  <string name="result_calendar">Agendagebeurtenis gevonden</string>
+  <string name="result_email_address">E-mailadres gevonden</string>
+  <string name="result_geo">Geografische coördinaten gevonden</string>
+  <string name="result_isbn">Boek gevonden</string>
+  <string name="result_product">Product gevonden</string>
+  <string name="result_sms">Sms-adres gevonden</string>
+  <string name="result_tel">Telefoonnummer gevonden</string>
+  <string name="result_text">Platte tekst gevonden</string>
+  <string name="result_uri">URL gevonden</string>
+  <string name="result_wifi">WLAN-configuratie gevonden</string>
+  <string name="sbc_name">Zoeken op Google Boeken</string>
+  <string name="wifi_changing_network">Verbinding met netwerk opvragen\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-pl/strings.xml b/BarCodeScanner/mobile/src/main/res/values-pl/strings.xml
new file mode 100644 (file)
index 0000000..acd5b1d
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Aplikacje</string>
+  <string name="bookmark_picker_name">Zakładki</string>
+  <string name="button_add_calendar">Dodaj do kalendarza</string>
+  <string name="button_add_contact">Dodaj kontakt</string>
+  <string name="button_book_search">Szukaj książek</string>
+  <string name="button_cancel">Anuluj</string>
+  <string name="button_custom_product_search">Wyszukiwanie indywidualne</string>
+  <string name="button_dial">Zadzwoń</string>
+  <string name="button_email">Wyślij email</string>
+  <string name="button_get_directions">Wskazówki</string>
+  <string name="button_mms">Wyślij MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Otwórz przeglądarkę</string>
+  <string name="button_product_search">Szukaj produktów</string>
+  <string name="button_search_book_contents">Przeszukaj zawartość</string>
+  <string name="button_share_app">Aplikacja</string>
+  <string name="button_share_bookmark">Zakładka</string>
+  <string name="button_share_by_email">Udostępnij przez email</string>
+  <string name="button_share_by_sms">Udostępnij przez SMS</string>
+  <string name="button_share_clipboard">Schowek</string>
+  <string name="button_share_contact">Kontakt</string>
+  <string name="button_show_map">Pokaż mapę</string>
+  <string name="button_sms">Wyślij SMS</string>
+  <string name="button_web_search">Szukaj w sieci</string>
+  <string name="button_wifi">Podłącz do sieci</string>
+  <string name="contents_contact">Informacje o kontakcie</string>
+  <string name="contents_email">Adres email</string>
+  <string name="contents_location">Współrzędne geograficzne</string>
+  <string name="contents_phone">Numer telefonu</string>
+  <string name="contents_sms">Adres SMS</string>
+  <string name="contents_text">Zwykły tekst</string>
+  <string name="history_clear_one_history_text">Wyczyść</string>
+  <string name="history_clear_text">Wyczyść historię</string>
+  <string name="history_email_title">Historia Skanera Kodów Paskowych</string>
+  <string name="history_empty">Pusty</string>
+  <string name="history_empty_detail">Brak zeskanowanych kodów</string>
+  <string name="history_send">Wyślij historię</string>
+  <string name="history_title">Historia</string>
+  <string name="menu_encode_mecard">Użyj MECARD</string>
+  <string name="menu_encode_vcard">Użyj vCard</string>
+  <string name="menu_help">Pomoc</string>
+  <string name="menu_history">Historia</string>
+  <string name="menu_settings">Ustawienia</string>
+  <string name="menu_share">Udostępnij</string>
+  <string name="msg_bulk_mode_scanned">Tryb zbiorczy: skanowanie i zapisywanie kodów kreskowych w trybie ciągłym</string>
+  <string name="msg_camera_framework_bug">Przepraszamy, aparat Android napotkał problem. Może wystąpić potrzeba ponownego uruchomienia urządzenia.</string>
+  <string name="msg_default_format">Format</string>
+  <string name="msg_default_meta">Metadanych</string>
+  <string name="msg_default_mms_subject">Cześć</string>
+  <string name="msg_default_status">Umieść kod paskowy w prostokącie wizjera aby zeskanować.</string>
+  <string name="msg_default_time">Czas</string>
+  <string name="msg_default_type">Typ</string>
+  <string name="msg_encode_contents_failed">Nie można zakodować kodu paskowego z dostarczonych danych.</string>
+  <string name="msg_error">Błąd</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Przepraszamy, żadana aplikacja nie może zostać uruchomiona. Zawartość kodu paskowego może być nieprawidłowa.</string>
+  <string name="msg_invalid_value">Nieprawidłowa wartość</string>
+  <string name="msg_redirect">Przekierowanie</string>
+  <string name="msg_sbc_book_not_searchable">Przepraszamy, ta książka nie jest przeszukiwalna.</string>
+  <string name="msg_sbc_failed">Przepraszamy, wyszukiwania napotkało problem.</string>
+  <string name="msg_sbc_no_page_returned">Nie zwrócono żadnej strony</string>
+  <string name="msg_sbc_page">Strona</string>
+  <string name="msg_sbc_results">Wyniki</string>
+  <string name="msg_sbc_searching_book">Przeszukiwanie książki\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Wycinek niedostępny</string>
+  <string name="msg_share_explanation">Możesz udostępniać dane wyświetlając kod paskowy na swoim ekranie i skanując go innym telefonem.</string>
+  <string name="msg_share_text">Albo wpisz tekst</string>
+  <string name="msg_sure">Czy na pewno?</string>
+  <string name="msg_unmount_usb">Niestety, karta SD nie jest dostępna.</string>
+  <string name="preferences_actions_title">Akcja po odnalezieniu kodu\u2026</string>
+  <string name="preferences_auto_focus_title">Ustaw ostrość</string>
+  <string name="preferences_auto_open_web_title">Otwieranie stron internetowych automatycznie</string>
+  <string name="preferences_bulk_mode_summary">Skanowanie i zapisywanie wielu kodów kreskowych jeden po drugim w trybie ciągłym</string>
+  <string name="preferences_bulk_mode_title">Tryb ciągłego skanowania</string>
+  <string name="preferences_copy_to_clipboard_title">Kopiuj do schowka</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Zastępstwa: %s = zawartość, %f = format, %t = typ</string>
+  <string name="preferences_custom_product_search_title">Własny URL wyszukiwania</string>
+  <string name="preferences_decode_1D_industrial_title">1D przemysłowe</string>
+  <string name="preferences_decode_1D_product_title">1D wyrobów</string>
+  <string name="preferences_decode_Aztec_title">Aztek</string>
+  <string name="preferences_decode_Data_Matrix_title">Dekoduj Decode Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">Dekoduj kody QR</string>
+  <string name="preferences_device_bug_workarounds_title">Obejścia błędów urządzeń</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Brak trybu sceny barcode</string>
+  <string name="preferences_disable_continuous_focus_summary">Używaj tylko standardowego trybu ostrości</string>
+  <string name="preferences_disable_continuous_focus_title">Ostrość</string>
+  <string name="preferences_disable_exposure_title">Bez ekspozycji</string>
+  <string name="preferences_disable_metering_title">Nr pomiaru</string>
+  <string name="preferences_front_light_auto">Automatyczny</string>
+  <string name="preferences_front_light_off">Nieaktywny</string>
+  <string name="preferences_front_light_on">Aktywny</string>
+  <string name="preferences_front_light_summary">Polepsza skanowanie przy małej ilości światła w niektórych telefonach, ale może powodować odbłysk. Nie działa na wszystkich telefonach.</string>
+  <string name="preferences_front_light_title">Używaj lampy frontowej</string>
+  <string name="preferences_general_title">Ustawienia ogólne</string>
+  <string name="preferences_history_summary">Przechowywanie skanów w historii</string>
+  <string name="preferences_history_title">Dodaj do historii</string>
+  <string name="preferences_invert_scan_summary">Skanowanie białych kodów kreskowych na czarnym tle. Nie dostępne w niektórych urządzeniach.</string>
+  <string name="preferences_invert_scan_title">Odwróć skanowania</string>
+  <string name="preferences_name">Ustawienia</string>
+  <string name="preferences_orientation_title">Brak automatycznego obracania</string>
+  <string name="preferences_play_beep_title">Piszcz</string>
+  <string name="preferences_remember_duplicates_summary">Przechowuj zaskanowane kody w tej samej historii</string>
+  <string name="preferences_remember_duplicates_title">Pamiętaj, duplikaty</string>
+  <string name="preferences_result_title">Ustawienia wyników</string>
+  <string name="preferences_scanning_title">Podczas skanowania kodów kreskowych\u2026</string>
+  <string name="preferences_search_country">Szukaj kraju</string>
+  <string name="preferences_supplemental_summary">Spróbuj wyszukać więcej informacji na temat kodów kreskowych</string>
+  <string name="preferences_supplemental_title">Pobierz więcej informacji</string>
+  <string name="preferences_vibrate_title">Wibruj</string>
+  <string name="result_address_book">Znaleziono dane kontaktu</string>
+  <string name="result_calendar">Znaleziono wydarzenie z kalendarza</string>
+  <string name="result_email_address">Znaleziono adres email</string>
+  <string name="result_geo">Znaleziono współrzędne geograficzne</string>
+  <string name="result_isbn">Znaleziono książkę</string>
+  <string name="result_product">Znaleziono produkt</string>
+  <string name="result_sms">Znaleziono adres SMS</string>
+  <string name="result_tel">Znaleziono numer telefonu</string>
+  <string name="result_text">Znaleziono zwykły tekst</string>
+  <string name="result_uri">Znaleziono URL</string>
+  <string name="result_wifi">Znaleziono konfiguracje sieci</string>
+  <string name="sbc_name">Wyszukiwanie książek Google</string>
+  <string name="wifi_changing_network">Ubiegającymi się o przyłączenie do sieci\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-pt/strings.xml b/BarCodeScanner/mobile/src/main/res/values-pt/strings.xml
new file mode 100644 (file)
index 0000000..c7d8d78
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Aplicações</string>
+  <string name="bookmark_picker_name">Favoritos</string>
+  <string name="button_add_calendar">Adicionar ao calendário</string>
+  <string name="button_add_contact">Adicionar contacto</string>
+  <string name="button_book_search">Procurar livro</string>
+  <string name="button_cancel">Cancelar</string>
+  <string name="button_custom_product_search">Pesquisa Personalizada</string>
+  <string name="button_dial">Marcar número</string>
+  <string name="button_email">Enviar e-mail</string>
+  <string name="button_get_directions">Obter direcções</string>
+  <string name="button_mms">Enviar MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Abrir navegador</string>
+  <string name="button_product_search">Procurar produto</string>
+  <string name="button_search_book_contents">Pesquisar conteúdos</string>
+  <string name="button_share_app">Aplicação</string>
+  <string name="button_share_bookmark">Favorito</string>
+  <string name="button_share_by_email">Partilhar via e-mail</string>
+  <string name="button_share_by_sms">Partilhar via SMS</string>
+  <string name="button_share_clipboard">Área de transferência</string>
+  <string name="button_share_contact">Contacto</string>
+  <string name="button_show_map">Visualizar mapa</string>
+  <string name="button_sms">Enviar SMS</string>
+  <string name="button_web_search">Pesquisa na Web</string>
+  <string name="button_wifi">Conectar à rede</string>
+  <string name="contents_contact">Informação de contacto</string>
+  <string name="contents_email">Endereço de e-mail</string>
+  <string name="contents_location">Coordenadas geográficas</string>
+  <string name="contents_phone">Número de telefone</string>
+  <string name="contents_sms">Endereço SMS</string>
+  <string name="contents_text">Texto simples</string>
+  <string name="history_clear_one_history_text">Limpar</string>
+  <string name="history_clear_text">Limpar histórico</string>
+  <string name="history_email_title">Histórico do Barcode Scanner</string>
+  <string name="history_empty">Vazio</string>
+  <string name="history_empty_detail">Não código de barras foram registrados</string>
+  <string name="history_send">Enviar histórico</string>
+  <string name="history_title">Histórico</string>
+  <string name="menu_encode_mecard">Usar MECARD</string>
+  <string name="menu_encode_vcard">Usar vCard</string>
+  <string name="menu_help">Ajuda</string>
+  <string name="menu_history">Histórico</string>
+  <string name="menu_settings">Definições</string>
+  <string name="menu_share">Partilhar</string>
+  <string name="msg_bulk_mode_scanned">Modo em massa: código de barras lido e guardado</string>
+  <string name="msg_camera_framework_bug">Desculpe, a câmera do Android encontrou um problema. Poderá precisar de reiniciar o dispositivo.</string>
+  <string name="msg_default_format">Formato</string>
+  <string name="msg_default_meta">Metadata</string>
+  <string name="msg_default_mms_subject">Olá</string>
+  <string name="msg_default_status">Alinhar código de barras com o exemplo para ser lido.</string>
+  <string name="msg_default_time">Tempo</string>
+  <string name="msg_default_type">Tipo</string>
+  <string name="msg_encode_contents_failed">Não foi possível codificar o código de barradas apartir dos dados fornecidos.</string>
+  <string name="msg_error">Erro</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Desculpe, a aplicação solicitada não pode ser iniciada. O conteúdo do código de barras poderá ser inválido.</string>
+  <string name="msg_invalid_value">Valor inválido</string>
+  <string name="msg_redirect">Redirecionar</string>
+  <string name="msg_sbc_book_not_searchable">Desculpe, este livro não é pesquisável.</string>
+  <string name="msg_sbc_failed">Desculpe, foi encontrado um erro na pesquisa.</string>
+  <string name="msg_sbc_no_page_returned">Nenhuma página obtida</string>
+  <string name="msg_sbc_page">Página</string>
+  <string name="msg_sbc_results">Resultados</string>
+  <string name="msg_sbc_searching_book">A procurar livro\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Trecho não disponível</string>
+  <string name="msg_share_explanation">Pode partilhar dados exibindo um código de barras no seu ecrã e lendo-o com outro telemóvel</string>
+  <string name="msg_share_text">Ou introduza algum texto e pressione Enter</string>
+  <string name="msg_sure">Tem a certeza?</string>
+  <string name="msg_unmount_usb">Desculpe, o cartão SD não está disponível.</string>
+  <string name="preferences_actions_title">Quando o código de barras é encontrado\u2026</string>
+  <string name="preferences_auto_focus_title">Usar foco automático</string>
+  <string name="preferences_auto_open_web_title">Abrir páginas da web automaticamente</string>
+  <string name="preferences_bulk_mode_summary">Ler e guardar códigos de barras continuamente</string>
+  <string name="preferences_bulk_mode_title">Modo em massa</string>
+  <string name="preferences_copy_to_clipboard_title">Copiar para a área de transferência</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Substituições: %s = conteúdos, %f = formato, %t = tipo</string>
+  <string name="preferences_custom_product_search_title">Pesquisa personalizada de URL</string>
+  <string name="preferences_decode_1D_industrial_title">Indústrial 1D</string>
+  <string name="preferences_decode_1D_product_title">Produto 1D</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR Codes</string>
+  <string name="preferences_device_bug_workarounds_title">Soluções alternativas de dispositivos com erros</string>
+  <string name="preferences_disable_barcode_scene_mode_title">No modo de cena de código de barras</string>
+  <string name="preferences_disable_continuous_focus_summary">Use apenas o modo de focagem padrão</string>
+  <string name="preferences_disable_continuous_focus_title">No foco contínuo</string>
+  <string name="preferences_disable_exposure_title">Nenhuma exposição</string>
+  <string name="preferences_disable_metering_title">Sem medição</string>
+  <string name="preferences_front_light_auto">Automático</string>
+  <string name="preferences_front_light_off">Inativo</string>
+  <string name="preferences_front_light_on">Ativo</string>
+  <string name="preferences_front_light_summary">Melhora a leitura em luz fraca em alguns telefones, mas pode causar clarões. Não disponível em certos dispositivos.</string>
+  <string name="preferences_front_light_title">Usar luz da frente</string>
+  <string name="preferences_general_title">Definições Gerais</string>
+  <string name="preferences_history_summary">Armazene seus scans em História</string>
+  <string name="preferences_history_title">Adicionar à História</string>
+  <string name="preferences_invert_scan_summary">Procurar por códigos de barras brancos em fundo preto. Não disponível em certos dispositivos.</string>
+  <string name="preferences_invert_scan_title">Inverter leitura</string>
+  <string name="preferences_name">Definições</string>
+  <string name="preferences_orientation_title">Sem rotação automática</string>
+  <string name="preferences_play_beep_title">Apitar</string>
+  <string name="preferences_remember_duplicates_summary">Guardar pesquisas múltiplas do mesmo código de barras no histórico</string>
+  <string name="preferences_remember_duplicates_title">Lembrar duplicados</string>
+  <string name="preferences_result_title">Definições do resultado</string>
+  <string name="preferences_scanning_title">Quando procurar por códigos de barras, descodificar\u2026</string>
+  <string name="preferences_search_country">País busca</string>
+  <string name="preferences_supplemental_summary">Tentar recuperar mais informação sobre os conteúdos dos códigos de barras</string>
+  <string name="preferences_supplemental_title">Recuperar mais informação</string>
+  <string name="preferences_vibrate_title">Vibrar</string>
+  <string name="result_address_book">Info de contacto encontrada</string>
+  <string name="result_calendar">Evento de calendário encontrado</string>
+  <string name="result_email_address">Endereço de e-mail encontrado</string>
+  <string name="result_geo">Coordenadas geográficas encontradas</string>
+  <string name="result_isbn">Livro encontrado</string>
+  <string name="result_product">Produto encontrado</string>
+  <string name="result_sms">Endereço SMS encontrado</string>
+  <string name="result_tel">Número de telefone encontrado</string>
+  <string name="result_text">Texto simples encontrado</string>
+  <string name="result_uri">URL encontrado</string>
+  <string name="result_wifi">Configuração WLAN encontrados</string>
+  <string name="sbc_name">Pesquisa Google Book</string>
+  <string name="wifi_changing_network">Solicitando ligação à rede\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-ro/strings.xml b/BarCodeScanner/mobile/src/main/res/values-ro/strings.xml
new file mode 100644 (file)
index 0000000..417f954
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Aplicații</string>
+  <string name="bookmark_picker_name">Nume însemnare</string>
+  <string name="button_add_calendar">Adaugă în calendar</string>
+  <string name="button_add_contact">Adaugă contact</string>
+  <string name="button_book_search">Caută carte</string>
+  <string name="button_cancel">Renunță</string>
+  <string name="button_custom_product_search">Căutare personalizată</string>
+  <string name="button_dial">Telefonează la numărul</string>
+  <string name="button_email">Trimite e-mail</string>
+  <string name="button_get_directions">Descarcă indicații</string>
+  <string name="button_mms">Trimite MMS</string>
+  <string name="button_ok">Acceptă</string>
+  <string name="button_open_browser">Deschide navigator</string>
+  <string name="button_product_search">Caută produs</string>
+  <string name="button_search_book_contents">Caută conținut</string>
+  <string name="button_share_app">Aplicație</string>
+  <string name="button_share_bookmark">Semn de carte</string>
+  <string name="button_share_by_email">Distribuie prin e-mail</string>
+  <string name="button_share_by_sms">Distribuie prin SMS</string>
+  <string name="button_share_clipboard">Clipboard</string>
+  <string name="button_share_contact">Contact</string>
+  <string name="button_show_map">Arată harta</string>
+  <string name="button_sms">Trimite SMS</string>
+  <string name="button_web_search">Caută pe web</string>
+  <string name="button_wifi">Conectează la rețea</string>
+  <string name="contents_contact">Informații de contact</string>
+  <string name="contents_email">Adresă de e-mail</string>
+  <string name="contents_location">Coordonate geografice</string>
+  <string name="contents_phone">Telefon</string>
+  <string name="contents_sms">Număr de SMS</string>
+  <string name="contents_text">Text</string>
+  <string name="history_clear_one_history_text">Șterge</string>
+  <string name="history_clear_text">Șterge istoricul</string>
+  <string name="history_email_title">Istoric Barcode Scanner</string>
+  <string name="history_empty">Nicio înregistare</string>
+  <string name="history_empty_detail">Nicio scanare de coduri de bară nu a fost înregistrată</string>
+  <string name="history_send">Trimite istoric</string>
+  <string name="history_title">Istoric</string>
+  <string name="menu_encode_mecard">Folosește MECARD</string>
+  <string name="menu_encode_vcard">Folosește vCard</string>
+  <string name="menu_help">Ajutor</string>
+  <string name="menu_history">Istoric</string>
+  <string name="menu_settings">Configurări</string>
+  <string name="menu_share">Distribuie</string>
+  <string name="msg_bulk_mode_scanned">Scanare continuă: cod de bare scanat și salvat</string>
+  <string name="msg_camera_framework_bug">Probleme cu camera foto. Repornește dispozitivul.</string>
+  <string name="msg_default_format">Format</string>
+  <string name="msg_default_meta">Metadate</string>
+  <string name="msg_default_mms_subject">Servus</string>
+  <string name="msg_default_status">Plasează codul de bare în interiorul vizorului pentru a-l scana</string>
+  <string name="msg_default_time">Ora</string>
+  <string name="msg_default_type">Tip</string>
+  <string name="msg_encode_contents_failed">Codificare eșuată a codului de bare, din datele furnizate</string>
+  <string name="msg_error">Eroare</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Aplicația solicitată nu a putut fi lansată. Codul de bare poate fi incorect.</string>
+  <string name="msg_invalid_value">Valoare nevalidă</string>
+  <string name="msg_redirect">Redirecționare</string>
+  <string name="msg_sbc_book_not_searchable">Cartea nu poate fi căutată</string>
+  <string name="msg_sbc_failed">Căutarea a întâmpinat probleme</string>
+  <string name="msg_sbc_no_page_returned">Nicio pagină găsită</string>
+  <string name="msg_sbc_page">Pagina</string>
+  <string name="msg_sbc_results">Rezultate</string>
+  <string name="msg_sbc_searching_book">Caută cartea\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Fragment indisponibil</string>
+  <string name="msg_share_explanation">Poți distribui datele afișând codul pe ecran și scanându-l cu alt aparat</string>
+  <string name="msg_share_text">Sau introdu textul și tastează Enter</string>
+  <string name="msg_sure">Confirmă</string>
+  <string name="msg_unmount_usb">Card SD inaccesibil</string>
+  <string name="preferences_actions_title">Când un cod de bare este găsit\u2026</string>
+  <string name="preferences_auto_focus_title">Folosește focalizare automată</string>
+  <string name="preferences_auto_open_web_title">Deschide automat paginile web</string>
+  <string name="preferences_bulk_mode_summary">Scanează continuu și salvează codurile de bară</string>
+  <string name="preferences_bulk_mode_title">Scanare continuă</string>
+  <string name="preferences_copy_to_clipboard_title">Copiază în clipboard</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Înlocuiri: %s = conținut, %f = format, %t = tip</string>
+  <string name="preferences_custom_product_search_title">Căutare URL personalizată</string>
+  <string name="preferences_decode_1D_industrial_title">1D Industriale</string>
+  <string name="preferences_decode_1D_product_title">1D Produs</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417</string>
+  <string name="preferences_decode_QR_title">Coduri QR</string>
+  <string name="preferences_device_bug_workarounds_title">Rezolvări rapide ale defectelor la aparat</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Nicio imagine afișată în mod vedere</string>
+  <string name="preferences_disable_continuous_focus_summary">Folosește focalizarea standard</string>
+  <string name="preferences_disable_continuous_focus_title">Dezactivează focalizarea continuă</string>
+  <string name="preferences_disable_exposure_title">Nicio expunere</string>
+  <string name="preferences_disable_metering_title">Nicio contorizare</string>
+  <string name="preferences_front_light_auto">Iluminare automată</string>
+  <string name="preferences_front_light_off">Oprește</string>
+  <string name="preferences_front_light_on">Pornește</string>
+  <string name="preferences_front_light_summary">Îmbunătățește scanarea în lumină redusă, dar poate cauza strălucire excesivă. Nu funcționează la toate aparatele.</string>
+  <string name="preferences_front_light_title">Folosește lumina frontală</string>
+  <string name="preferences_general_title">Configurări generale</string>
+  <string name="preferences_history_summary">Păstrați scanate în istorie</string>
+  <string name="preferences_history_title">Adauga la Istorie</string>
+  <string name="preferences_invert_scan_summary">Scanează coduri de bară albe pe fundal negru. Indisponibil pe unele aparate.</string>
+  <string name="preferences_invert_scan_title">Scanare în negativ</string>
+  <string name="preferences_name">Configurări</string>
+  <string name="preferences_orientation_title">Fără rotire automată</string>
+  <string name="preferences_play_beep_title">Sună</string>
+  <string name="preferences_remember_duplicates_summary">Înregistrează în Istoric, scanări multiple ale aceluiași cod de bare</string>
+  <string name="preferences_remember_duplicates_title">Reține scanările duplicat</string>
+  <string name="preferences_result_title">Configurări rezultate</string>
+  <string name="preferences_scanning_title">Când scanează coduri de bară, decodifică\u2026</string>
+  <string name="preferences_search_country">Caută țara</string>
+  <string name="preferences_supplemental_summary">Încearcă preluarea mai multor informații din conținutul codurilor de bară</string>
+  <string name="preferences_supplemental_title">Preia mai multe informații</string>
+  <string name="preferences_vibrate_title">Vibrează</string>
+  <string name="result_address_book">Găsit informații de contact</string>
+  <string name="result_calendar">Găsit eveniment în calendar</string>
+  <string name="result_email_address">Găsit adresa de e-mail</string>
+  <string name="result_geo">Găsit coordonatele geografice</string>
+  <string name="result_isbn">Găsit cartea</string>
+  <string name="result_product">Găsit produs</string>
+  <string name="result_sms">Găsit număr de SMS</string>
+  <string name="result_tel">Găsit număr de telefon</string>
+  <string name="result_text">Găsit text</string>
+  <string name="result_uri">Găsit URL</string>
+  <string name="result_wifi">Găsit configurarea WLAN</string>
+  <string name="sbc_name">Căutare Google Cărți</string>
+  <string name="wifi_changing_network">Solicită conexiune la rețea\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-ru/strings.xml b/BarCodeScanner/mobile/src/main/res/values-ru/strings.xml
new file mode 100644 (file)
index 0000000..4de59a4
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Сканер штрих-кодов</string>
+  <string name="app_picker_name">Приложения</string>
+  <string name="bookmark_picker_name">Закладки</string>
+  <string name="button_add_calendar">Добавить в календарь</string>
+  <string name="button_add_contact">Добавить контакт</string>
+  <string name="button_book_search">Поиск книги</string>
+  <string name="button_cancel">Отмена</string>
+  <string name="button_custom_product_search">Пользовательский поиск</string>
+  <string name="button_dial">Набрать номер</string>
+  <string name="button_email">Отправить e-mail</string>
+  <string name="button_get_directions">Проложить маршрут</string>
+  <string name="button_mms">Послать MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Открыть браузер</string>
+  <string name="button_product_search">Поиск товара</string>
+  <string name="button_search_book_contents">Поиск в содержании книги</string>
+  <string name="button_share_app">Приложение</string>
+  <string name="button_share_bookmark">Закладка</string>
+  <string name="button_share_by_email">Поделиться через эл. почту</string>
+  <string name="button_share_by_sms">Поделиться через SMS</string>
+  <string name="button_share_clipboard">Буфер обмена</string>
+  <string name="button_share_contact">Контакт</string>
+  <string name="button_show_map">Показать карту</string>
+  <string name="button_sms">Отправить SMS</string>
+  <string name="button_web_search">Поиск в интернете</string>
+  <string name="button_wifi">Подключиться к сети</string>
+  <string name="contents_contact">Контактная информация</string>
+  <string name="contents_email">Адрес эл. почты</string>
+  <string name="contents_location">Географические координаты</string>
+  <string name="contents_phone">Номер телефона</string>
+  <string name="contents_sms">Адрес для SMS</string>
+  <string name="contents_text">Текст</string>
+  <string name="history_clear_one_history_text">Удалить</string>
+  <string name="history_clear_text">Удалить историю</string>
+  <string name="history_email_title">История сканирования</string>
+  <string name="history_empty">Пусто</string>
+  <string name="history_empty_detail">Нет сохраненных штрих-кодов</string>
+  <string name="history_send">Отправить историю</string>
+  <string name="history_title">История</string>
+  <string name="menu_encode_mecard">Использовать MECARD</string>
+  <string name="menu_encode_vcard">Использовать vCard</string>
+  <string name="menu_help">Помощь</string>
+  <string name="menu_history">История</string>
+  <string name="menu_settings">Настройки</string>
+  <string name="menu_share">Поделиться</string>
+  <string name="msg_bulk_mode_scanned">Массовый режим: штрих-код распознан и сохранен</string>
+  <string name="msg_camera_framework_bug">К сожалению, возникла ошибка камеры. Может потребоваться перезагрузить устройство.</string>
+  <string name="msg_default_format">Формат</string>
+  <string name="msg_default_meta">Метаданные</string>
+  <string name="msg_default_mms_subject">Привет</string>
+  <string name="msg_default_status">Чтобы сканировать штрих-код, поместите его в прямоугольник видоискателя.</string>
+  <string name="msg_default_time">Время</string>
+  <string name="msg_default_type">Тип</string>
+  <string name="msg_encode_contents_failed">Невозможно создать штрих-код из текущих данных.</string>
+  <string name="msg_error">Ошибка</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">К сожалению, запрошенное приложение не может быть запущено. Возможно, штрих-код содержит неверные данные.</string>
+  <string name="msg_invalid_value">Неверное значение</string>
+  <string name="msg_redirect">Переслать</string>
+  <string name="msg_sbc_book_not_searchable">К сожалению, поиск в этой книге невозможен.</string>
+  <string name="msg_sbc_failed">К сожалению, при поиске произошла ошибка.</string>
+  <string name="msg_sbc_no_page_returned">Ни одна страница не возвращена.</string>
+  <string name="msg_sbc_page">Страница</string>
+  <string name="msg_sbc_results">Результаты</string>
+  <string name="msg_sbc_searching_book">Поиск книги\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Фрагмент недоступен</string>
+  <string name="msg_share_explanation">Вы можете поделиться данными, отобразив на экране своего телефона штрих-код, который можно считать другим телефоном.</string>
+  <string name="msg_share_text">Или введите текст</string>
+  <string name="msg_sure">Вы уверены?</string>
+  <string name="msg_unmount_usb">К сожалению, SD-карта не доступна.</string>
+  <string name="preferences_actions_title">Когда штрих-код найден\u2026</string>
+  <string name="preferences_auto_focus_title">Использовать автофокус</string>
+  <string name="preferences_auto_open_web_title">Открывать веб-страницы автоматически</string>
+  <string name="preferences_bulk_mode_summary">Постоянно сканировать и сохранять штрих-коды</string>
+  <string name="preferences_bulk_mode_title">Массовое сканирование</string>
+  <string name="preferences_copy_to_clipboard_title">Копировать в буфер обмена</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Подстановки: %s = содержание, %f = формат, %t = тип</string>
+  <string name="preferences_custom_product_search_title">URL пользовательского поиска</string>
+  <string name="preferences_decode_1D_industrial_title">1D промышленные</string>
+  <string name="preferences_decode_1D_product_title">1D товарные</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR-коды</string>
+  <string name="preferences_device_bug_workarounds_title">Исправление ошибок устройства</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Не использовать режим съемки "штрих-код"</string>
+  <string name="preferences_disable_continuous_focus_summary">Использовать только стандартный режим фокусировки</string>
+  <string name="preferences_disable_continuous_focus_title">Не использовать непрерывную фокусировку</string>
+  <string name="preferences_disable_exposure_title">Не использовать экспозицию</string>
+  <string name="preferences_disable_metering_title">Не использовать измерение</string>
+  <string name="preferences_front_light_auto">Автоматически</string>
+  <string name="preferences_front_light_off">Выключен</string>
+  <string name="preferences_front_light_on">Включен</string>
+  <string name="preferences_front_light_summary">Улучшает распознавание в условиях низкой освещенности, но может вызвать блики. Работает не на всех устройствах.</string>
+  <string name="preferences_front_light_title">Фонарик</string>
+  <string name="preferences_general_title">Общие настройки</string>
+  <string name="preferences_history_summary">Храните ваши сканы в истории</string>
+  <string name="preferences_history_title">Добавить в истории</string>
+  <string name="preferences_invert_scan_summary">Сканирование белых штрих-кодов на черном фоне. Не работает на некоторых устройствах.</string>
+  <string name="preferences_invert_scan_title">Инвертировать</string>
+  <string name="preferences_name">Настройки</string>
+  <string name="preferences_orientation_title">Не поворачивать автоматически</string>
+  <string name="preferences_play_beep_title">Звуковой сигнал</string>
+  <string name="preferences_remember_duplicates_summary">Сохранять в истории результат сканирования одного и того же штрих-кода</string>
+  <string name="preferences_remember_duplicates_title">Запоминать дубликаты</string>
+  <string name="preferences_result_title">Настройки результатов</string>
+  <string name="preferences_scanning_title">Распознавать штрих-коды\u2026</string>
+  <string name="preferences_search_country">Страна для поиска</string>
+  <string name="preferences_supplemental_summary">Показывать подробную информацию о штрих-коде</string>
+  <string name="preferences_supplemental_title">Подробности</string>
+  <string name="preferences_vibrate_title">Вибрация</string>
+  <string name="result_address_book">Найдены контактные данные</string>
+  <string name="result_calendar">Найдено событие для календаря</string>
+  <string name="result_email_address">Найден адрес эл. почты</string>
+  <string name="result_geo">Найдены географические координаты</string>
+  <string name="result_isbn">Найдена книга</string>
+  <string name="result_product">Найден товар</string>
+  <string name="result_sms">Найден адрес для SMS</string>
+  <string name="result_tel">Найден номер телефона</string>
+  <string name="result_text">Найден текст</string>
+  <string name="result_uri">Найден URL</string>
+  <string name="result_wifi">Найдена конфигурация сети</string>
+  <string name="sbc_name">Поиск книг Google</string>
+  <string name="wifi_changing_network">Запрос подключения к сети\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-sk/strings.xml b/BarCodeScanner/mobile/src/main/res/values-sk/strings.xml
new file mode 100644 (file)
index 0000000..e6948d5
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Aplikácie</string>
+  <string name="bookmark_picker_name">Záložky</string>
+  <string name="button_add_calendar">Pridať do kalendára</string>
+  <string name="button_add_contact">Pridať kontakt</string>
+  <string name="button_book_search">Hľadať knihu</string>
+  <string name="button_cancel">Zrušiť</string>
+  <string name="button_custom_product_search">Vlastné vyhľadávanie</string>
+  <string name="button_dial">Vytočiť číslo</string>
+  <string name="button_email">Poslať e-mail</string>
+  <string name="button_get_directions">Získať pokyny</string>
+  <string name="button_mms">Poslať MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Otvoriť prehliadač</string>
+  <string name="button_product_search">Vyhľadať produkt</string>
+  <string name="button_search_book_contents">Vyhľadať obsah</string>
+  <string name="button_share_app">Aplikácia</string>
+  <string name="button_share_bookmark">Záložka</string>
+  <string name="button_share_by_email">Zdieľať cez e-mail</string>
+  <string name="button_share_by_sms">Zdieľať cez SMS</string>
+  <string name="button_share_clipboard">Schránka</string>
+  <string name="button_share_contact">Kontakt</string>
+  <string name="button_show_map">Zobraziť mapu</string>
+  <string name="button_sms">Poslať SMS</string>
+  <string name="button_web_search">Hľadať na webe</string>
+  <string name="button_wifi">Pripojiť sa sieti</string>
+  <string name="contents_contact">Informácie o kontakte</string>
+  <string name="contents_email">E-mailová adresa</string>
+  <string name="contents_location">Geografické súradnice</string>
+  <string name="contents_phone">Telefónne číslo</string>
+  <string name="contents_sms">SMS adresa</string>
+  <string name="contents_text">Obyčajný text</string>
+  <string name="history_clear_one_history_text">Vymazať</string>
+  <string name="history_clear_text">Vymazať históriu</string>
+  <string name="history_email_title">História Barcode Scanneru</string>
+  <string name="history_empty">Prázdna</string>
+  <string name="history_empty_detail">Žiadne čiarové kódy neboli zaznamenané</string>
+  <string name="history_send">Poslať históriu</string>
+  <string name="history_title">História</string>
+  <string name="menu_encode_mecard">Použiť MECARD</string>
+  <string name="menu_encode_vcard">Použiť vCard</string>
+  <string name="menu_help">Nápoveda</string>
+  <string name="menu_history">História</string>
+  <string name="menu_settings">Nastavenia</string>
+  <string name="menu_share">Zdieľať</string>
+  <string name="msg_bulk_mode_scanned">Hromadný režim: skenovanie a ukladanie čiarových kódov</string>
+  <string name="msg_camera_framework_bug">Ospravedlňujeme sa, fotoaparát narazil na problém. Možno bude potrebné reštartovať zariadenie.</string>
+  <string name="msg_default_format">Formát</string>
+  <string name="msg_default_meta">Metadáta</string>
+  <string name="msg_default_mms_subject">Ahoj</string>
+  <string name="msg_default_status">Umiestnite čiarový kód do vnútra obdĺžnika hľadáčiku pre skenovanie.</string>
+  <string name="msg_default_time">Čas</string>
+  <string name="msg_default_type">Typ</string>
+  <string name="msg_encode_contents_failed">Nie je možné zakódovať čiarový kód z poskytnutých údajov.</string>
+  <string name="msg_error">Chyba</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Ospravedlňujeme sa, požadovaná aplikácia nemohla byť spustená. Obsah čiarového kódu je možno neplatný.</string>
+  <string name="msg_invalid_value">Neplatná hodnota</string>
+  <string name="msg_redirect">Presmerovať</string>
+  <string name="msg_sbc_book_not_searchable">Ospravedlňujeme sa, táto kniha nie je prehliadateľná.</string>
+  <string name="msg_sbc_failed">Ospravedlňujeme sa, vyhľadávanie narazilo na problém.</string>
+  <string name="msg_sbc_no_page_returned">Nenašla sa žiadna stránka</string>
+  <string name="msg_sbc_page">Stránka</string>
+  <string name="msg_sbc_results">Výsledky</string>
+  <string name="msg_sbc_searching_book">Vyhľadáva sa kniha\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Úryvok nie je k dispozícii</string>
+  <string name="msg_share_explanation">Môžete zdieľať dáta zobrazením čiarového kódu na displeji vášho zariadenia a jeho zoskenovaním iným zariadením</string>
+  <string name="msg_share_text">Alebo zadajte nejaký text</string>
+  <string name="msg_sure">Ste si istí?</string>
+  <string name="msg_unmount_usb">Ospravedlňujeme sa, SD karta nie je prístupná.</string>
+  <string name="preferences_actions_title">Pri zistení čiarového kódu</string>
+  <string name="preferences_auto_focus_title">Použiť automatické zaostrenie</string>
+  <string name="preferences_auto_open_web_title">Otvorte webové stránky automaticky</string>
+  <string name="preferences_bulk_mode_summary">Skenovať a ukladať veľa čiarových kódov bez prerušenia</string>
+  <string name="preferences_bulk_mode_title">Hromadný režim skenovania</string>
+  <string name="preferences_copy_to_clipboard_title">Kopírovať do schránky</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Nahradiť: %s = obsah, %f = formát, %t = typ</string>
+  <string name="preferences_custom_product_search_title">Vlastné vyhľadávanie URL</string>
+  <string name="preferences_decode_1D_industrial_title">1D priemyselné</string>
+  <string name="preferences_decode_1D_product_title">1D tovar</string>
+  <string name="preferences_decode_Aztec_title">Aztécky</string>
+  <string name="preferences_decode_Data_Matrix_title">Dáta Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR kódy</string>
+  <string name="preferences_device_bug_workarounds_title">Možné chyby zariadenia</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Bez scénického režimu čiarového kódu</string>
+  <string name="preferences_disable_continuous_focus_summary">Použiť iba štandardné zaostrenie.</string>
+  <string name="preferences_disable_continuous_focus_title">Bez nepretržitého zaostrovania</string>
+  <string name="preferences_disable_exposure_title">Bez expozície</string>
+  <string name="preferences_disable_metering_title">Bez úpravy jasu</string>
+  <string name="preferences_front_light_auto">Automatický</string>
+  <string name="preferences_front_light_off">Neaktívne</string>
+  <string name="preferences_front_light_on">Aktívne</string>
+  <string name="preferences_front_light_summary">Použiť prisvetlenie</string>
+  <string name="preferences_front_light_title">Použiť predné svetlo</string>
+  <string name="preferences_general_title">Všeobecné nastavenia</string>
+  <string name="preferences_history_summary">Uložte si skeny v histórii</string>
+  <string name="preferences_history_title">Pridať do dejín</string>
+  <string name="preferences_invert_scan_summary">Skenovať biele čiarové kódy na čiernom pozadí. Nie je k dispozícii na všetkých zariadeniach.</string>
+  <string name="preferences_invert_scan_title">Invertované skenovanie</string>
+  <string name="preferences_name">Nastavenia</string>
+  <string name="preferences_orientation_title">Neotáčať automaticky</string>
+  <string name="preferences_play_beep_title">Zvuková signalizácia</string>
+  <string name="preferences_remember_duplicates_summary">Uložiť viacnásobné skenovanie do jednej histórie čiarového kódu</string>
+  <string name="preferences_remember_duplicates_title">Zapamätať si duplikáty</string>
+  <string name="preferences_result_title">Nastavenia výsledku</string>
+  <string name="preferences_scanning_title">Dekódovať čiarové kódy</string>
+  <string name="preferences_search_country">Vyhľadávať v krajine</string>
+  <string name="preferences_supplemental_summary">Skúsiť získať viac informácií o obsahu čiarového kódu</string>
+  <string name="preferences_supplemental_title">Získať viac informácií</string>
+  <string name="preferences_vibrate_title">Vibrovať</string>
+  <string name="result_address_book">Nájdená informácia o kontakte</string>
+  <string name="result_calendar">Nájdená udalosť kalendára</string>
+  <string name="result_email_address">Nájdená e-mailová adresa</string>
+  <string name="result_geo">Nájdená zemepisná súradnica</string>
+  <string name="result_isbn">Nájdená kniha</string>
+  <string name="result_product">Nájdený tovar</string>
+  <string name="result_sms">Nájdená SMS adresa</string>
+  <string name="result_tel">Nájdené telefónne číslo</string>
+  <string name="result_text">Nájdený obyčajný text</string>
+  <string name="result_uri">Nájdená URL</string>
+  <string name="result_wifi">Nájdená konfigurácia WLAN</string>
+  <string name="sbc_name">Vyhľadať v Google Knihy</string>
+  <string name="wifi_changing_network">Požiadavka na pripojenie k sieti\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-sl/strings.xml b/BarCodeScanner/mobile/src/main/res/values-sl/strings.xml
new file mode 100644 (file)
index 0000000..09f4bc0
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Aplikacije</string>
+  <string name="bookmark_picker_name">Zaznamki</string>
+  <string name="button_add_calendar">Dodaj v koledar</string>
+  <string name="button_add_contact">Dodaj kontakt</string>
+  <string name="button_book_search">Išči knjigo</string>
+  <string name="button_cancel">Prekliči</string>
+  <string name="button_custom_product_search">Iskanje po meri</string>
+  <string name="button_dial">Pokliči številko</string>
+  <string name="button_email">Pošlji e-mail</string>
+  <string name="button_get_directions">Dobi smer</string>
+  <string name="button_mms">Pošlji MMS</string>
+  <string name="button_ok">V redu</string>
+  <string name="button_open_browser">Odpri brskalnik</string>
+  <string name="button_product_search">Iskanje po izdelkih</string>
+  <string name="button_search_book_contents">Išči vsebino</string>
+  <string name="button_share_app">Aplikacija</string>
+  <string name="button_share_bookmark">Zaznamek</string>
+  <string name="button_share_by_email">Deli preko e-maila</string>
+  <string name="button_share_by_sms">Deli preko SMS</string>
+  <string name="button_share_clipboard">Odložišče</string>
+  <string name="button_share_contact">Kontakt</string>
+  <string name="button_show_map">Pokaži zemljevid</string>
+  <string name="button_sms">Pošlji SMS</string>
+  <string name="button_web_search">Spletno iskanje</string>
+  <string name="button_wifi">Poveži se na omrežje</string>
+  <string name="contents_contact">Informacije o kontaktu</string>
+  <string name="contents_email">E-naslov</string>
+  <string name="contents_location">Geografske koordinate</string>
+  <string name="contents_phone">Telefonska številka</string>
+  <string name="contents_sms">SMS naslov</string>
+  <string name="contents_text">Tekst</string>
+  <string name="history_clear_one_history_text">Pobriši</string>
+  <string name="history_clear_text">Pobriši zgodovino</string>
+  <string name="history_email_title">Barcode Scanner zgodovina</string>
+  <string name="history_empty">Prazne</string>
+  <string name="history_empty_detail">Št črtne kode scans so bile zabeležene</string>
+  <string name="history_send">Pošlji zgodovino</string>
+  <string name="history_title">Zgodovina</string>
+  <string name="menu_encode_mecard">Uporaba MECARD</string>
+  <string name="menu_encode_vcard">Uporaba vCard</string>
+  <string name="menu_help">Pomoč</string>
+  <string name="menu_history">Zgodovina</string>
+  <string name="menu_settings">Nastavitve</string>
+  <string name="menu_share">Deli</string>
+  <string name="msg_bulk_mode_scanned">Slikanje na debelo: črtna koda prebrana in shranjena</string>
+  <string name="msg_camera_framework_bug">Oprostite, Android kamera je naletela na težave. Mogoče boste morali ponovno zagnati napravo.</string>
+  <string name="msg_default_format">Format</string>
+  <string name="msg_default_meta">Metapodatki</string>
+  <string name="msg_default_mms_subject">Živjo</string>
+  <string name="msg_default_status">Za branje postavite črtno kodo znotraj iskala.</string>
+  <string name="msg_default_time">Čas</string>
+  <string name="msg_default_type">Tip</string>
+  <string name="msg_encode_contents_failed">Ni bilo mogoče narediti črtne kode iz podanih podatkov</string>
+  <string name="msg_error">Napaka</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Oprostite, zahtevana aplikacija se ne more zagnati. Lahko da gre za napačno vsebino črtne kode.</string>
+  <string name="msg_invalid_value">Neveljavna vrednost</string>
+  <string name="msg_redirect">Preusmeritev</string>
+  <string name="msg_sbc_book_not_searchable">Oprostite, po tej knjigi se ne da iskati.</string>
+  <string name="msg_sbc_failed">Oprostite, iskanje je naletelo na napako.</string>
+  <string name="msg_sbc_no_page_returned">Brez vrnjene strani.</string>
+  <string name="msg_sbc_page">Stran</string>
+  <string name="msg_sbc_results">Rezultati</string>
+  <string name="msg_sbc_searching_book">Iščem knjigo\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Košček ni na voljo</string>
+  <string name="msg_share_explanation">Lahko delite podatke s prikazom črtne kode na vašem zaslonu in branju le-te z drugim mobilnim telefonom.</string>
+  <string name="msg_share_text">Ali vnesite nekaj besedila</string>
+  <string name="msg_sure">Ali ste prepričani?</string>
+  <string name="msg_unmount_usb">Oprostite, do SD kartice ni možno dostopati</string>
+  <string name="preferences_actions_title">Ko je črtna koda najdena\u2026</string>
+  <string name="preferences_auto_focus_title">Uporabite samodejno ostrenje</string>
+  <string name="preferences_auto_open_web_title">Odpiranje spletnih strani samodejno</string>
+  <string name="preferences_bulk_mode_summary">Beri in shrani več črtnih kod zaporedoma</string>
+  <string name="preferences_bulk_mode_title">Branje črtnih kod na debelo</string>
+  <string name="preferences_copy_to_clipboard_title">Kopiraj v beležnico</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Zamenjave: %s = vsebin, %f = format, %t = vrsta</string>
+  <string name="preferences_custom_product_search_title">URL za iskanje po meri</string>
+  <string name="preferences_decode_1D_industrial_title">1D industrial</string>
+  <string name="preferences_decode_1D_product_title">1D izdelka</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR kodo</string>
+  <string name="preferences_device_bug_workarounds_title">Naprava Bug Rešitve</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Št črtne kode scenski način</string>
+  <string name="preferences_disable_continuous_focus_summary">Uporabljajte samo standardni način ostrenja</string>
+  <string name="preferences_disable_continuous_focus_title">Št stalna osredotočenost</string>
+  <string name="preferences_disable_exposure_title">Nobena izpostavljenost</string>
+  <string name="preferences_disable_metering_title">Št merjenje</string>
+  <string name="preferences_front_light_auto">Samodejno</string>
+  <string name="preferences_front_light_off">Neaktivno</string>
+  <string name="preferences_front_light_on">Aktivna</string>
+  <string name="preferences_front_light_summary">Izboljša branje pri slabi svetlobi na nekaterih telefonih, a lahko povzroči blesk. Ne deluje na vseh telefonih.</string>
+  <string name="preferences_front_light_title">Uporabite sprednjo luč</string>
+  <string name="preferences_general_title">Splošne nastavitve</string>
+  <string name="preferences_history_summary">Shranjevanje skeniranih dokumentov v zgodovini</string>
+  <string name="preferences_history_title">Dodaj v zgodovino</string>
+  <string name="preferences_invert_scan_summary">Scan za beli črtne kode na črni podlagi. Ni na voljo na nekaterih napravah.</string>
+  <string name="preferences_invert_scan_title">Obrni skeniranje</string>
+  <string name="preferences_name">Nastavitve</string>
+  <string name="preferences_orientation_title">Št avtomatsko rotacijo</string>
+  <string name="preferences_play_beep_title">Pisk</string>
+  <string name="preferences_remember_duplicates_summary">Shranjevanje več skandiranje iste črtne kode v zgodovini</string>
+  <string name="preferences_remember_duplicates_title">Zapomni si dvojnikov</string>
+  <string name="preferences_result_title">Nastavitve rezultatov branja</string>
+  <string name="preferences_scanning_title">Ko berete črtne kode, preberi\u2026</string>
+  <string name="preferences_search_country">Išči po državi</string>
+  <string name="preferences_supplemental_summary">Poskusite pridobiti več informacij o vsebini črtne kode</string>
+  <string name="preferences_supplemental_title">Naloži Več info</string>
+  <string name="preferences_vibrate_title">Vibriraj</string>
+  <string name="result_address_book">Najdene informacije o kontaktu</string>
+  <string name="result_calendar">Najden koledarski dogodek</string>
+  <string name="result_email_address">Najden e-naslov</string>
+  <string name="result_geo">Najdene geografske koordinate</string>
+  <string name="result_isbn">Najdena knjiga</string>
+  <string name="result_product">Najden produkt</string>
+  <string name="result_sms">Najden SMS naslov</string>
+  <string name="result_tel">Najdena telefonska številka</string>
+  <string name="result_text">Najden tekst</string>
+  <string name="result_uri">Najden URL</string>
+  <string name="result_wifi">Najdene WLAN nastavitve</string>
+  <string name="sbc_name">Iskanje z Google Book Search</string>
+  <string name="wifi_changing_network">Zahteva priključitev na omrežje\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-sv/strings.xml b/BarCodeScanner/mobile/src/main/res/values-sv/strings.xml
new file mode 100644 (file)
index 0000000..492eca2
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Applikationer</string>
+  <string name="bookmark_picker_name">Bokmärken</string>
+  <string name="button_add_calendar">Lägg till i kalender</string>
+  <string name="button_add_contact">Lägg till kontakt</string>
+  <string name="button_book_search">Boksökning</string>
+  <string name="button_cancel">Avbryt</string>
+  <string name="button_custom_product_search">Anpassad sökning</string>
+  <string name="button_dial">Slå nummer</string>
+  <string name="button_email">Skicka e-post</string>
+  <string name="button_get_directions">Få anvisningar</string>
+  <string name="button_mms">Skicka MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Öppna webbläsare</string>
+  <string name="button_product_search">Produktsök</string>
+  <string name="button_search_book_contents">Sökinnehåll</string>
+  <string name="button_share_app">Applikation</string>
+  <string name="button_share_bookmark">Bokmärke</string>
+  <string name="button_share_by_email">Dela via e-post</string>
+  <string name="button_share_by_sms">Dela via SMS</string>
+  <string name="button_share_clipboard">Klippbord</string>
+  <string name="button_share_contact">Kontakt</string>
+  <string name="button_show_map">Visa karta</string>
+  <string name="button_sms">Skicka SMS</string>
+  <string name="button_web_search">Webbsök</string>
+  <string name="button_wifi">Anslut till nätverk</string>
+  <string name="contents_contact">Kontaktinfo</string>
+  <string name="contents_email">E-postadress</string>
+  <string name="contents_location">Geografiska koordinater</string>
+  <string name="contents_phone">Telefonnummer</string>
+  <string name="contents_sms">SMS-adress</string>
+  <string name="contents_text">Vanlig text</string>
+  <string name="history_clear_one_history_text">Rensa</string>
+  <string name="history_clear_text">Rensa historik</string>
+  <string name="history_email_title">Historik inskannade streckkoder</string>
+  <string name="history_empty">Tom</string>
+  <string name="history_empty_detail">Inga inskannade streckkoder har registrerats</string>
+  <string name="history_send">Skicka historik</string>
+  <string name="history_title">Historik</string>
+  <string name="menu_encode_mecard">Använd MECARD</string>
+  <string name="menu_encode_vcard">Använd vCard</string>
+  <string name="menu_help">Hjälp</string>
+  <string name="menu_history">Historik</string>
+  <string name="menu_settings">Inställningar</string>
+  <string name="menu_share">Dela</string>
+  <string name="msg_bulk_mode_scanned">Bulk-läge: streckkod har inskannats och sparats</string>
+  <string name="msg_camera_framework_bug">Det uppstod tyvärr ett fel med Androidkameran.</string>
+  <string name="msg_default_format">Format</string>
+  <string name="msg_default_meta">Metadata</string>
+  <string name="msg_default_mms_subject">Hej</string>
+  <string name="msg_default_status">Placera steckkoden inom sökarens rektangel för att läsa den.</string>
+  <string name="msg_default_time">Tid</string>
+  <string name="msg_default_type">Typ</string>
+  <string name="msg_encode_contents_failed">Det gick inte att avkoda en streckkod från den erhållna informationen.</string>
+  <string name="msg_error">Fel</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Den begärda applikationen kunde tyvärr inte startas. Streckkodens innehåll kan vara ogiltigt.</string>
+  <string name="msg_invalid_value">Ogiltigt värde</string>
+  <string name="msg_redirect">Omdirigering</string>
+  <string name="msg_sbc_book_not_searchable">Den här boken är tyvärr inte sökbar.</string>
+  <string name="msg_sbc_failed">Det uppstod tyvärr ett fel vid sökning. </string>
+  <string name="msg_sbc_no_page_returned">Ingen sida funnen</string>
+  <string name="msg_sbc_page">Sida</string>
+  <string name="msg_sbc_results">Resultat</string>
+  <string name="msg_sbc_searching_book">Söker bok\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Utdrag ej tillgängligt</string>
+  <string name="msg_share_explanation">Du kan dela information genom att visa en streckkod på din skärm och sedan skanna in den med en annan telefon.</string>
+  <string name="msg_share_text">Eller skriv in text och tryck Enter</string>
+  <string name="msg_sure">Är du säker?</string>
+  <string name="msg_unmount_usb">SD-kortet är tyvärr inte tillgängligt.</string>
+  <string name="preferences_actions_title">När en streckkod hittas\u2026</string>
+  <string name="preferences_auto_focus_title">Använd autofokus</string>
+  <string name="preferences_auto_open_web_title">Öppna webbsidor automatiskt</string>
+  <string name="preferences_bulk_mode_summary">Skanna och spara flera streckkoder samtidigt</string>
+  <string name="preferences_bulk_mode_title">Bulk-inskanningläge</string>
+  <string name="preferences_copy_to_clipboard_title">Kopiera till urklipp</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Ersättningar: %s = innehåll, %f = format, %t = typ</string>
+  <string name="preferences_custom_product_search_title">Anpassad sökning URL</string>
+  <string name="preferences_decode_1D_industrial_title">1D Industriell</string>
+  <string name="preferences_decode_1D_product_title">1D Produkt</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR Code</string>
+  <string name="preferences_device_bug_workarounds_title">Bugglösningar för enhet</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Inget scenläge för streckkod</string>
+  <string name="preferences_disable_continuous_focus_summary">Använd endast standardfokusläge</string>
+  <string name="preferences_disable_continuous_focus_title">Ingen kontinuerlig fokus</string>
+  <string name="preferences_disable_exposure_title">Ingen exponering</string>
+  <string name="preferences_disable_metering_title">Ingen mätning</string>
+  <string name="preferences_front_light_auto">Automatisk</string>
+  <string name="preferences_front_light_off">Inaktiv</string>
+  <string name="preferences_front_light_on">Aktiv</string>
+  <string name="preferences_front_light_summary">Förbättrar inskanning i svag belysing på vissa telefoner, men kan orsaka bländning. Ej tillgängligt på vissa enheter.</string>
+  <string name="preferences_front_light_title">Använd frontljus</string>
+  <string name="preferences_general_title">Grundläggande inställningar</string>
+  <string name="preferences_history_summary">Lagra dina skanningar i historia</string>
+  <string name="preferences_history_title">Lägg till Historia</string>
+  <string name="preferences_invert_scan_summary">Skanna in vita streckkoder mot svart bakgrund. Ej tillgängligt på vissa enheter. </string>
+  <string name="preferences_invert_scan_title">Invertera inskanning</string>
+  <string name="preferences_name">Inställningar</string>
+  <string name="preferences_orientation_title">Ingen automatisk rotering</string>
+  <string name="preferences_play_beep_title">Ton</string>
+  <string name="preferences_remember_duplicates_summary">Lagra flera inskanningar av samma streckkod i historik</string>
+  <string name="preferences_remember_duplicates_title">Kom ihåg dubletter</string>
+  <string name="preferences_result_title">Resultatinställningar</string>
+  <string name="preferences_scanning_title">När du skannar in streckkoder, avkoda\u2026</string>
+  <string name="preferences_search_country">Sök land</string>
+  <string name="preferences_supplemental_summary">Försök hämta mer information om streckkodens innehåll</string>
+  <string name="preferences_supplemental_title">Hämta mer info</string>
+  <string name="preferences_vibrate_title">Vibrera</string>
+  <string name="result_address_book">Hittade kontaktinformation</string>
+  <string name="result_calendar">Hittade kalenderhändelser</string>
+  <string name="result_email_address">Hittade e-postadress</string>
+  <string name="result_geo">Hittade geografiska koordinater</string>
+  <string name="result_isbn">Hittade bok</string>
+  <string name="result_product">Hittade produkt</string>
+  <string name="result_sms">Hittade SMS-adress</string>
+  <string name="result_tel">Hittade telefonnummer</string>
+  <string name="result_text">Hittade vanlig text</string>
+  <string name="result_uri">Hittade URL</string>
+  <string name="result_wifi">Hittade WLAN-konfiguration</string>
+  <string name="sbc_name">Google Book Search</string>
+  <string name="wifi_changing_network">Begär anslutning till nätverk\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-th/strings.xml b/BarCodeScanner/mobile/src/main/res/values-th/strings.xml
new file mode 100644 (file)
index 0000000..8ba5a26
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">แอพพลิเคชั่น</string>
+  <string name="bookmark_picker_name">บุ๊คมาร์ก</string>
+  <string name="button_add_calendar">เพิ่มไปยังปฏิทิน</string>
+  <string name="button_add_contact">เพิ่มผู้ติดต่อ</string>
+  <string name="button_book_search">ค้นหาหนังสือ</string>
+  <string name="button_cancel">ยกเลิก</string>
+  <string name="button_custom_product_search">ค้นหาแบบกำหนดเอง</string>
+  <string name="button_dial">เรียกเลขหมาย</string>
+  <string name="button_email">ส่งอีเมล</string>
+  <string name="button_get_directions">รับข้อมูลเส้นทาง</string>
+  <string name="button_mms">ส่ง MMS</string>
+  <string name="button_ok">ตกลง</string>
+  <string name="button_open_browser">เปิดเบราว์เซอร์</string>
+  <string name="button_product_search">ค้นหาสินค้า</string>
+  <string name="button_search_book_contents">ค้นหาเนื้อหา</string>
+  <string name="button_share_app">แอพพลิเคชั่น</string>
+  <string name="button_share_bookmark">บุ๊คมาร์ก</string>
+  <string name="button_share_by_email">แบ่งปันผ่านอีเมล</string>
+  <string name="button_share_by_sms">แบ่งปันผ่าน SMS</string>
+  <string name="button_share_clipboard">คลิปบอร์ด</string>
+  <string name="button_share_contact">ผู้ติดต่อ</string>
+  <string name="button_show_map">แสดงแผนที่</string>
+  <string name="button_sms">ส่ง SMS</string>
+  <string name="button_web_search">ค้นหาเว็บ</string>
+  <string name="button_wifi">เชื่อมต่อกับเครือข่าย</string>
+  <string name="contents_contact">ข้อมูลผู้ติดต่อ</string>
+  <string name="contents_email">ที่อยู่อีเมล</string>
+  <string name="contents_location">พิกัดทางภูมิศาสตร์</string>
+  <string name="contents_phone">เบอร์โทรศัพท์</string>
+  <string name="contents_sms">ที่อยู่ SMS</string>
+  <string name="contents_text">ข้อความธรรมดา</string>
+  <string name="history_clear_one_history_text">ล้าง</string>
+  <string name="history_clear_text">ล้างประวัติ</string>
+  <string name="history_email_title">ประวัติ Barcode Scanner</string>
+  <string name="history_empty">ว่าง</string>
+  <string name="history_empty_detail">ไม่มีบาร์โค้ดที่ถูกบันทึกไว้</string>
+  <string name="history_send">ส่งประวัติ</string>
+  <string name="history_title">ประวัติ</string>
+  <string name="menu_encode_mecard">ใช้ MECARD</string>
+  <string name="menu_encode_vcard">ใช้ vCard</string>
+  <string name="menu_help">ช่วยเหลือ</string>
+  <string name="menu_history">ประวัติ</string>
+  <string name="menu_settings">การตั้งค่า</string>
+  <string name="menu_share">แบ่งปัน</string>
+  <string name="msg_bulk_mode_scanned">โหมดเป็นกลุ่ม: บาร์โค้ดที่สแกนและบันทึกไว้</string>
+  <string name="msg_camera_framework_bug">ขออภัย พบปัญหาของกล้อง Android คุณอาจจะต้องรีสตาร์ทอุปกรณ์</string>
+  <string name="msg_default_format">รูปแบบ</string>
+  <string name="msg_default_meta">ข้อมูลเมตา</string>
+  <string name="msg_default_mms_subject">สวัสดี</string>
+  <string name="msg_default_status">วางบาร์โค้ดภายในสี่เหลี่ยมผืนผ้าที่ช่องมองภาพเพื่อสแกน</string>
+  <string name="msg_default_time">เวลา</string>
+  <string name="msg_default_type">ชนิด</string>
+  <string name="msg_encode_contents_failed">ไม่สามารถเข้ารหัสบาร์โค้ดจากข้อมูลที่มี</string>
+  <string name="msg_error">ข้อผิดพลาด</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">ขออภัย แอพพลิเคชั่นที่ร้องขอไม่สามารถเปิดใช้ได้ เนื้อหาบาร์โค้ดอาจจะไม่ถูกต้อง</string>
+  <string name="msg_invalid_value">ค่าไม่ถูกต้อง</string>
+  <string name="msg_redirect">เปลี่ยนเส้นทาง</string>
+  <string name="msg_sbc_book_not_searchable">ขออภัย ไม่สามารถค้นหาหนังสือเล่มนี้ได้</string>
+  <string name="msg_sbc_failed">ขออภัย พบปัญหาในการค้นหา</string>
+  <string name="msg_sbc_no_page_returned">ไม่มีหน้าที่ส่งกลับมา</string>
+  <string name="msg_sbc_page">หน้า</string>
+  <string name="msg_sbc_results">ผลลัพธ์</string>
+  <string name="msg_sbc_searching_book">กำลังค้นหาหนังสือ\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">ส่วนย่อยไม่สามารถใช้ได้</string>
+  <string name="msg_share_explanation">คุณสามารถแบ่งปันข้อมูลโดยการแสดงบาร์โค้ดบนหน้าจอของคุณและสแกนด้วยโทรศัพท์อื่น</string>
+  <string name="msg_share_text">หรือพิมพ์ข้อความบางอย่างและกด Enter</string>
+  <string name="msg_sure">คุณแน่ใจหรือไม่?</string>
+  <string name="msg_unmount_usb">ขออภัย ไม่สามารถเข้าถึง SD การ์ดได้</string>
+  <string name="preferences_actions_title">เมื่อพบบาร์โค้ด\u2026</string>
+  <string name="preferences_auto_focus_title">ใช้ระบบโฟกัสอัตโนมัติ</string>
+  <string name="preferences_auto_open_web_title">เปิดหน้าเว็บโดยอัตโนมัติ</string>
+  <string name="preferences_bulk_mode_summary">สแกนและบันทึกบาร์โค้ดเป็นจำนวนมากอย่างต่อเนื่อง</string>
+  <string name="preferences_bulk_mode_title">โหมดการสแกนเป็นกลุ่ม</string>
+  <string name="preferences_copy_to_clipboard_title">คัดลอกไปยังคลิปบอร์ด</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">การแทนที่: %s = เนื้อหา, %f = รูปแบบ, %t = ชนิด</string>
+  <string name="preferences_custom_product_search_title">ค้นหาตาม URL ที่กำหนดเอง</string>
+  <string name="preferences_decode_1D_industrial_title">1D อุตสาหกรรม</string>
+  <string name="preferences_decode_1D_product_title">1D สินค้า</string>
+  <string name="preferences_decode_Aztec_title">แอซเท็ก</string>
+  <string name="preferences_decode_Data_Matrix_title">ข้อมูลเมทริกซ์</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">คิวอาร์โค้ด</string>
+  <string name="preferences_device_bug_workarounds_title">วิธีการแก้ปัญหาจุดบกพร่องของอุปกรณ์</string>
+  <string name="preferences_disable_barcode_scene_mode_title">ไม่มีโหมดฉากบาร์โค้ด</string>
+  <string name="preferences_disable_continuous_focus_summary">ใช้โหมดโฟกัสมาตรฐานเท่านั้น</string>
+  <string name="preferences_disable_continuous_focus_title">ไม่มีการโฟกัสอย่างต่อเนื่อง</string>
+  <string name="preferences_disable_exposure_title">ไม่มีการการเปิดรับแสง</string>
+  <string name="preferences_disable_metering_title">ไม่มีการวัดแสง</string>
+  <string name="preferences_front_light_auto">อัตโนมัติ</string>
+  <string name="preferences_front_light_off">ปิด</string>
+  <string name="preferences_front_light_on">เปิด</string>
+  <string name="preferences_front_light_summary">ปรับปรุงการสแกนในที่มีแสงน้อยบนโทรศัพท์บางรุ่น แต่อาจก่อให้เกิดแสงจ้า ไม่ได้ทำงานบนโทรศัพท์ทุกรุ่น</string>
+  <string name="preferences_front_light_title">ใช้แฟลช</string>
+  <string name="preferences_general_title">การตั้งค่าทั่วไป</string>
+  <string name="preferences_history_summary">เก็บภาพสแกนในประวัติศาสตร์</string>
+  <string name="preferences_history_title">เพิ่มลงในประวัติศาสตร์</string>
+  <string name="preferences_invert_scan_summary">สแกนบาร์โค้ดสีขาวบนพื้นหลังสีดำ ไม่สามารถใช้ได้บนบางอุปกรณ์</string>
+  <string name="preferences_invert_scan_title">สลับการสแกน</string>
+  <string name="preferences_name">การตั้งค่า</string>
+  <string name="preferences_orientation_title">ไม่มีการหมุนอัตโนมัติ</string>
+  <string name="preferences_play_beep_title">เสียงเตือน</string>
+  <string name="preferences_remember_duplicates_summary">จัดเก็บการสแกนบาร์โค้ดที่เหมือนกันหลายครั้งในประวัติ</string>
+  <string name="preferences_remember_duplicates_title">จดจำรายการที่ซ้ำกัน</string>
+  <string name="preferences_result_title">ผลการตั้งค่า</string>
+  <string name="preferences_scanning_title">เมื่อสแกนหาบาร์โค้ด, ถอดรหัส\u2026</string>
+  <string name="preferences_search_country">ประเทศที่ค้นหา</string>
+  <string name="preferences_supplemental_summary">พยายามที่จะเรียกข้อมูลเพิ่มเติมเกี่ยวกับเนื้อหาของบาร์โค้ด</string>
+  <string name="preferences_supplemental_title">เรียกข้อมูลเพิ่มเติม</string>
+  <string name="preferences_vibrate_title">การสั่น</string>
+  <string name="result_address_book">พบข้อมูลผู้ติดต่อ</string>
+  <string name="result_calendar">พบเหตุการณ์ในปฏิทิน</string>
+  <string name="result_email_address">พบที่อยู่อีเมล</string>
+  <string name="result_geo">พบพิกัดทางภูมิศาสตร์</string>
+  <string name="result_isbn">พบหนังสือ</string>
+  <string name="result_product">พบสินค้า</string>
+  <string name="result_sms">พบที่อยู่ SMS</string>
+  <string name="result_tel">พบเบอร์โทรศัพท์</string>
+  <string name="result_text">พบข้อความธรรมดา</string>
+  <string name="result_uri">พบ URL</string>
+  <string name="result_wifi">พบการกำหนดค่า WLAN</string>
+  <string name="sbc_name">ค้นหาหนังสือจาก Google</string>
+  <string name="wifi_changing_network">กำลังร้องขอการเชื่อมต่อกับเครือข่าย\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-tr/strings.xml b/BarCodeScanner/mobile/src/main/res/values-tr/strings.xml
new file mode 100644 (file)
index 0000000..dc40026
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barkod Tarayıcısı</string>
+  <string name="app_picker_name">Uygulamalar</string>
+  <string name="bookmark_picker_name">Yer imleri</string>
+  <string name="button_add_calendar">Takvime ekle</string>
+  <string name="button_add_contact">Kişi ekle</string>
+  <string name="button_book_search">Kitap Arama</string>
+  <string name="button_cancel">İptal</string>
+  <string name="button_custom_product_search">Özel arama</string>
+  <string name="button_dial">Numaraya çağrı</string>
+  <string name="button_email">Email gönder</string>
+  <string name="button_get_directions">Yön bilgisi al</string>
+  <string name="button_mms">MMS gönder</string>
+  <string name="button_ok">Tamam</string>
+  <string name="button_open_browser">Tarayıcıyı aç</string>
+  <string name="button_product_search">Ürün arama</string>
+  <string name="button_search_book_contents">İçerik arama</string>
+  <string name="button_share_app">Uygulama paylaş</string>
+  <string name="button_share_bookmark">Yer imi paylaş</string>
+  <string name="button_share_by_email">Email ile paylaş</string>
+  <string name="button_share_by_sms">SMS ile paylaş</string>
+  <string name="button_share_clipboard">Pano</string>
+  <string name="button_share_contact">Kişi</string>
+  <string name="button_show_map">Haritayı göster</string>
+  <string name="button_sms">SMS gönder</string>
+  <string name="button_web_search">Webde ara</string>
+  <string name="button_wifi">Ağa bağlan</string>
+  <string name="contents_contact">Kişi bilgisi</string>
+  <string name="contents_email">Email adresi</string>
+  <string name="contents_location">Coğrafi koordinatlar</string>
+  <string name="contents_phone">Telefon numarası</string>
+  <string name="contents_sms">SMS adresi</string>
+  <string name="contents_text">Düz metin</string>
+  <string name="history_clear_one_history_text">Temizle</string>
+  <string name="history_clear_text">Geçmişi temizle</string>
+  <string name="history_email_title">Barkod Tarayıcı geçmişi</string>
+  <string name="history_empty">Boş</string>
+  <string name="history_empty_detail">Yok barkod taramaları kaydedildi</string>
+  <string name="history_send">Geçmişi gönder</string>
+  <string name="history_title">Geçmiş</string>
+  <string name="menu_encode_mecard">MECARD kullanın</string>
+  <string name="menu_encode_vcard">VCard kullanın</string>
+  <string name="menu_help">Yardım</string>
+  <string name="menu_history">Geçmiş</string>
+  <string name="menu_settings">Ayarlar</string>
+  <string name="menu_share">Paylaş</string>
+  <string name="msg_bulk_mode_scanned">Toplu modu: taranan ve kaydedilen barkodlar</string>
+  <string name="msg_camera_framework_bug">Üzgünüz, Android kamera bir sorunla karşılaştı. Cihazı yeniden başlatmanız gerekebilir.</string>
+  <string name="msg_default_format">Biçim</string>
+  <string name="msg_default_meta">Metadata</string>
+  <string name="msg_default_mms_subject">Merhaba</string>
+  <string name="msg_default_status">Barkodu taramak için vizördeki dikdörtgenin içerisine yerleştirin.</string>
+  <string name="msg_default_time">Süre</string>
+  <string name="msg_default_type">Tür</string>
+  <string name="msg_encode_contents_failed">Sağlanan verilerden bir barkod kodlanamadı.</string>
+  <string name="msg_error">Hata</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Üzgünüz, istenen uygulama başlatılamadı. Barkod içeriği geçersiz olabilir.</string>
+  <string name="msg_invalid_value">Geçersiz değer</string>
+  <string name="msg_redirect">Yönlendirme</string>
+  <string name="msg_sbc_book_not_searchable">Üzgünüz, bu kitapla ilgili arama yapılamıyor.</string>
+  <string name="msg_sbc_failed">Üzgünüz, arama esnasında bir sorun oluştu.</string>
+  <string name="msg_sbc_no_page_returned">Dönen sayfa yok</string>
+  <string name="msg_sbc_page">Sayfa</string>
+  <string name="msg_sbc_results">Sonuçlar</string>
+  <string name="msg_sbc_searching_book">Kitap aranıyor\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Parçacık yok</string>
+  <string name="msg_share_explanation">Ekranınızda görüntülediğiniz barkodu başka bir telefonla tarayarak veri paylaşabilirsiniz.</string>
+  <string name="msg_share_text">Veya yazın bazı metin</string>
+  <string name="msg_sure">Emin misin?</string>
+  <string name="msg_unmount_usb">Lütfen USB depolamayı devre dışı bırakın.</string>
+  <string name="preferences_actions_title">Bir barkod bulunduğu zaman\u2026</string>
+  <string name="preferences_auto_focus_title">Otomatik odaklama kullanın</string>
+  <string name="preferences_auto_open_web_title">Otomatik olarak web sayfaları açın</string>
+  <string name="preferences_bulk_mode_summary">Birden fazla barkodu toplu olarak taramak ve kaydetmek için</string>
+  <string name="preferences_bulk_mode_title">Toplu tarama modu</string>
+  <string name="preferences_copy_to_clipboard_title">Panoya kopyala</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Yerine Koyma: %s = içeriği, %f = biçim, %t = tip</string>
+  <string name="preferences_custom_product_search_title">Özel arama adresi</string>
+  <string name="preferences_decode_1D_industrial_title">1D Sanayi</string>
+  <string name="preferences_decode_1D_product_title">1D Ürün</string>
+  <string name="preferences_decode_Aztec_title">Aztek</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR barkodları</string>
+  <string name="preferences_device_bug_workarounds_title">Cihaz Hata Geçici Çözümler</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Hayır barkod sahne modu</string>
+  <string name="preferences_disable_continuous_focus_summary">Sadece standart odaklama modunu kullanın</string>
+  <string name="preferences_disable_continuous_focus_title">Hayır sürekli odak</string>
+  <string name="preferences_disable_exposure_title">Maruziyet</string>
+  <string name="preferences_disable_metering_title">Hiçbir ölçüm</string>
+  <string name="preferences_front_light_auto">Otomatik</string>
+  <string name="preferences_front_light_off">Atıl</string>
+  <string name="preferences_front_light_on">Aktif</string>
+  <string name="preferences_front_light_summary">Bazı telefonlarda düşük ışıkta taramayı iyileştirir, ancak parlamaya neden olabilir. Tüm telefonlarda sonuç vermez.</string>
+  <string name="preferences_front_light_title">Ön ışığı kullan</string>
+  <string name="preferences_general_title">Genel ayarlar</string>
+  <string name="preferences_history_summary">Tarih içinde taramaları saklayın</string>
+  <string name="preferences_history_title">Tarih ekle</string>
+  <string name="preferences_invert_scan_summary">Siyah zemin üzerine beyaz barkod tarama. Bazı cihazlar mevcut değildir.</string>
+  <string name="preferences_invert_scan_title">Tarama haricindekileri</string>
+  <string name="preferences_name">Ayarlar</string>
+  <string name="preferences_orientation_title">Otomatik rotasyon yok</string>
+  <string name="preferences_play_beep_title">Bip</string>
+  <string name="preferences_remember_duplicates_summary">Aynı barkoda ait farklı taramaları kayıtlarda depola</string>
+  <string name="preferences_remember_duplicates_title">Aynı barkodları hatırla</string>
+  <string name="preferences_result_title">Sonuç ayarları</string>
+  <string name="preferences_scanning_title">Barkodlar taraması \u2026</string>
+  <string name="preferences_search_country">Arama Ülke</string>
+  <string name="preferences_supplemental_summary">Barkod içeriği hakkında daha fazla bilgi almayı dene</string>
+  <string name="preferences_supplemental_title">Daha fazla bilgi </string>
+  <string name="preferences_vibrate_title">Titreşim </string>
+  <string name="result_address_book">Bulunan kişi bilgisi</string>
+  <string name="result_calendar">Bulunan takvim etkinliği</string>
+  <string name="result_email_address">Bulunan Email adresi</string>
+  <string name="result_geo">Bulunan coğrafi koordinatlar</string>
+  <string name="result_isbn">Bulunan kitap</string>
+  <string name="result_product">Bulunan ürün</string>
+  <string name="result_sms">Bulunan SMS adresi</string>
+  <string name="result_tel">Bulunan telefon numarası</string>
+  <string name="result_text">Bulunan düz metin</string>
+  <string name="result_uri">Bulunan URL</string>
+  <string name="result_wifi">Bulunan Wi-Fi konfigürasyonu</string>
+  <string name="sbc_name">Google Kitap Arama</string>
+  <string name="wifi_changing_network">Ağa bir bağlantı isteğinde\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-uk/strings.xml b/BarCodeScanner/mobile/src/main/res/values-uk/strings.xml
new file mode 100644 (file)
index 0000000..0113377
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Сканер штрих-кодів</string>
+  <string name="app_picker_name">Програми</string>
+  <string name="bookmark_picker_name">Закладки</string>
+  <string name="button_add_calendar">Додати в календар</string>
+  <string name="button_add_contact">Додати контакт</string>
+  <string name="button_book_search">Пошук книги</string>
+  <string name="button_cancel">Відміна</string>
+  <string name="button_custom_product_search">Користувацький пошук</string>
+  <string name="button_dial">Набрати номер</string>
+  <string name="button_email">Відправити e-mail</string>
+  <string name="button_get_directions">Прокласти маршрут</string>
+  <string name="button_mms">Відправити MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Відкрити браузер</string>
+  <string name="button_product_search">Пошук товара</string>
+  <string name="button_search_book_contents">Пошук вмісту книги</string>
+  <string name="button_share_app">Програма</string>
+  <string name="button_share_bookmark">Закладка</string>
+  <string name="button_share_by_email">Поділитись через e-mail</string>
+  <string name="button_share_by_sms">Поділитись через SMS</string>
+  <string name="button_share_clipboard">Буфер обміну</string>
+  <string name="button_share_contact">Контакт</string>
+  <string name="button_show_map">Показати карту</string>
+  <string name="button_sms">Відправити SMS</string>
+  <string name="button_web_search">Пошук в інтернеті</string>
+  <string name="button_wifi">Підключитись до мережі</string>
+  <string name="contents_contact">Контактна інформація</string>
+  <string name="contents_email">Адреса e-mail</string>
+  <string name="contents_location">Географічні координати</string>
+  <string name="contents_phone">Номер телефону</string>
+  <string name="contents_sms">Адреса для SMS</string>
+  <string name="contents_text">Текст</string>
+  <string name="history_clear_one_history_text">Видалити</string>
+  <string name="history_clear_text">Видалити історію</string>
+  <string name="history_email_title">Історія сканування</string>
+  <string name="history_empty">Пусто</string>
+  <string name="history_empty_detail">Нема збережених штрих-кодів</string>
+  <string name="history_send">Відправити історію</string>
+  <string name="history_title">Історія</string>
+  <string name="menu_encode_mecard">Використовуйте MECARD</string>
+  <string name="menu_encode_vcard">Використовуйте vCard</string>
+  <string name="menu_help">Допомога</string>
+  <string name="menu_history">Історія</string>
+  <string name="menu_settings">Налаштування</string>
+  <string name="menu_share">Поділитись</string>
+  <string name="msg_bulk_mode_scanned">Масовий режим: зберігати історію сканування</string>
+  <string name="msg_camera_framework_bug">Нажаль, виникла помилка камери. Можливо, вам знадобиться перезавантажити пристрій.</string>
+  <string name="msg_default_format">Формат</string>
+  <string name="msg_default_meta">Метадані</string>
+  <string name="msg_default_mms_subject">Привіт</string>
+  <string name="msg_default_status">Щоб відсканувати штрих-код, помістіть його в прямокутник видошукача.</string>
+  <string name="msg_default_time">Час</string>
+  <string name="msg_default_type">Тип</string>
+  <string name="msg_encode_contents_failed">Неможливо створити штрих-код з наданих даних.</string>
+  <string name="msg_error">Помилка</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Нажаль, неможливо запустити дану програму. Можливо, вміст штрих-коду пошкоджено.</string>
+  <string name="msg_invalid_value">Некоректна</string>
+  <string name="msg_redirect">Переслати</string>
+  <string name="msg_sbc_book_not_searchable">Нажаль, пошук книги був невдалим.</string>
+  <string name="msg_sbc_failed">Нажаль, виникла помилка пошуку.</string>
+  <string name="msg_sbc_no_page_returned">Не знайдено жодної сторінки.</string>
+  <string name="msg_sbc_page">Сторінка</string>
+  <string name="msg_sbc_results">Результати</string>
+  <string name="msg_sbc_searching_book">Пошук книги\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Фрагмент недоступний</string>
+  <string name="msg_share_explanation">Ви можете ділитись даними, скануючи штрих-код з вашого екрану іншим телефоном.</string>
+  <string name="msg_share_text">Або введіть текст</string>
+  <string name="msg_sure">Ви впевнені?</string>
+  <string name="msg_unmount_usb">Нажаль, SD-карта недоступна.</string>
+  <string name="preferences_actions_title">Коли штрих-код знайдено\u2026</string>
+  <string name="preferences_auto_focus_title">Використовувати автофокус</string>
+  <string name="preferences_auto_open_web_title">Відкрийте веб-сторінок автоматично</string>
+  <string name="preferences_bulk_mode_summary">Постійно сканувати та зберігати штрих-коди</string>
+  <string name="preferences_bulk_mode_title">Масове сканування</string>
+  <string name="preferences_copy_to_clipboard_title">Скопіювати до буферу обміну</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Заміни: %s = вміст, %f = формат, %t = тип</string>
+  <string name="preferences_custom_product_search_title">URL користувацького пошуку</string>
+  <string name="preferences_decode_1D_industrial_title">Промислові 1D</string>
+  <string name="preferences_decode_1D_product_title">1D продукту</string>
+  <string name="preferences_decode_Aztec_title">Ацтекскій</string>
+  <string name="preferences_decode_Data_Matrix_title">Розпізнавати Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">Розпізнавати QR-коди</string>
+  <string name="preferences_device_bug_workarounds_title">Виправлення помилок пристрою</string>
+  <string name="preferences_disable_barcode_scene_mode_title">Немає режимі штрих-коду сцени</string>
+  <string name="preferences_disable_continuous_focus_summary">Стандартний режим фокусування</string>
+  <string name="preferences_disable_continuous_focus_title">Відклюти безперервне фокусування</string>
+  <string name="preferences_disable_exposure_title">Відключити експозицію</string>
+  <string name="preferences_disable_metering_title">Немає обліку</string>
+  <string name="preferences_front_light_auto">Автоматично</string>
+  <string name="preferences_front_light_off">Вимкнено</string>
+  <string name="preferences_front_light_on">Увімкнено</string>
+  <string name="preferences_front_light_summary">Покращує розпізнавання при поганому освітлення, але може викликати відблиски. Працює не на всіх пристроях.</string>
+  <string name="preferences_front_light_title">Ліхтарик</string>
+  <string name="preferences_general_title">Загальні налаштування</string>
+  <string name="preferences_history_summary">Зберігайте ваші скани в історії</string>
+  <string name="preferences_history_title">Додати в історії</string>
+  <string name="preferences_invert_scan_summary">Сканування білих штрих-кодів на чорному фоні. Не працює на деяких пристроях.</string>
+  <string name="preferences_invert_scan_title">Інвертувати</string>
+  <string name="preferences_name">Налаштування</string>
+  <string name="preferences_orientation_title">Немає автоматичного повороту</string>
+  <string name="preferences_play_beep_title">Пищати</string>
+  <string name="preferences_remember_duplicates_summary">Зберігати результати сканування однакових штрих-кодів</string>
+  <string name="preferences_remember_duplicates_title">Запом\'ятовувати дублікати</string>
+  <string name="preferences_result_title">Налаштування результатів</string>
+  <string name="preferences_scanning_title">Під час сканування штрих-кодів\u2026</string>
+  <string name="preferences_search_country">Пошук країни</string>
+  <string name="preferences_supplemental_summary">Показати детальну інформацію про штрих-код</string>
+  <string name="preferences_supplemental_title">Подробиці</string>
+  <string name="preferences_vibrate_title">Вібрувати</string>
+  <string name="result_address_book">Знайдені контактні дані</string>
+  <string name="result_calendar">Знайдено подію для календаря</string>
+  <string name="result_email_address">Знайдено e-mail адресу</string>
+  <string name="result_geo">Знайдено географічні координати</string>
+  <string name="result_isbn">Знайдено книгу</string>
+  <string name="result_product">Знайдено товар</string>
+  <string name="result_sms">Знайдено адресу для SMS</string>
+  <string name="result_tel">Знайдено номер телефона</string>
+  <string name="result_text">Знайдено текст</string>
+  <string name="result_uri">Знайдено URL</string>
+  <string name="result_wifi">Знайдено конфігурацію мережі</string>
+  <string name="sbc_name">Пошук книг Google</string>
+  <string name="wifi_changing_network">Запит підключення до мережі\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-zh-rCN/strings.xml b/BarCodeScanner/mobile/src/main/res/values-zh-rCN/strings.xml
new file mode 100644 (file)
index 0000000..2d95aa7
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">条码扫描器</string>
+  <string name="app_picker_name">应用</string>
+  <string name="bookmark_picker_name">书签</string>
+  <string name="button_add_calendar">添加事件至日历</string>
+  <string name="button_add_contact">添加联系人</string>
+  <string name="button_book_search">打开图书搜索</string>
+  <string name="button_cancel">取消</string>
+  <string name="button_custom_product_search">自定义搜索</string>
+  <string name="button_dial">拨号</string>
+  <string name="button_email">发送email</string>
+  <string name="button_get_directions">获取地址</string>
+  <string name="button_mms">发送彩信</string>
+  <string name="button_ok">确定</string>
+  <string name="button_open_browser">打开浏览器</string>
+  <string name="button_product_search">打开产品搜索</string>
+  <string name="button_search_book_contents">搜索图书内容</string>
+  <string name="button_share_app">共享应用</string>
+  <string name="button_share_bookmark">分享书签</string>
+  <string name="button_share_by_email">通过email分享</string>
+  <string name="button_share_by_sms">通过短信分享</string>
+  <string name="button_share_clipboard">分享剪切板</string>
+  <string name="button_share_contact">分享联系人</string>
+  <string name="button_show_map">显示地图</string>
+  <string name="button_sms">发送短信</string>
+  <string name="button_web_search">网页搜索</string>
+  <string name="button_wifi">连接到网络</string>
+  <string name="contents_contact">联系人信息</string>
+  <string name="contents_email">Email地址</string>
+  <string name="contents_location">地理坐标</string>
+  <string name="contents_phone">电话号码</string>
+  <string name="contents_sms">短信地址</string>
+  <string name="contents_text">纯文本</string>
+  <string name="history_clear_one_history_text">删除</string>
+  <string name="history_clear_text">删除历史</string>
+  <string name="history_email_title">条码扫描器历史</string>
+  <string name="history_empty">空的</string>
+  <string name="history_empty_detail">没有条码扫描已记录</string>
+  <string name="history_send">发送历史</string>
+  <string name="history_title">历史</string>
+  <string name="menu_encode_mecard">使用MECARD</string>
+  <string name="menu_encode_vcard">使用vCard</string>
+  <string name="menu_help">帮助</string>
+  <string name="menu_history">历史</string>
+  <string name="menu_settings">设置</string>
+  <string name="menu_share">分享</string>
+  <string name="msg_bulk_mode_scanned">批量扫描:找到条码,已保存</string>
+  <string name="msg_camera_framework_bug">抱歉,Android相机出现问题。您可能需要重启设备。</string>
+  <string name="msg_default_format">格式</string>
+  <string name="msg_default_meta">元数据</string>
+  <string name="msg_default_mms_subject">Hi</string>
+  <string name="msg_default_status">请将条码置于取景框内扫描。  </string>
+  <string name="msg_default_time">时间</string>
+  <string name="msg_default_type">类型</string>
+  <string name="msg_encode_contents_failed">无法根据已有数据生成条码。   </string>
+  <string name="msg_error">错误</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">抱歉,无法打开所需软件。 条码内容可能无效。</string>
+  <string name="msg_invalid_value">值无效</string>
+  <string name="msg_redirect">重定向</string>
+  <string name="msg_sbc_book_not_searchable">抱歉,无法找到此图书。</string>
+  <string name="msg_sbc_failed">抱歉,搜索时遇到错误。</string>
+  <string name="msg_sbc_no_page_returned">无页面返回</string>
+  <string name="msg_sbc_page">页面</string>
+  <string name="msg_sbc_results">结果</string>
+  <string name="msg_sbc_searching_book">搜索图书…</string>
+  <string name="msg_sbc_snippet_unavailable">摘录不可用</string>
+  <string name="msg_share_explanation">您可以通过在自己的手机上显示条码,并使用其它手机扫描此条码的方式进行分享</string>
+  <string name="msg_share_text">或键入一些文字</string>
+  <string name="msg_sure">你肯定吗?</string>
+  <string name="msg_unmount_usb">抱歉,SD卡不可访问。</string>
+  <string name="preferences_actions_title">找到条码时</string>
+  <string name="preferences_auto_focus_title">使用自动对焦</string>
+  <string name="preferences_auto_open_web_title">自动打开网页</string>
+  <string name="preferences_bulk_mode_summary">连续扫描并保存多个条形码</string>
+  <string name="preferences_bulk_mode_title">批量扫描模式</string>
+  <string name="preferences_copy_to_clipboard_title">复制到剪切板</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">替换:%s=内容,%f=格式,%t=类型</string>
+  <string name="preferences_custom_product_search_title">自定义搜索网址</string>
+  <string name="preferences_decode_1D_industrial_title">1D工业</string>
+  <string name="preferences_decode_1D_product_title">1D产品</string>
+  <string name="preferences_decode_Aztec_title">阿兹台克人</string>
+  <string name="preferences_decode_Data_Matrix_title">扫描 DM码</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">扫描 QR码</string>
+  <string name="preferences_device_bug_workarounds_title">设备问题解决办法</string>
+  <string name="preferences_disable_barcode_scene_mode_title">没有条形码的场景模式</string>
+  <string name="preferences_disable_continuous_focus_summary">只使用标准对焦模式</string>
+  <string name="preferences_disable_continuous_focus_title">没有持续关注</string>
+  <string name="preferences_disable_exposure_title">无曝光</string>
+  <string name="preferences_disable_metering_title">无计量</string>
+  <string name="preferences_front_light_auto">自动</string>
+  <string name="preferences_front_light_off">待用</string>
+  <string name="preferences_front_light_on">活跃</string>
+  <string name="preferences_front_light_summary">前灯可用时,打开前灯</string>
+  <string name="preferences_front_light_title">前灯</string>
+  <string name="preferences_general_title">一般设置</string>
+  <string name="preferences_history_summary">存储在历史的扫描</string>
+  <string name="preferences_history_title">加入历史</string>
+  <string name="preferences_invert_scan_summary">黑色背景上的白色条形码扫描。在某些设备上。</string>
+  <string name="preferences_invert_scan_title">反向扫描</string>
+  <string name="preferences_name">设置</string>
+  <string name="preferences_orientation_title">没有自动旋转</string>
+  <string name="preferences_play_beep_title">提示音</string>
+  <string name="preferences_remember_duplicates_summary">在历史记录中保存重复记录</string>
+  <string name="preferences_remember_duplicates_title">记住重复</string>
+  <string name="preferences_result_title">结果设置</string>
+  <string name="preferences_scanning_title">条码类型选择</string>
+  <string name="preferences_search_country">搜索国家</string>
+  <string name="preferences_supplemental_summary">尝试检索关于条码内容的更多信息</string>
+  <string name="preferences_supplemental_title">检索更多信息</string>
+  <string name="preferences_vibrate_title">振动</string>
+  <string name="result_address_book">找到联系人信息</string>
+  <string name="result_calendar">找到日历事件</string>
+  <string name="result_email_address">找到email地址</string>
+  <string name="result_geo">找到地理坐标</string>
+  <string name="result_isbn">找到图书</string>
+  <string name="result_product">找到产品</string>
+  <string name="result_sms">找到短信地址</string>
+  <string name="result_tel">找到电话号码</string>
+  <string name="result_text">找到纯文本</string>
+  <string name="result_uri">找到URL</string>
+  <string name="result_wifi">发现网络配置</string>
+  <string name="sbc_name">Google图书搜索</string>
+  <string name="wifi_changing_network">请求连接到网络\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-zh-rHK/strings.xml b/BarCodeScanner/mobile/src/main/res/values-zh-rHK/strings.xml
new file mode 100644 (file)
index 0000000..c644de6
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">條碼掃描器</string>
+  <string name="app_picker_name">應用程式</string>
+  <string name="bookmark_picker_name">書籤</string>
+  <string name="button_add_calendar">加入至行事曆</string>
+  <string name="button_add_contact">加入聯絡人</string>
+  <string name="button_book_search">圖書搜尋</string>
+  <string name="button_cancel">取消</string>
+  <string name="button_custom_product_search">自定義搜尋</string>
+  <string name="button_dial">撥號</string>
+  <string name="button_email">發送電子郵件</string>
+  <string name="button_get_directions">規劃路線</string>
+  <string name="button_mms">發送 MMS</string>
+  <string name="button_ok">確定</string>
+  <string name="button_open_browser">開啟瀏覽器</string>
+  <string name="button_product_search">產品搜尋</string>
+  <string name="button_search_book_contents">搜尋圖書內容</string>
+  <string name="button_share_app">應用程式</string>
+  <string name="button_share_bookmark">書籤</string>
+  <string name="button_share_by_email">透過電子郵件分享</string>
+  <string name="button_share_by_sms">透過簡訊分享</string>
+  <string name="button_share_clipboard">剪貼簿</string>
+  <string name="button_share_contact">聯絡人資訊</string>
+  <string name="button_show_map">顯示地圖</string>
+  <string name="button_sms">發送簡訊</string>
+  <string name="button_web_search">網頁搜尋</string>
+  <string name="button_wifi">連接網路</string>
+  <string name="contents_contact">聯絡人資訊</string>
+  <string name="contents_email">電子郵件地址</string>
+  <string name="contents_location">地理座標</string>
+  <string name="contents_phone">電話號碼</string>
+  <string name="contents_sms">簡訊地址</string>
+  <string name="contents_text">純文字</string>
+  <string name="history_clear_one_history_text">清除記錄</string>
+  <string name="history_clear_text">清除</string>
+  <string name="history_email_title">條碼掃描器記錄</string>
+  <string name="history_empty">沒有記錄</string>
+  <string name="history_empty_detail">沒有條碼掃描記錄</string>
+  <string name="history_send">發送記錄</string>
+  <string name="history_title">記錄</string>
+  <string name="menu_encode_mecard">使用 MECARD</string>
+  <string name="menu_encode_vcard">使用 vCard</string>
+  <string name="menu_help">說明</string>
+  <string name="menu_history">記錄</string>
+  <string name="menu_settings">設定</string>
+  <string name="menu_share">分享</string>
+  <string name="msg_bulk_mode_scanned">大量掃描模式:條碼掃描並儲存</string>
+  <string name="msg_camera_framework_bug">很抱歉,Android 相機出現問題,您可能需要重新啟動您的裝置。</string>
+  <string name="msg_default_format">格式</string>
+  <string name="msg_default_meta">元資料</string>
+  <string name="msg_default_mms_subject">你好</string>
+  <string name="msg_default_status">將條碼置於鏡頭範圍內以進行掃描。</string>
+  <string name="msg_default_time">時間</string>
+  <string name="msg_default_type">類型</string>
+  <string name="msg_encode_contents_failed">無法讀取條碼。</string>
+  <string name="msg_error">錯誤</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">抱歉,無法打開所需軟體,條碼內容可能不符規格。</string>
+  <string name="msg_invalid_value">輸入值無效</string>
+  <string name="msg_redirect">重定向</string>
+  <string name="msg_sbc_book_not_searchable">無法找到此圖書。</string>
+  <string name="msg_sbc_failed">搜尋時發生錯誤。</string>
+  <string name="msg_sbc_no_page_returned">沒有取得頁面</string>
+  <string name="msg_sbc_page">頁面</string>
+  <string name="msg_sbc_results">結果</string>
+  <string name="msg_sbc_searching_book">搜尋圖書中\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">無法取得摘要</string>
+  <string name="msg_share_explanation">您可以在您的手機螢幕上顯示條碼,並使用其他手機掃描條碼,藉此分享資訊</string>
+  <string name="msg_share_text">或輸入一些文字並按 Enter</string>
+  <string name="msg_sure">您確定嗎?</string>
+  <string name="msg_unmount_usb">無法讀取 SD 卡。</string>
+  <string name="preferences_actions_title">找到條碼時\u2026</string>
+  <string name="preferences_auto_focus_title">使用自動對焦</string>
+  <string name="preferences_auto_open_web_title">自動打開網頁</string>
+  <string name="preferences_bulk_mode_summary">連續掃描並儲存多個條碼</string>
+  <string name="preferences_bulk_mode_title">大量掃描模式</string>
+  <string name="preferences_copy_to_clipboard_title">複製到剪貼簿</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">替換:%s=內容,%f=格式,%t=類型</string>
+  <string name="preferences_custom_product_search_title">自訂搜尋網址</string>
+  <string name="preferences_decode_1D_industrial_title">一維工業條碼</string>
+  <string name="preferences_decode_1D_product_title">一維產品條碼</string>
+  <string name="preferences_decode_Aztec_title">Aztec 條碼</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix 條碼</string>
+  <string name="preferences_decode_PDF417_title">PDF417 條碼(β)</string>
+  <string name="preferences_decode_QR_title">QR Code</string>
+  <string name="preferences_device_bug_workarounds_title">迴避設備問題</string>
+  <string name="preferences_disable_barcode_scene_mode_title">取消條碼場景模式</string>
+  <string name="preferences_disable_continuous_focus_summary">只使用標準對焦模式</string>
+  <string name="preferences_disable_continuous_focus_title">取消連續對焦</string>
+  <string name="preferences_disable_exposure_title">取消曝光</string>
+  <string name="preferences_disable_metering_title">取消測光</string>
+  <string name="preferences_front_light_auto">自動</string>
+  <string name="preferences_front_light_off">關</string>
+  <string name="preferences_front_light_on">開</string>
+  <string name="preferences_front_light_summary">改善在低光源的環境下掃描的成功率,但有可能造成過度曝光的現象</string>
+  <string name="preferences_front_light_title">使用前光源</string>
+  <string name="preferences_general_title">一般設定</string>
+  <string name="preferences_history_summary">存儲在歷史的掃描</string>
+  <string name="preferences_history_title">加入歷史</string>
+  <string name="preferences_invert_scan_summary">掃描黑底白字的條碼(某些設備上無法使用)</string>
+  <string name="preferences_invert_scan_title">黑底白字掃描</string>
+  <string name="preferences_name">設定</string>
+  <string name="preferences_orientation_title">沒有自動旋轉</string>
+  <string name="preferences_play_beep_title">嗶一聲</string>
+  <string name="preferences_remember_duplicates_summary">在記錄中重複儲存相同的條碼</string>
+  <string name="preferences_remember_duplicates_title">記錄重複的條碼</string>
+  <string name="preferences_result_title">結果設定</string>
+  <string name="preferences_scanning_title">當掃描條碼時,解碼\u2026</string>
+  <string name="preferences_search_country">搜尋國家</string>
+  <string name="preferences_supplemental_summary">嘗試透過條碼搜尋更多的資訊</string>
+  <string name="preferences_supplemental_title">搜尋更多資訊</string>
+  <string name="preferences_vibrate_title">震動</string>
+  <string name="result_address_book">找到聯絡人資訊</string>
+  <string name="result_calendar">找到行事曆事件</string>
+  <string name="result_email_address">找到電子郵件地址</string>
+  <string name="result_geo">找到座標</string>
+  <string name="result_isbn">找到圖書</string>
+  <string name="result_product">找到產品</string>
+  <string name="result_sms">找到簡訊</string>
+  <string name="result_tel">找到電話號碼</string>
+  <string name="result_text">找到文字</string>
+  <string name="result_uri">找到 URL</string>
+  <string name="result_wifi">找到無線區網設定</string>
+  <string name="sbc_name">Google 圖書搜尋</string>
+  <string name="wifi_changing_network">網路連接中\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values-zh-rTW/strings.xml b/BarCodeScanner/mobile/src/main/res/values-zh-rTW/strings.xml
new file mode 100644 (file)
index 0000000..c644de6
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">條碼掃描器</string>
+  <string name="app_picker_name">應用程式</string>
+  <string name="bookmark_picker_name">書籤</string>
+  <string name="button_add_calendar">加入至行事曆</string>
+  <string name="button_add_contact">加入聯絡人</string>
+  <string name="button_book_search">圖書搜尋</string>
+  <string name="button_cancel">取消</string>
+  <string name="button_custom_product_search">自定義搜尋</string>
+  <string name="button_dial">撥號</string>
+  <string name="button_email">發送電子郵件</string>
+  <string name="button_get_directions">規劃路線</string>
+  <string name="button_mms">發送 MMS</string>
+  <string name="button_ok">確定</string>
+  <string name="button_open_browser">開啟瀏覽器</string>
+  <string name="button_product_search">產品搜尋</string>
+  <string name="button_search_book_contents">搜尋圖書內容</string>
+  <string name="button_share_app">應用程式</string>
+  <string name="button_share_bookmark">書籤</string>
+  <string name="button_share_by_email">透過電子郵件分享</string>
+  <string name="button_share_by_sms">透過簡訊分享</string>
+  <string name="button_share_clipboard">剪貼簿</string>
+  <string name="button_share_contact">聯絡人資訊</string>
+  <string name="button_show_map">顯示地圖</string>
+  <string name="button_sms">發送簡訊</string>
+  <string name="button_web_search">網頁搜尋</string>
+  <string name="button_wifi">連接網路</string>
+  <string name="contents_contact">聯絡人資訊</string>
+  <string name="contents_email">電子郵件地址</string>
+  <string name="contents_location">地理座標</string>
+  <string name="contents_phone">電話號碼</string>
+  <string name="contents_sms">簡訊地址</string>
+  <string name="contents_text">純文字</string>
+  <string name="history_clear_one_history_text">清除記錄</string>
+  <string name="history_clear_text">清除</string>
+  <string name="history_email_title">條碼掃描器記錄</string>
+  <string name="history_empty">沒有記錄</string>
+  <string name="history_empty_detail">沒有條碼掃描記錄</string>
+  <string name="history_send">發送記錄</string>
+  <string name="history_title">記錄</string>
+  <string name="menu_encode_mecard">使用 MECARD</string>
+  <string name="menu_encode_vcard">使用 vCard</string>
+  <string name="menu_help">說明</string>
+  <string name="menu_history">記錄</string>
+  <string name="menu_settings">設定</string>
+  <string name="menu_share">分享</string>
+  <string name="msg_bulk_mode_scanned">大量掃描模式:條碼掃描並儲存</string>
+  <string name="msg_camera_framework_bug">很抱歉,Android 相機出現問題,您可能需要重新啟動您的裝置。</string>
+  <string name="msg_default_format">格式</string>
+  <string name="msg_default_meta">元資料</string>
+  <string name="msg_default_mms_subject">你好</string>
+  <string name="msg_default_status">將條碼置於鏡頭範圍內以進行掃描。</string>
+  <string name="msg_default_time">時間</string>
+  <string name="msg_default_type">類型</string>
+  <string name="msg_encode_contents_failed">無法讀取條碼。</string>
+  <string name="msg_error">錯誤</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">抱歉,無法打開所需軟體,條碼內容可能不符規格。</string>
+  <string name="msg_invalid_value">輸入值無效</string>
+  <string name="msg_redirect">重定向</string>
+  <string name="msg_sbc_book_not_searchable">無法找到此圖書。</string>
+  <string name="msg_sbc_failed">搜尋時發生錯誤。</string>
+  <string name="msg_sbc_no_page_returned">沒有取得頁面</string>
+  <string name="msg_sbc_page">頁面</string>
+  <string name="msg_sbc_results">結果</string>
+  <string name="msg_sbc_searching_book">搜尋圖書中\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">無法取得摘要</string>
+  <string name="msg_share_explanation">您可以在您的手機螢幕上顯示條碼,並使用其他手機掃描條碼,藉此分享資訊</string>
+  <string name="msg_share_text">或輸入一些文字並按 Enter</string>
+  <string name="msg_sure">您確定嗎?</string>
+  <string name="msg_unmount_usb">無法讀取 SD 卡。</string>
+  <string name="preferences_actions_title">找到條碼時\u2026</string>
+  <string name="preferences_auto_focus_title">使用自動對焦</string>
+  <string name="preferences_auto_open_web_title">自動打開網頁</string>
+  <string name="preferences_bulk_mode_summary">連續掃描並儲存多個條碼</string>
+  <string name="preferences_bulk_mode_title">大量掃描模式</string>
+  <string name="preferences_copy_to_clipboard_title">複製到剪貼簿</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">替換:%s=內容,%f=格式,%t=類型</string>
+  <string name="preferences_custom_product_search_title">自訂搜尋網址</string>
+  <string name="preferences_decode_1D_industrial_title">一維工業條碼</string>
+  <string name="preferences_decode_1D_product_title">一維產品條碼</string>
+  <string name="preferences_decode_Aztec_title">Aztec 條碼</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix 條碼</string>
+  <string name="preferences_decode_PDF417_title">PDF417 條碼(β)</string>
+  <string name="preferences_decode_QR_title">QR Code</string>
+  <string name="preferences_device_bug_workarounds_title">迴避設備問題</string>
+  <string name="preferences_disable_barcode_scene_mode_title">取消條碼場景模式</string>
+  <string name="preferences_disable_continuous_focus_summary">只使用標準對焦模式</string>
+  <string name="preferences_disable_continuous_focus_title">取消連續對焦</string>
+  <string name="preferences_disable_exposure_title">取消曝光</string>
+  <string name="preferences_disable_metering_title">取消測光</string>
+  <string name="preferences_front_light_auto">自動</string>
+  <string name="preferences_front_light_off">關</string>
+  <string name="preferences_front_light_on">開</string>
+  <string name="preferences_front_light_summary">改善在低光源的環境下掃描的成功率,但有可能造成過度曝光的現象</string>
+  <string name="preferences_front_light_title">使用前光源</string>
+  <string name="preferences_general_title">一般設定</string>
+  <string name="preferences_history_summary">存儲在歷史的掃描</string>
+  <string name="preferences_history_title">加入歷史</string>
+  <string name="preferences_invert_scan_summary">掃描黑底白字的條碼(某些設備上無法使用)</string>
+  <string name="preferences_invert_scan_title">黑底白字掃描</string>
+  <string name="preferences_name">設定</string>
+  <string name="preferences_orientation_title">沒有自動旋轉</string>
+  <string name="preferences_play_beep_title">嗶一聲</string>
+  <string name="preferences_remember_duplicates_summary">在記錄中重複儲存相同的條碼</string>
+  <string name="preferences_remember_duplicates_title">記錄重複的條碼</string>
+  <string name="preferences_result_title">結果設定</string>
+  <string name="preferences_scanning_title">當掃描條碼時,解碼\u2026</string>
+  <string name="preferences_search_country">搜尋國家</string>
+  <string name="preferences_supplemental_summary">嘗試透過條碼搜尋更多的資訊</string>
+  <string name="preferences_supplemental_title">搜尋更多資訊</string>
+  <string name="preferences_vibrate_title">震動</string>
+  <string name="result_address_book">找到聯絡人資訊</string>
+  <string name="result_calendar">找到行事曆事件</string>
+  <string name="result_email_address">找到電子郵件地址</string>
+  <string name="result_geo">找到座標</string>
+  <string name="result_isbn">找到圖書</string>
+  <string name="result_product">找到產品</string>
+  <string name="result_sms">找到簡訊</string>
+  <string name="result_tel">找到電話號碼</string>
+  <string name="result_text">找到文字</string>
+  <string name="result_uri">找到 URL</string>
+  <string name="result_wifi">找到無線區網設定</string>
+  <string name="sbc_name">Google 圖書搜尋</string>
+  <string name="wifi_changing_network">網路連接中\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values/arrays.xml b/BarCodeScanner/mobile/src/main/res/values/arrays.xml
new file mode 100644 (file)
index 0000000..08959d5
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<resources xmlns:tools="http://schemas.android.com/tools">
+  <string-array name="country_codes" tools:ignore="MissingTranslation">
+    <item>-</item>
+    <item>AR</item>
+    <item>AU</item>
+    <item>BR</item>
+    <item>BG</item>
+    <item>CA</item>
+    <item>CH</item>
+    <item>CN</item>
+    <item>CZ</item>
+    <item>DE</item>
+    <item>DK</item>
+    <item>ES</item>
+    <item>FI</item>
+    <item>FR</item>
+    <item>GB</item>
+    <item>GR</item>
+    <item>HU</item>
+    <item>ID</item>
+    <item>IT</item>
+    <item>JP</item>
+    <item>KR</item>
+    <item>NL</item>
+    <item>PL</item>
+    <item>PT</item>
+    <item>RO</item>    
+    <item>RU</item>
+    <item>SE</item>
+    <item>SK</item>
+    <item>SI</item>
+    <item>TR</item>
+    <item>TW</item>
+    <item>US</item>
+  </string-array>
+  <string-array name="preferences_front_light_values" tools:ignore="MissingTranslation">
+    <item>ON</item>
+    <item>AUTO</item>
+    <item>OFF</item>
+  </string-array>
+  <string-array name="preferences_front_light_options">
+    <item>@string/preferences_front_light_on</item>
+    <item>@string/preferences_front_light_auto</item>
+    <item>@string/preferences_front_light_off</item>
+  </string-array>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values/colors.xml b/BarCodeScanner/mobile/src/main/res/values/colors.xml
new file mode 100644 (file)
index 0000000..909224b
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <color name="contents_text">#ff000000</color>
+  <color name="encode_view">#ffffffff</color>
+  <color name="possible_result_points">#c0ffbd21</color> <!-- Android standard ICS color -->
+  <color name="result_minor_text">#ffc0c0c0</color>
+  <color name="result_points">#c099cc00</color> <!-- Android standard ICS color -->
+  <color name="result_text">#ffffffff</color>
+  <color name="result_view">#b0000000</color>
+  <color name="status_text">#ffffffff</color>
+  <color name="transparent">#00000000</color>
+  <color name="viewfinder_laser">#ffcc0000</color> <!-- Android standard ICS color -->
+  <color name="viewfinder_mask">#60000000</color>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values/dimens.xml b/BarCodeScanner/mobile/src/main/res/values/dimens.xml
new file mode 100644 (file)
index 0000000..258bbb2
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <dimen name="standard_padding">8dip</dimen>
+  <dimen name="half_padding">4dip</dimen>
+</resources>
\ No newline at end of file
diff --git a/BarCodeScanner/mobile/src/main/res/values/ids.xml b/BarCodeScanner/mobile/src/main/res/values/ids.xml
new file mode 100644 (file)
index 0000000..58399b9
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <item type="id" name="decode"/>
+  <item type="id" name="decode_failed"/>
+  <item type="id" name="decode_succeeded"/>
+  <item type="id" name="launch_product_query"/>
+  <item type="id" name="quit"/>
+  <item type="id" name="restart_preview"/>
+  <item type="id" name="return_scan_result"/>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values/strings.xml b/BarCodeScanner/mobile/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..f763675
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <string name="app_name">Barcode Scanner</string>
+  <string name="app_picker_name">Applications</string>
+  <string name="bookmark_picker_name">Bookmarks</string>
+  <string name="button_add_calendar">Add to calendar</string>
+  <string name="button_add_contact">Add contact</string>
+  <string name="button_book_search">Book Search</string>
+  <string name="button_cancel">Cancel</string>
+  <string name="button_custom_product_search">Custom search</string>
+  <string name="button_dial">Dial number</string>
+  <string name="button_email">Send email</string>
+  <string name="button_get_directions">Get directions</string>
+  <string name="button_mms">Send MMS</string>
+  <string name="button_ok">OK</string>
+  <string name="button_open_browser">Open browser</string>
+  <string name="button_product_search">Product search</string>
+  <string name="button_search_book_contents">Search contents</string>
+  <string name="button_share_app">Application</string>
+  <string name="button_share_bookmark">Bookmark</string>
+  <string name="button_share_by_email">Share via email</string>
+  <string name="button_share_by_sms">Share via SMS</string>
+  <string name="button_share_clipboard">Clipboard</string>
+  <string name="button_share_contact">Contact</string>
+  <string name="button_show_map">Show map</string>
+  <string name="button_sms">Send SMS</string>
+  <string name="button_web_search">Web search</string>
+  <string name="button_wifi">Connect to Network</string>
+  <string name="contents_contact">Contact info</string>
+  <string name="contents_email">Email address</string>
+  <string name="contents_location">Geographic coordinates</string>
+  <string name="contents_phone">Phone number</string>
+  <string name="contents_sms">SMS address</string>
+  <string name="contents_text">Plain text</string>
+  <string name="history_clear_text">Clear history</string>
+  <string name="history_clear_one_history_text">Clear</string>
+  <string name="history_email_title">Barcode Scanner history</string>
+  <string name="history_empty">Empty</string>
+  <string name="history_empty_detail">No barcode scans have been recorded</string>
+  <string name="history_send">Send history</string>
+  <string name="history_title">History</string>
+  <string name="menu_encode_mecard">Use MECARD</string>
+  <string name="menu_encode_vcard">Use vCard</string>
+  <string name="menu_help">Help</string>
+  <string name="menu_history">History</string>
+  <string name="menu_settings">Settings</string>
+  <string name="menu_share">Share</string>
+  <string name="msg_bulk_mode_scanned">Bulk mode: barcode scanned and saved</string>
+  <string name="msg_camera_framework_bug">Sorry, the Android camera encountered a problem. You may need to restart the device.</string>
+  <string name="msg_default_format">Format</string>
+  <string name="msg_default_meta">Metadata</string>
+  <string name="msg_default_mms_subject">Hi</string>
+  <string name="msg_default_status">Place a barcode inside the viewfinder rectangle to scan it.</string>
+  <string name="msg_default_time">Time</string>
+  <string name="msg_default_type">Type</string>
+  <string name="msg_encode_contents_failed">Could not encode a barcode from the data provided.</string>
+  <string name="msg_error">Error</string>
+  <string name="msg_google_books">Google</string>
+  <string name="msg_google_product">Google</string>
+  <string name="msg_intent_failed">Sorry, the requested application could not be launched. The barcode contents may be invalid.</string>
+  <string name="msg_invalid_value">Invalid value</string>
+  <string name="msg_redirect">Redirect</string>
+  <string name="msg_sbc_book_not_searchable">Sorry, this book is not searchable.</string>
+  <string name="msg_sbc_failed">Sorry, the search encountered a problem.</string>
+  <string name="msg_sbc_no_page_returned">No page returned</string>
+  <string name="msg_sbc_page">Page</string>
+  <string name="msg_sbc_results">Results</string>
+  <string name="msg_sbc_searching_book">Searching book\u2026</string>
+  <string name="msg_sbc_snippet_unavailable">Snippet not available</string>
+  <string name="msg_share_explanation">You can share data by displaying a barcode on your screen and scanning it with another phone.</string>
+  <string name="msg_share_text">Or type some text and press Enter</string>
+  <string name="msg_sure">Are you sure?</string>
+  <string name="msg_unmount_usb">Sorry, the SD card is not accessible.</string>
+  <string name="preferences_actions_title">When a barcode is found\u2026</string>
+  <string name="preferences_auto_focus_title">Use auto focus</string>
+  <string name="preferences_auto_open_web_title">Open web pages automatically</string>
+  <string name="preferences_bulk_mode_summary">Scan and save many barcodes continuously</string>
+  <string name="preferences_bulk_mode_title">Bulk scan mode</string>
+  <string name="preferences_copy_to_clipboard_title">Copy to clipboard</string>
+  <string name="preferences_custom_product_search_summary" formatted="false">Substitutions: %s = contents, %f = format, %t = type</string>
+  <string name="preferences_custom_product_search_title">Custom search URL</string>
+  <string name="preferences_decode_1D_industrial_title">1D Industrial</string>
+  <string name="preferences_decode_1D_product_title">1D Product</string>
+  <string name="preferences_decode_Aztec_title">Aztec</string>
+  <string name="preferences_decode_Data_Matrix_title">Data Matrix</string>
+  <string name="preferences_decode_PDF417_title">PDF417 (β)</string>
+  <string name="preferences_decode_QR_title">QR Codes</string>
+  <string name="preferences_device_bug_workarounds_title">Device Bug Workarounds</string>
+  <string name="preferences_disable_barcode_scene_mode_title">No barcode scene mode</string>
+  <string name="preferences_disable_continuous_focus_summary">Use only standard focus mode</string>
+  <string name="preferences_disable_continuous_focus_title">No continuous focus</string>
+  <string name="preferences_disable_exposure_title">No exposure</string>
+  <string name="preferences_disable_metering_title">No metering</string>
+  <string name="preferences_front_light_summary">Improves scanning in low light on some phones, but may cause glare. Does not work on all phones.</string>
+  <string name="preferences_front_light_title">Use front light</string>
+  <string name="preferences_front_light_auto">Automatic</string>
+  <string name="preferences_front_light_off">Off</string>
+  <string name="preferences_front_light_on">On</string>
+  <string name="preferences_general_title">General settings</string>
+  <string name="preferences_history_summary">Store your scans in History</string>
+  <string name="preferences_history_title">Add to History</string>
+  <string name="preferences_invert_scan_title">Invert scan</string>
+  <string name="preferences_invert_scan_summary">Scan for white barcodes on black background. Not available on some devices.</string>  
+  <string name="preferences_name">Settings</string>
+  <string name="preferences_orientation_title">No automatic rotation</string>
+  <string name="preferences_play_beep_title">Beep</string>
+  <string name="preferences_remember_duplicates_summary">Store multiple scans of the same barcode in History</string>
+  <string name="preferences_remember_duplicates_title">Remember duplicates</string>
+  <string name="preferences_result_title">Result settings</string>
+  <string name="preferences_scanning_title">When scanning for barcodes, decode\u2026</string>
+  <string name="preferences_search_country">Search country</string>
+  <string name="preferences_supplemental_summary">Try to retrieve more information about the barcode contents</string>
+  <string name="preferences_supplemental_title">Retrieve more info</string>
+  <string name="preferences_vibrate_title">Vibrate</string>
+  <string name="result_address_book">Found contact info</string>
+  <string name="result_calendar">Found calendar event</string>
+  <string name="result_email_address">Found email address</string>
+  <string name="result_geo">Found geographic coordinates</string>
+  <string name="result_isbn">Found book</string>
+  <string name="result_product">Found product</string>
+  <string name="result_sms">Found SMS address</string>
+  <string name="result_tel">Found phone number</string>
+  <string name="result_text">Found plain text</string>
+  <string name="result_uri">Found URL</string>
+  <string name="result_wifi">Found WLAN Configuration</string>
+  <string name="sbc_name">Google Book Search</string>
+  <string name="wifi_changing_network">Requesting connection to network\u2026</string>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values/styles.xml b/BarCodeScanner/mobile/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..b9b2a50
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2012 ZXing authors
+
+ 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.
+ -->
+<resources>
+
+  <style name="ResultButton" parent="@android:style/Widget.Holo.Button.Borderless.Small">
+    <item name="android:layout_width">0dip</item>
+    <item name="android:layout_height">wrap_content</item>
+    <item name="android:layout_weight">1</item>
+  </style>
+  <style name="ShareButton" parent="@android:style/Widget.Holo.Button.Borderless.Small">
+    <item name="android:layout_width">wrap_content</item>
+    <item name="android:layout_height">wrap_content</item>
+  </style>
+
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/values/themes.xml b/BarCodeScanner/mobile/src/main/res/values/themes.xml
new file mode 100644 (file)
index 0000000..1f76ec2
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2012 ZXing authors
+
+ 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.
+ -->
+<resources>
+  <style name="CaptureTheme" parent="android:Theme.Holo">
+    <item name="android:windowFullscreen">true</item>
+    <item name="android:windowContentOverlay">@null</item>
+    <item name="android:windowActionBarOverlay">true</item>
+    <item name="android:windowActionModeOverlay">true</item>
+  </style>
+</resources>
diff --git a/BarCodeScanner/mobile/src/main/res/xml/preferences.xml b/BarCodeScanner/mobile/src/main/res/xml/preferences.xml
new file mode 100644 (file)
index 0000000..196fed1
--- /dev/null
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ 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.
+ -->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+  <PreferenceCategory android:title="@string/preferences_scanning_title">
+    <CheckBoxPreference
+        android:key="preferences_decode_1D_product"
+        android:defaultValue="true"
+        android:title="@string/preferences_decode_1D_product_title"/>
+    <CheckBoxPreference
+        android:key="preferences_decode_1D_industrial"
+        android:defaultValue="true"
+        android:title="@string/preferences_decode_1D_industrial_title"/>
+    <CheckBoxPreference
+        android:key="preferences_decode_QR"
+        android:defaultValue="true"
+        android:title="@string/preferences_decode_QR_title"/>
+    <CheckBoxPreference
+        android:key="preferences_decode_Data_Matrix"
+        android:defaultValue="true"
+        android:title="@string/preferences_decode_Data_Matrix_title"/>
+    <CheckBoxPreference
+        android:key="preferences_decode_Aztec"
+        android:defaultValue="false"
+        android:title="@string/preferences_decode_Aztec_title"/>
+    <CheckBoxPreference
+        android:key="preferences_decode_PDF417"
+        android:defaultValue="false"
+        android:title="@string/preferences_decode_PDF417_title"/>
+  </PreferenceCategory>
+  <PreferenceCategory android:title="@string/preferences_actions_title">
+    <CheckBoxPreference
+        android:key="preferences_play_beep"
+        android:defaultValue="true"
+        android:title="@string/preferences_play_beep_title"/>
+    <CheckBoxPreference
+        android:key="preferences_vibrate"
+        android:defaultValue="false"
+        android:title="@string/preferences_vibrate_title"/>
+    <CheckBoxPreference
+        android:key="preferences_copy_to_clipboard"
+        android:defaultValue="true"
+        android:title="@string/preferences_copy_to_clipboard_title"/>
+    <CheckBoxPreference
+        android:key="preferences_auto_open_web"
+        android:defaultValue="false"
+        android:title="@string/preferences_auto_open_web_title"/>
+    <CheckBoxPreference
+        android:key="preferences_remember_duplicates"
+        android:defaultValue="false"
+        android:title="@string/preferences_remember_duplicates_title"
+        android:summary="@string/preferences_remember_duplicates_summary"/>
+    <CheckBoxPreference
+        android:key="preferences_history"
+        android:defaultValue="true"
+        android:title="@string/preferences_history_title"
+        android:summary="@string/preferences_history_summary"/>
+    <CheckBoxPreference
+        android:key="preferences_supplemental"
+        android:defaultValue="true"
+        android:title="@string/preferences_supplemental_title"
+        android:summary="@string/preferences_supplemental_summary"/>
+  </PreferenceCategory>
+  <PreferenceCategory android:title="@string/preferences_general_title">
+    <ListPreference
+        android:entries="@array/preferences_front_light_options"
+        android:entryValues="@array/preferences_front_light_values"
+        android:key="preferences_front_light_mode"
+        android:defaultValue="OFF"
+        android:title="@string/preferences_front_light_title"
+        android:summary="@string/preferences_front_light_summary"/>
+    <CheckBoxPreference
+        android:key="preferences_auto_focus"
+        android:defaultValue="true"
+        android:title="@string/preferences_auto_focus_title"/>
+    <CheckBoxPreference
+        android:key="preferences_invert_scan"
+        android:defaultValue="false"
+        android:title="@string/preferences_invert_scan_title"
+        android:summary="@string/preferences_invert_scan_summary"/>
+    <CheckBoxPreference
+        android:key="preferences_bulk_mode"
+        android:defaultValue="false"
+        android:title="@string/preferences_bulk_mode_title"
+        android:summary="@string/preferences_bulk_mode_summary"/>
+    <CheckBoxPreference
+        android:key="preferences_orientation"
+        android:defaultValue="true"
+        android:title="@string/preferences_orientation_title"/>
+  </PreferenceCategory>
+  <PreferenceCategory android:title="@string/preferences_result_title">
+    <EditTextPreference
+        android:key="preferences_custom_product_search"
+        android:title="@string/preferences_custom_product_search_title"
+        android:summary="@string/preferences_custom_product_search_summary"/>
+    <ListPreference
+        android:key="preferences_search_country"
+        android:defaultValue="-"
+        android:entries="@array/country_codes"
+        android:entryValues="@array/country_codes"
+        android:title="@string/preferences_search_country"/>
+  </PreferenceCategory>
+  <PreferenceCategory android:title="@string/preferences_device_bug_workarounds_title">
+    <CheckBoxPreference
+        android:key="preferences_disable_continuous_focus"
+        android:defaultValue="true"
+        android:title="@string/preferences_disable_continuous_focus_title"
+        android:summary="@string/preferences_disable_continuous_focus_summary"/>
+    <CheckBoxPreference
+        android:key="preferences_disable_exposure"
+        android:defaultValue="true"
+        android:title="@string/preferences_disable_exposure_title"/>
+    <CheckBoxPreference
+        android:key="preferences_disable_metering"
+        android:defaultValue="true"
+        android:title="@string/preferences_disable_metering_title"/>
+    <CheckBoxPreference
+        android:key="preferences_disable_barcode_scene_mode"
+        android:defaultValue="true"
+        android:title="@string/preferences_disable_barcode_scene_mode_title"/>
+  </PreferenceCategory>
+</PreferenceScreen>
diff --git a/BarCodeScanner/settings.gradle b/BarCodeScanner/settings.gradle
new file mode 100644 (file)
index 0000000..8afcea4
--- /dev/null
@@ -0,0 +1 @@
+include ':mobile', ':glass'
diff --git a/QRScanner/.gitignore b/QRScanner/.gitignore
new file mode 100644 (file)
index 0000000..afbdab3
--- /dev/null
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/QRScanner/.idea/.name b/QRScanner/.idea/.name
new file mode 100644 (file)
index 0000000..9eecaed
--- /dev/null
@@ -0,0 +1 @@
+QR Scanner
\ No newline at end of file
diff --git a/QRScanner/.idea/compiler.xml b/QRScanner/.idea/compiler.xml
new file mode 100644 (file)
index 0000000..217af47
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <resourceExtensions />
+    <wildcardResourcePatterns>
+      <entry name="!?*.java" />
+      <entry name="!?*.form" />
+      <entry name="!?*.class" />
+      <entry name="!?*.groovy" />
+      <entry name="!?*.scala" />
+      <entry name="!?*.flex" />
+      <entry name="!?*.kt" />
+      <entry name="!?*.clj" />
+    </wildcardResourcePatterns>
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="false">
+        <processorPath useClasspath="true" />
+      </profile>
+    </annotationProcessing>
+  </component>
+</project>
+
diff --git a/QRScanner/.idea/copyright/profiles_settings.xml b/QRScanner/.idea/copyright/profiles_settings.xml
new file mode 100644 (file)
index 0000000..e7bedf3
--- /dev/null
@@ -0,0 +1,3 @@
+<component name="CopyrightManager">
+  <settings default="" />
+</component>
\ No newline at end of file
diff --git a/QRScanner/.idea/encodings.xml b/QRScanner/.idea/encodings.xml
new file mode 100644 (file)
index 0000000..e206d70
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+</project>
+
diff --git a/QRScanner/.idea/gradle.xml b/QRScanner/.idea/gradle.xml
new file mode 100644 (file)
index 0000000..a577ae6
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/glass" />
+            <option value="$PROJECT_DIR$/mobile" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>
+
diff --git a/QRScanner/.idea/misc.xml b/QRScanner/.idea/misc.xml
new file mode 100644 (file)
index 0000000..99b2e43
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="EntryPointsManager">
+    <entry_points version="2.0" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="masterDetails">
+    <states>
+      <state key="ProjectJDKs.UI">
+        <settings>
+          <last-edited>1.8</last-edited>
+          <splitter-proportions>
+            <option name="proportions">
+              <list>
+                <option value="0.2" />
+              </list>
+            </option>
+          </splitter-proportions>
+        </settings>
+      </state>
+    </states>
+  </component>
+</project>
+
diff --git a/QRScanner/.idea/modules.xml b/QRScanner/.idea/modules.xml
new file mode 100644 (file)
index 0000000..1da6260
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/QRScanner.iml" filepath="$PROJECT_DIR$/QRScanner.iml" />
+      <module fileurl="file://$PROJECT_DIR$/glass/glass.iml" filepath="$PROJECT_DIR$/glass/glass.iml" />
+      <module fileurl="file://$PROJECT_DIR$/mobile/mobile.iml" filepath="$PROJECT_DIR$/mobile/mobile.iml" />
+    </modules>
+  </component>
+</project>
+
diff --git a/QRScanner/.idea/scopes/scope_settings.xml b/QRScanner/.idea/scopes/scope_settings.xml
new file mode 100644 (file)
index 0000000..922003b
--- /dev/null
@@ -0,0 +1,5 @@
+<component name="DependencyValidationManager">
+  <state>
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+  </state>
+</component>
\ No newline at end of file
diff --git a/QRScanner/.idea/vcs.xml b/QRScanner/.idea/vcs.xml
new file mode 100644 (file)
index 0000000..def6a6a
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="" />
+  </component>
+</project>
+
diff --git a/QRScanner/QRScanner.iml b/QRScanner/QRScanner.iml
new file mode 100644 (file)
index 0000000..42f4ed5
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <output url="file://$MODULE_DIR$/build/classes/main" />
+    <output-test url="file://$MODULE_DIR$/build/classes/test" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/QRScanner/build.gradle b/QRScanner/build.gradle
new file mode 100644 (file)
index 0000000..6356aab
--- /dev/null
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.0.0'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
diff --git a/QRScanner/glass/.gitignore b/QRScanner/glass/.gitignore
new file mode 100644 (file)
index 0000000..796b96d
--- /dev/null
@@ -0,0 +1 @@
+/build
diff --git a/QRScanner/glass/build.gradle b/QRScanner/glass/build.gradle
new file mode 100644 (file)
index 0000000..5d6a1db
--- /dev/null
@@ -0,0 +1,36 @@
+apply plugin: 'com.android.application'
+
+repositories {
+    jcenter()
+    flatDir {
+        dirs 'prebuilt-libs'
+    }
+}
+
+android {
+    compileSdkVersion "Google Inc.:Glass Development Kit Preview:19"
+    buildToolsVersion "21.1.2"
+
+    defaultConfig {
+        applicationId "cz.cvut.fel.dce.qrscanner"
+        minSdkVersion 19
+        targetSdkVersion 21
+        versionCode 1
+        versionName "1.0"
+    }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+}
diff --git a/QRScanner/glass/glass.iml b/QRScanner/glass/glass.iml
new file mode 100644 (file)
index 0000000..6b8b3c6
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="QRScanner" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":glass" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android 4.4.2 Glass Development Kit Preview" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/QRScanner/glass/proguard-rules.pro b/QRScanner/glass/proguard-rules.pro
new file mode 100644 (file)
index 0000000..1a1fc0a
--- /dev/null
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/michal/adt-bundle-linux-x86_64-20140702/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/QRScanner/glass/src/androidTest/java/cz/cvut/fel/dce/qrscanner/ApplicationTest.java b/QRScanner/glass/src/androidTest/java/cz/cvut/fel/dce/qrscanner/ApplicationTest.java
new file mode 100644 (file)
index 0000000..e1ab10c
--- /dev/null
@@ -0,0 +1,13 @@
+package cz.cvut.fel.dce.qrscanner;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
+ */
+public class ApplicationTest extends ApplicationTestCase<Application> {
+       public ApplicationTest() {
+               super(Application.class);
+       }
+}
\ No newline at end of file
diff --git a/QRScanner/glass/src/main/AndroidManifest.xml b/QRScanner/glass/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..b08a3d5
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="cz.cvut.fel.dce.qrscanner" >
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name" >
+        <activity
+            android:name=".MainActivity"
+            android:icon="@drawable/ic_glass_logo"
+            android:label="@string/title_activity_main" >
+            <intent-filter>
+                <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
+            </intent-filter>
+
+            <meta-data
+                android:name="com.google.android.glass.VoiceTrigger"
+                android:resource="@xml/voice_trigger" />
+        </activity>
+    </application>
+
+</manifest>
diff --git a/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/MainActivity.java b/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/MainActivity.java
new file mode 100644 (file)
index 0000000..b5e9d39
--- /dev/null
@@ -0,0 +1,121 @@
+package cz.cvut.fel.dce.qrscanner;
+
+import com.google.android.glass.media.Sounds;
+import com.google.android.glass.widget.CardBuilder;
+import com.google.android.glass.widget.CardScrollAdapter;
+import com.google.android.glass.widget.CardScrollView;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+
+import cz.cvut.fel.dce.qrscanner.integration.IntentIntegrator;
+import cz.cvut.fel.dce.qrscanner.integration.IntentResult;
+
+/**
+ * An {@link Activity} showing a tuggable "Hello World!" card.
+ * <p/>
+ * The main content view is composed of a one-card {@link CardScrollView} that provides tugging
+ * feedback to the user when swipe gestures are detected.
+ * If your Glassware intends to intercept swipe gestures, you should set the content view directly
+ * and use a {@link com.google.android.glass.touchpad.GestureDetector}.
+ *
+ * @see <a href="https://developers.google.com/glass/develop/gdk/touch">GDK Developer Guide</a>
+ */
+public class MainActivity extends Activity {
+       public final static String TAG = "MainActivity";
+
+       /**
+        * {@link CardScrollView} to use as the main content view.
+        */
+       private CardScrollView mCardScroller;
+
+       /**
+        * "Hello World!" {@link View} generated by {@link #buildView()}.
+        */
+       private View mView;
+
+       @Override
+       protected void onCreate(Bundle bundle) {
+               super.onCreate(bundle);
+
+               mView = buildView();
+
+               mCardScroller = new CardScrollView(this);
+               mCardScroller.setAdapter(new CardScrollAdapter() {
+                       @Override
+                       public int getCount() {
+                               return 1;
+                       }
+
+                       @Override
+                       public Object getItem(int position) {
+                               return mView;
+                       }
+
+                       @Override
+                       public View getView(int position, View convertView, ViewGroup parent) {
+                               return mView;
+                       }
+
+                       @Override
+                       public int getPosition(Object item) {
+                               if (mView.equals(item)) {
+                                       return 0;
+                               }
+                               return AdapterView.INVALID_POSITION;
+                       }
+               });
+               // Handle the TAP event.
+               mCardScroller.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+                       @Override
+                       public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                               startScan();
+                       }
+               });
+               setContentView(mCardScroller);
+       }
+
+       public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+               IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
+               if (scanResult != null) {
+                       Log.i(TAG, scanResult.toString());
+               }
+               // else continue with any other code you need in the method
+
+       }
+
+       @Override
+       protected void onResume() {
+               super.onResume();
+               mCardScroller.activate();
+       }
+
+       @Override
+       protected void onPause() {
+               mCardScroller.deactivate();
+               super.onPause();
+       }
+
+       private void startScan() {
+               IntentIntegrator integrator = new IntentIntegrator(this);
+               integrator.initiateScan();
+       }
+
+       /**
+        * Builds a Glass styled "Hello World!" view using the {@link CardBuilder} class.
+        */
+       private View buildView() {
+               CardBuilder card = new CardBuilder(this, CardBuilder.Layout.TEXT);
+
+               card.setText(R.string.hello_world);
+               return card.getView();
+       }
+
+}
diff --git a/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentIntegrator.java b/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentIntegrator.java
new file mode 100644 (file)
index 0000000..8e371bc
--- /dev/null
@@ -0,0 +1,508 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.qrscanner.integration;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.ActivityNotFoundException;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+import cz.cvut.fel.dce.qrscanner.integration.IntentResult;
+
+/**
+ * <p>A utility class which helps ease integration with Barcode Scanner via {@link android.content.Intent}s. This is a simple
+ * way to invoke barcode scanning and receive the result, without any need to integrate, modify, or learn the
+ * project's source code.</p>
+ *
+ * <h2>Initiating a barcode scan</h2>
+ *
+ * <p>To integrate, create an instance of {@code IntentIntegrator} and call {@link #initiateScan()} and wait
+ * for the result in your app.</p>
+ *
+ * <p>It does require that the Barcode Scanner (or work-alike) application is installed. The
+ * {@link #initiateScan()} method will prompt the user to download the application, if needed.</p>
+ *
+ * <p>There are a few steps to using this integration. First, your {@link android.app.Activity} must implement
+ * the method {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)} and include a line of code like this:</p>
+ *
+ * <pre>{@code
+ * public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ *   IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
+ *   if (scanResult != null) {
+ *     // handle scan result
+ *   }
+ *   // else continue with any other code you need in the method
+ *   ...
+ * }
+ * }</pre>
+ *
+ * <p>This is where you will handle a scan result.</p>
+ *
+ * <p>Second, just call this in response to a user action somewhere to begin the scan process:</p>
+ *
+ * <pre>{@code
+ * IntentIntegrator integrator = new IntentIntegrator(yourActivity);
+ * integrator.initiateScan();
+ * }</pre>
+ *
+ * <p>Note that {@link #initiateScan()} returns an {@link android.app.AlertDialog} which is non-null if the
+ * user was prompted to download the application. This lets the calling app potentially manage the dialog.
+ * In particular, ideally, the app dismisses the dialog if it's still active in its {@link android.app.Activity#onPause()}
+ * method.</p>
+ * 
+ * <p>You can use {@link #setTitle(String)} to customize the title of this download prompt dialog (or, use
+ * {@link #setTitleByID(int)} to set the title by string resource ID.) Likewise, the prompt message, and
+ * yes/no button labels can be changed.</p>
+ *
+ * <p>Finally, you can use {@link #addExtra(String, Object)} to add more parameters to the Intent used
+ * to invoke the scanner. This can be used to set additional options not directly exposed by this
+ * simplified API.</p>
+ * 
+ * <p>By default, this will only allow applications that are known to respond to this intent correctly
+ * do so. The apps that are allowed to response can be set with {@link #setTargetApplications(java.util.List)}.
+ * For example, set to {@link #TARGET_BARCODE_SCANNER_ONLY} to only target the Barcode Scanner app itself.</p>
+ *
+ * <h2>Sharing text via barcode</h2>
+ *
+ * <p>To share text, encoded as a QR Code on-screen, similarly, see {@link #shareText(CharSequence)}.</p>
+ *
+ * <p>Some code, particularly download integration, was contributed from the Anobiit application.</p>
+ *
+ * <h2>Enabling experimental barcode formats</h2>
+ *
+ * <p>Some formats are not enabled by default even when scanning with {@link #ALL_CODE_TYPES}, such as
+ * PDF417. Use {@link #initiateScan(java.util.Collection)} with
+ * a collection containing the names of formats to scan for explicitly, like "PDF_417", to use such
+ * formats.</p>
+ *
+ * @author Sean Owen
+ * @author Fred Lin
+ * @author Isaac Potoczny-Jones
+ * @author Brad Drehmer
+ * @author gcstang
+ */
+public class IntentIntegrator {
+
+  public static final int REQUEST_CODE = 0x0000c0de; // Only use bottom 16 bits
+  private static final String TAG = IntentIntegrator.class.getSimpleName();
+
+  public static final String DEFAULT_TITLE = "Install Barcode Scanner?";
+  public static final String DEFAULT_MESSAGE =
+      "This application requires Barcode Scanner. Would you like to install it?";
+  public static final String DEFAULT_YES = "Yes";
+  public static final String DEFAULT_NO = "No";
+
+  private static final String BS_PACKAGE = "cz.cvut.fel.dce.barcodescanner";
+  private static final String BSPLUS_PACKAGE = "com.srowen.bs.android";
+
+  // supported barcode formats
+  public static final Collection<String> PRODUCT_CODE_TYPES = list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "RSS_14");
+  public static final Collection<String> ONE_D_CODE_TYPES =
+      list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128",
+           "ITF", "RSS_14", "RSS_EXPANDED");
+  public static final Collection<String> QR_CODE_TYPES = Collections.singleton("QR_CODE");
+  public static final Collection<String> DATA_MATRIX_TYPES = Collections.singleton("DATA_MATRIX");
+
+  public static final Collection<String> ALL_CODE_TYPES = null;
+  
+  public static final List<String> TARGET_BARCODE_SCANNER_ONLY = Collections.singletonList(BS_PACKAGE);
+  public static final List<String> TARGET_ALL_KNOWN = list(
+          BSPLUS_PACKAGE,             // Barcode Scanner+
+          BSPLUS_PACKAGE + ".simple", // Barcode Scanner+ Simple
+          BS_PACKAGE                  // Barcode Scanner          
+          // What else supports this intent?
+      );
+  
+  private final Activity activity;
+  private final Fragment fragment;
+
+  private String title;
+  private String message;
+  private String buttonYes;
+  private String buttonNo;
+  private List<String> targetApplications;
+  private final Map<String,Object> moreExtras = new HashMap<String,Object>(3);
+
+  /**
+   * @param activity {@link android.app.Activity} invoking the integration
+   */
+  public IntentIntegrator(Activity activity) {
+    this.activity = activity;
+    this.fragment = null;
+    initializeConfiguration();
+  }
+
+  /**
+   * @param fragment {@link android.app.Fragment} invoking the integration.
+   *  {@link #startActivityForResult(android.content.Intent, int)} will be called on the {@link android.app.Fragment} instead
+   *  of an {@link android.app.Activity}
+   */
+  public IntentIntegrator(Fragment fragment) {
+    this.activity = fragment.getActivity();
+    this.fragment = fragment;
+    initializeConfiguration();
+  }
+
+  private void initializeConfiguration() {
+    title = DEFAULT_TITLE;
+    message = DEFAULT_MESSAGE;
+    buttonYes = DEFAULT_YES;
+    buttonNo = DEFAULT_NO;
+    targetApplications = TARGET_ALL_KNOWN;
+  }
+  
+  public String getTitle() {
+    return title;
+  }
+  
+  public void setTitle(String title) {
+    this.title = title;
+  }
+
+  public void setTitleByID(int titleID) {
+    title = activity.getString(titleID);
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  public void setMessageByID(int messageID) {
+    message = activity.getString(messageID);
+  }
+
+  public String getButtonYes() {
+    return buttonYes;
+  }
+
+  public void setButtonYes(String buttonYes) {
+    this.buttonYes = buttonYes;
+  }
+
+  public void setButtonYesByID(int buttonYesID) {
+    buttonYes = activity.getString(buttonYesID);
+  }
+
+  public String getButtonNo() {
+    return buttonNo;
+  }
+
+  public void setButtonNo(String buttonNo) {
+    this.buttonNo = buttonNo;
+  }
+
+  public void setButtonNoByID(int buttonNoID) {
+    buttonNo = activity.getString(buttonNoID);
+  }
+  
+  public Collection<String> getTargetApplications() {
+    return targetApplications;
+  }
+  
+  public final void setTargetApplications(List<String> targetApplications) {
+    if (targetApplications.isEmpty()) {
+      throw new IllegalArgumentException("No target applications");
+    }
+    this.targetApplications = targetApplications;
+  }
+  
+  public void setSingleTargetApplication(String targetApplication) {
+    this.targetApplications = Collections.singletonList(targetApplication);
+  }
+
+  public Map<String,?> getMoreExtras() {
+    return moreExtras;
+  }
+
+  public final void addExtra(String key, Object value) {
+    moreExtras.put(key, value);
+  }
+
+  /**
+   * Initiates a scan for all known barcode types with the default camera.
+   *
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise.
+   */
+  public final AlertDialog initiateScan() {
+    return initiateScan(ALL_CODE_TYPES, -1);
+  }
+  
+  /**
+   * Initiates a scan for all known barcode types with the specified camera.
+   *
+   * @param cameraId camera ID of the camera to use. A negative value means "no preference".
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise.
+   */
+  public final AlertDialog initiateScan(int cameraId) {
+    return initiateScan(ALL_CODE_TYPES, cameraId);
+  }
+
+  /**
+   * Initiates a scan, using the default camera, only for a certain set of barcode types, given as strings corresponding
+   * to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
+   * like {@link #PRODUCT_CODE_TYPES} for example.
+   *
+   * @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise.
+   */
+  public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats) {
+    return initiateScan(desiredBarcodeFormats, -1);
+  }
+  
+  /**
+   * Initiates a scan, using the specified camera, only for a certain set of barcode types, given as strings corresponding
+   * to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
+   * like {@link #PRODUCT_CODE_TYPES} for example.
+   *
+   * @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
+   * @param cameraId camera ID of the camera to use. A negative value means "no preference".
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise
+   */
+  public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats, int cameraId) {
+    Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
+    intentScan.addCategory(Intent.CATEGORY_DEFAULT);
+
+    // check which types of codes to scan for
+    if (desiredBarcodeFormats != null) {
+      // set the desired barcode types
+      StringBuilder joinedByComma = new StringBuilder();
+      for (String format : desiredBarcodeFormats) {
+        if (joinedByComma.length() > 0) {
+          joinedByComma.append(',');
+        }
+        joinedByComma.append(format);
+      }
+      intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
+    }
+
+    // check requested camera ID
+    if (cameraId >= 0) {
+      intentScan.putExtra("SCAN_CAMERA_ID", cameraId);
+    }
+
+    String targetAppPackage = findTargetAppPackage(intentScan);
+    if (targetAppPackage == null) {
+      return showDownloadDialog();
+    }
+    intentScan.setPackage(targetAppPackage);
+    intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+    intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    attachMoreExtras(intentScan);
+    startActivityForResult(intentScan, REQUEST_CODE);
+    return null;
+  }
+
+  /**
+   * Start an activity. This method is defined to allow different methods of activity starting for
+   * newer versions of Android and for compatibility library.
+   *
+   * @param intent Intent to start.
+   * @param code Request code for the activity
+   * @see android.app.Activity#startActivityForResult(android.content.Intent, int)
+   * @see android.app.Fragment#startActivityForResult(android.content.Intent, int)
+   */
+  protected void startActivityForResult(Intent intent, int code) {
+    if (fragment == null) {
+      activity.startActivityForResult(intent, code);
+    } else {
+      fragment.startActivityForResult(intent, code);
+    }
+  }
+  
+  private String findTargetAppPackage(Intent intent) {
+    PackageManager pm = activity.getPackageManager();
+    List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+    if (availableApps != null) {
+      for (String targetApp : targetApplications) {
+        if (contains(availableApps, targetApp)) {
+          return targetApp;
+        }
+      }
+    }
+    return null;
+  }
+  
+  private static boolean contains(Iterable<ResolveInfo> availableApps, String targetApp) {
+    for (ResolveInfo availableApp : availableApps) {
+      String packageName = availableApp.activityInfo.packageName;
+      if (targetApp.equals(packageName)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private AlertDialog showDownloadDialog() {
+    AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
+    downloadDialog.setTitle(title);
+    downloadDialog.setMessage(message);
+    downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
+      @Override
+      public void onClick(DialogInterface dialogInterface, int i) {
+        String packageName;
+        if (targetApplications.contains(BS_PACKAGE)) {
+          // Prefer to suggest download of BS if it's anywhere in the list
+          packageName = BS_PACKAGE;
+        } else {
+          // Otherwise, first option:
+          packageName = targetApplications.get(0);
+        }
+        Uri uri = Uri.parse("market://details?id=" + packageName);
+        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+        try {
+          if (fragment == null) {
+            activity.startActivity(intent);
+          } else {
+            fragment.startActivity(intent);
+          }
+        } catch (ActivityNotFoundException anfe) {
+          // Hmm, market is not installed
+          Log.w(TAG, "Google Play is not installed; cannot install " + packageName);
+        }
+      }
+    });
+    downloadDialog.setNegativeButton(buttonNo, null);
+    downloadDialog.setCancelable(true);
+    return downloadDialog.show();
+  }
+
+
+  /**
+   * <p>Call this from your {@link android.app.Activity}'s
+   * {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)} method.</p>
+   *
+   * @param requestCode request code from {@code onActivityResult()}
+   * @param resultCode result code from {@code onActivityResult()}
+   * @param intent {@link android.content.Intent} from {@code onActivityResult()}
+   * @return null if the event handled here was not related to this class, or
+   *  else an {@link com.google.zxing.integration.android.IntentResult} containing the result of the scan. If the user cancelled scanning,
+   *  the fields will be null.
+   */
+  public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
+    if (requestCode == REQUEST_CODE) {
+      if (resultCode == Activity.RESULT_OK) {
+        String contents = intent.getStringExtra("SCAN_RESULT");
+        String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
+        byte[] rawBytes = intent.getByteArrayExtra("SCAN_RESULT_BYTES");
+        int intentOrientation = intent.getIntExtra("SCAN_RESULT_ORIENTATION", Integer.MIN_VALUE);
+        Integer orientation = intentOrientation == Integer.MIN_VALUE ? null : intentOrientation;
+        String errorCorrectionLevel = intent.getStringExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL");
+        return new IntentResult(contents,
+                                formatName,
+                                rawBytes,
+                                orientation,
+                                errorCorrectionLevel);
+      }
+      return new IntentResult();
+    }
+    return null;
+  }
+
+
+  /**
+   * Defaults to type "TEXT_TYPE".
+   *
+   * @param text the text string to encode as a barcode
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise
+   * @see #shareText(CharSequence, CharSequence)
+   */
+  public final AlertDialog shareText(CharSequence text) {
+    return shareText(text, "TEXT_TYPE");
+  }
+
+  /**
+   * Shares the given text by encoding it as a barcode, such that another user can
+   * scan the text off the screen of the device.
+   *
+   * @param text the text string to encode as a barcode
+   * @param type type of data to encode. See {@code com.google.zxing.client.android.Contents.Type} constants.
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise
+   */
+  public final AlertDialog shareText(CharSequence text, CharSequence type) {
+    Intent intent = new Intent();
+    intent.addCategory(Intent.CATEGORY_DEFAULT);
+    intent.setAction(BS_PACKAGE + ".ENCODE");
+    intent.putExtra("ENCODE_TYPE", type);
+    intent.putExtra("ENCODE_DATA", text);
+    String targetAppPackage = findTargetAppPackage(intent);
+    if (targetAppPackage == null) {
+      return showDownloadDialog();
+    }
+    intent.setPackage(targetAppPackage);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    attachMoreExtras(intent);
+    if (fragment == null) {
+      activity.startActivity(intent);
+    } else {
+      fragment.startActivity(intent);
+    }
+    return null;
+  }
+  
+  private static List<String> list(String... values) {
+    return Collections.unmodifiableList(Arrays.asList(values));
+  }
+
+  private void attachMoreExtras(Intent intent) {
+    for (Map.Entry<String,Object> entry : moreExtras.entrySet()) {
+      String key = entry.getKey();
+      Object value = entry.getValue();
+      // Kind of hacky
+      if (value instanceof Integer) {
+        intent.putExtra(key, (Integer) value);
+      } else if (value instanceof Long) {
+        intent.putExtra(key, (Long) value);
+      } else if (value instanceof Boolean) {
+        intent.putExtra(key, (Boolean) value);
+      } else if (value instanceof Double) {
+        intent.putExtra(key, (Double) value);
+      } else if (value instanceof Float) {
+        intent.putExtra(key, (Float) value);
+      } else if (value instanceof Bundle) {
+        intent.putExtra(key, (Bundle) value);
+      } else {
+        intent.putExtra(key, value.toString());
+      }
+    }
+  }
+
+}
diff --git a/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentResult.java b/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentResult.java
new file mode 100644 (file)
index 0000000..294a38d
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.qrscanner.integration;
+
+/**
+ * <p>Encapsulates the result of a barcode scan invoked through {@link com.google.zxing.integration.android.IntentIntegrator}.</p>
+ *
+ * @author Sean Owen
+ */
+public final class IntentResult {
+
+  private final String contents;
+  private final String formatName;
+  private final byte[] rawBytes;
+  private final Integer orientation;
+  private final String errorCorrectionLevel;
+
+  IntentResult() {
+    this(null, null, null, null, null);
+  }
+
+  IntentResult(String contents,
+               String formatName,
+               byte[] rawBytes,
+               Integer orientation,
+               String errorCorrectionLevel) {
+    this.contents = contents;
+    this.formatName = formatName;
+    this.rawBytes = rawBytes;
+    this.orientation = orientation;
+    this.errorCorrectionLevel = errorCorrectionLevel;
+  }
+
+  /**
+   * @return raw content of barcode
+   */
+  public String getContents() {
+    return contents;
+  }
+
+  /**
+   * @return name of format, like "QR_CODE", "UPC_A". See {@code BarcodeFormat} for more format names.
+   */
+  public String getFormatName() {
+    return formatName;
+  }
+
+  /**
+   * @return raw bytes of the barcode content, if applicable, or null otherwise
+   */
+  public byte[] getRawBytes() {
+    return rawBytes;
+  }
+
+  /**
+   * @return rotation of the image, in degrees, which resulted in a successful scan. May be null.
+   */
+  public Integer getOrientation() {
+    return orientation;
+  }
+
+  /**
+   * @return name of the error correction level used in the barcode, if applicable
+   */
+  public String getErrorCorrectionLevel() {
+    return errorCorrectionLevel;
+  }
+  
+  @Override
+  public String toString() {
+    StringBuilder dialogText = new StringBuilder(100);
+    dialogText.append("Format: ").append(formatName).append('\n');
+    dialogText.append("Contents: ").append(contents).append('\n');
+    int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
+    dialogText.append("Raw bytes: (").append(rawBytesLength).append(" bytes)\n");
+    dialogText.append("Orientation: ").append(orientation).append('\n');
+    dialogText.append("EC level: ").append(errorCorrectionLevel).append('\n');
+    return dialogText.toString();
+  }
+
+}
diff --git a/QRScanner/glass/src/main/res/drawable-hdpi/ic_glass_logo.png b/QRScanner/glass/src/main/res/drawable-hdpi/ic_glass_logo.png
new file mode 100644 (file)
index 0000000..2f17b96
Binary files /dev/null and b/QRScanner/glass/src/main/res/drawable-hdpi/ic_glass_logo.png differ
diff --git a/QRScanner/glass/src/main/res/drawable-hdpi/ic_stop.png b/QRScanner/glass/src/main/res/drawable-hdpi/ic_stop.png
new file mode 100644 (file)
index 0000000..f6acb41
Binary files /dev/null and b/QRScanner/glass/src/main/res/drawable-hdpi/ic_stop.png differ
diff --git a/QRScanner/glass/src/main/res/drawable-mdpi/ic_launcher.png b/QRScanner/glass/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..359047d
Binary files /dev/null and b/QRScanner/glass/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/QRScanner/glass/src/main/res/drawable-xhdpi/ic_launcher.png b/QRScanner/glass/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..71c6d76
Binary files /dev/null and b/QRScanner/glass/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/QRScanner/glass/src/main/res/drawable-xxhdpi/ic_launcher.png b/QRScanner/glass/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..4df1894
Binary files /dev/null and b/QRScanner/glass/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/QRScanner/glass/src/main/res/values/strings.xml b/QRScanner/glass/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..cf43073
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2014 ZXing authors
+
+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.
+-->
+<resources>
+  <string name="app_name">Skoda Demo</string>
+  <string name="title_activity_main">Skoda Demo</string>
+  <string name="hello_world">Skoda Demo</string>
+
+</resources>
diff --git a/QRScanner/glass/src/main/res/values/styles.xml b/QRScanner/glass/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..65a325d
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="AppTheme" parent="android:Theme.Holo.Light">
+    </style>
+</resources>
diff --git a/QRScanner/glass/src/main/res/xml/voice_trigger.xml b/QRScanner/glass/src/main/res/xml/voice_trigger.xml
new file mode 100644 (file)
index 0000000..d9283e1
--- /dev/null
@@ -0,0 +1,2 @@
+<!-- For more information about voice trigger, check out: https://developers.google.com/glass/develop/gdk/starting-glassware -->
+<trigger command="SHOW_ME_A_DEMO"/>
diff --git a/QRScanner/gradle.properties b/QRScanner/gradle.properties
new file mode 100644 (file)
index 0000000..1d3591c
--- /dev/null
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/QRScanner/gradle/wrapper/gradle-wrapper.jar b/QRScanner/gradle/wrapper/gradle-wrapper.jar
new file mode 100644 (file)
index 0000000..8c0fb64
Binary files /dev/null and b/QRScanner/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/QRScanner/gradle/wrapper/gradle-wrapper.properties b/QRScanner/gradle/wrapper/gradle-wrapper.properties
new file mode 100644 (file)
index 0000000..0c71e76
--- /dev/null
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/QRScanner/gradlew b/QRScanner/gradlew
new file mode 100755 (executable)
index 0000000..91a7e26
--- /dev/null
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/QRScanner/gradlew.bat b/QRScanner/gradlew.bat
new file mode 100644 (file)
index 0000000..aec9973
--- /dev/null
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem  Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS=\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%" == "" set DIRNAME=.\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if "%ERRORLEVEL%" == "0" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:init\r
+@rem Get command-line arguments, handling Windowz variants\r
+\r
+if not "%OS%" == "Windows_NT" goto win9xME_args\r
+if "%@eval[2+2]" == "4" goto 4NT_args\r
+\r
+:win9xME_args\r
+@rem Slurp the command line arguments.\r
+set CMD_LINE_ARGS=\r
+set _SKIP=2\r
+\r
+:win9xME_args_slurp\r
+if "x%~1" == "x" goto execute\r
+\r
+set CMD_LINE_ARGS=%*\r
+goto execute\r
+\r
+:4NT_args\r
+@rem Get arguments from the 4NT Shell from JP Software\r
+set CMD_LINE_ARGS=%$\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+@rem Execute Gradle\r
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if "%ERRORLEVEL%"=="0" goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
+exit /b 1\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
diff --git a/QRScanner/mobile/.gitignore b/QRScanner/mobile/.gitignore
new file mode 100644 (file)
index 0000000..796b96d
--- /dev/null
@@ -0,0 +1 @@
+/build
diff --git a/QRScanner/mobile/build.gradle b/QRScanner/mobile/build.gradle
new file mode 100644 (file)
index 0000000..2a96f34
--- /dev/null
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 21
+    buildToolsVersion "21.1.2"
+
+    defaultConfig {
+        applicationId "cz.cvut.fel.dce.qrscanner"
+        minSdkVersion 16
+        targetSdkVersion 21
+        versionCode 1
+        versionName "1.0"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git a/QRScanner/mobile/mobile.iml b/QRScanner/mobile/mobile.iml
new file mode 100644 (file)
index 0000000..b46bb87
--- /dev/null
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="QRScanner" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":mobile" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" exported="" name="appcompat-v7-21.0.3" level="project" />
+    <orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" />
+    <orderEntry type="library" exported="" name="support-v4-21.0.3" level="project" />
+  </component>
+</module>
+
diff --git a/QRScanner/mobile/proguard-rules.pro b/QRScanner/mobile/proguard-rules.pro
new file mode 100644 (file)
index 0000000..1a1fc0a
--- /dev/null
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/michal/adt-bundle-linux-x86_64-20140702/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/QRScanner/mobile/src/androidTest/java/cz/cvut/fel/dce/qrscanner/ApplicationTest.java b/QRScanner/mobile/src/androidTest/java/cz/cvut/fel/dce/qrscanner/ApplicationTest.java
new file mode 100644 (file)
index 0000000..e1ab10c
--- /dev/null
@@ -0,0 +1,13 @@
+package cz.cvut.fel.dce.qrscanner;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
+ */
+public class ApplicationTest extends ApplicationTestCase<Application> {
+       public ApplicationTest() {
+               super(Application.class);
+       }
+}
\ No newline at end of file
diff --git a/QRScanner/mobile/src/main/AndroidManifest.xml b/QRScanner/mobile/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..0ed237d
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="cz.cvut.fel.dce.qrscanner" >
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/QRScanner/mobile/src/main/java/cz/cvut/fel/dce/qrscanner/MainActivity.java b/QRScanner/mobile/src/main/java/cz/cvut/fel/dce/qrscanner/MainActivity.java
new file mode 100644 (file)
index 0000000..782b5fe
--- /dev/null
@@ -0,0 +1,59 @@
+package cz.cvut.fel.dce.qrscanner;
+
+import android.content.Intent;
+import android.support.v7.app.ActionBarActivity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import cz.cvut.fel.dce.qrscanner.integration.IntentIntegrator;
+import cz.cvut.fel.dce.qrscanner.integration.IntentResult;
+
+
+public class MainActivity extends ActionBarActivity {
+       public static final String TAG = "MainActivity";
+
+       @Override
+       protected void onCreate(Bundle savedInstanceState) {
+               super.onCreate(savedInstanceState);
+               setContentView(R.layout.activity_main);
+       }
+
+
+       @Override
+       public boolean onCreateOptionsMenu(Menu menu) {
+               // Inflate the menu; this adds items to the action bar if it is present.
+               getMenuInflater().inflate(R.menu.menu_main, menu);
+               return true;
+       }
+
+       @Override
+       public boolean onOptionsItemSelected(MenuItem item) {
+               // Handle action bar item clicks here. The action bar will
+               // automatically handle clicks on the Home/Up button, so long
+               // as you specify a parent activity in AndroidManifest.xml.
+               int id = item.getItemId();
+
+               //noinspection SimplifiableIfStatement
+               if (id == R.id.start_scan) {
+                       startScan();
+               }
+
+               return super.onOptionsItemSelected(item);
+       }
+
+       public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+               IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
+               if (scanResult != null) {
+                       Log.i(TAG, scanResult.toString());
+               }
+               // else continue with any other code you need in the method
+
+       }
+
+       private void startScan() {
+               IntentIntegrator integrator = new IntentIntegrator(this);
+               integrator.initiateScan(IntentIntegrator.QR_CODE_TYPES);
+       }
+}
diff --git a/QRScanner/mobile/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentIntegrator.java b/QRScanner/mobile/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentIntegrator.java
new file mode 100644 (file)
index 0000000..6f1ac03
--- /dev/null
@@ -0,0 +1,506 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.qrscanner.integration;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.ActivityNotFoundException;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>A utility class which helps ease integration with Barcode Scanner via {@link android.content.Intent}s. This is a simple
+ * way to invoke barcode scanning and receive the result, without any need to integrate, modify, or learn the
+ * project's source code.</p>
+ *
+ * <h2>Initiating a barcode scan</h2>
+ *
+ * <p>To integrate, create an instance of {@code IntentIntegrator} and call {@link #initiateScan()} and wait
+ * for the result in your app.</p>
+ *
+ * <p>It does require that the Barcode Scanner (or work-alike) application is installed. The
+ * {@link #initiateScan()} method will prompt the user to download the application, if needed.</p>
+ *
+ * <p>There are a few steps to using this integration. First, your {@link android.app.Activity} must implement
+ * the method {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)} and include a line of code like this:</p>
+ *
+ * <pre>{@code
+ * public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ *   IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
+ *   if (scanResult != null) {
+ *     // handle scan result
+ *   }
+ *   // else continue with any other code you need in the method
+ *   ...
+ * }
+ * }</pre>
+ *
+ * <p>This is where you will handle a scan result.</p>
+ *
+ * <p>Second, just call this in response to a user action somewhere to begin the scan process:</p>
+ *
+ * <pre>{@code
+ * IntentIntegrator integrator = new IntentIntegrator(yourActivity);
+ * integrator.initiateScan();
+ * }</pre>
+ *
+ * <p>Note that {@link #initiateScan()} returns an {@link android.app.AlertDialog} which is non-null if the
+ * user was prompted to download the application. This lets the calling app potentially manage the dialog.
+ * In particular, ideally, the app dismisses the dialog if it's still active in its {@link android.app.Activity#onPause()}
+ * method.</p>
+ * 
+ * <p>You can use {@link #setTitle(String)} to customize the title of this download prompt dialog (or, use
+ * {@link #setTitleByID(int)} to set the title by string resource ID.) Likewise, the prompt message, and
+ * yes/no button labels can be changed.</p>
+ *
+ * <p>Finally, you can use {@link #addExtra(String, Object)} to add more parameters to the Intent used
+ * to invoke the scanner. This can be used to set additional options not directly exposed by this
+ * simplified API.</p>
+ * 
+ * <p>By default, this will only allow applications that are known to respond to this intent correctly
+ * do so. The apps that are allowed to response can be set with {@link #setTargetApplications(java.util.List)}.
+ * For example, set to {@link #TARGET_BARCODE_SCANNER_ONLY} to only target the Barcode Scanner app itself.</p>
+ *
+ * <h2>Sharing text via barcode</h2>
+ *
+ * <p>To share text, encoded as a QR Code on-screen, similarly, see {@link #shareText(CharSequence)}.</p>
+ *
+ * <p>Some code, particularly download integration, was contributed from the Anobiit application.</p>
+ *
+ * <h2>Enabling experimental barcode formats</h2>
+ *
+ * <p>Some formats are not enabled by default even when scanning with {@link #ALL_CODE_TYPES}, such as
+ * PDF417. Use {@link #initiateScan(java.util.Collection)} with
+ * a collection containing the names of formats to scan for explicitly, like "PDF_417", to use such
+ * formats.</p>
+ *
+ * @author Sean Owen
+ * @author Fred Lin
+ * @author Isaac Potoczny-Jones
+ * @author Brad Drehmer
+ * @author gcstang
+ */
+public class IntentIntegrator {
+
+  public static final int REQUEST_CODE = 0x0000c0de; // Only use bottom 16 bits
+  private static final String TAG = IntentIntegrator.class.getSimpleName();
+
+  public static final String DEFAULT_TITLE = "Install Barcode Scanner?";
+  public static final String DEFAULT_MESSAGE =
+      "This application requires Barcode Scanner. Would you like to install it?";
+  public static final String DEFAULT_YES = "Yes";
+  public static final String DEFAULT_NO = "No";
+
+  private static final String BS_PACKAGE = "cz.cvut.fel.dce.barcodescanner";
+  private static final String BSPLUS_PACKAGE = "com.srowen.bs.android";
+
+  // supported barcode formats
+  public static final Collection<String> PRODUCT_CODE_TYPES = list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "RSS_14");
+  public static final Collection<String> ONE_D_CODE_TYPES =
+      list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128",
+           "ITF", "RSS_14", "RSS_EXPANDED");
+  public static final Collection<String> QR_CODE_TYPES = Collections.singleton("QR_CODE");
+  public static final Collection<String> DATA_MATRIX_TYPES = Collections.singleton("DATA_MATRIX");
+
+  public static final Collection<String> ALL_CODE_TYPES = null;
+  
+  public static final List<String> TARGET_BARCODE_SCANNER_ONLY = Collections.singletonList(BS_PACKAGE);
+  public static final List<String> TARGET_ALL_KNOWN = list(
+          BSPLUS_PACKAGE,             // Barcode Scanner+
+          BSPLUS_PACKAGE + ".simple", // Barcode Scanner+ Simple
+          BS_PACKAGE                  // Barcode Scanner          
+          // What else supports this intent?
+      );
+  
+  private final Activity activity;
+  private final Fragment fragment;
+
+  private String title;
+  private String message;
+  private String buttonYes;
+  private String buttonNo;
+  private List<String> targetApplications;
+  private final Map<String,Object> moreExtras = new HashMap<String,Object>(3);
+
+  /**
+   * @param activity {@link android.app.Activity} invoking the integration
+   */
+  public IntentIntegrator(Activity activity) {
+    this.activity = activity;
+    this.fragment = null;
+    initializeConfiguration();
+  }
+
+  /**
+   * @param fragment {@link android.app.Fragment} invoking the integration.
+   *  {@link #startActivityForResult(android.content.Intent, int)} will be called on the {@link android.app.Fragment} instead
+   *  of an {@link android.app.Activity}
+   */
+  public IntentIntegrator(Fragment fragment) {
+    this.activity = fragment.getActivity();
+    this.fragment = fragment;
+    initializeConfiguration();
+  }
+
+  private void initializeConfiguration() {
+    title = DEFAULT_TITLE;
+    message = DEFAULT_MESSAGE;
+    buttonYes = DEFAULT_YES;
+    buttonNo = DEFAULT_NO;
+    targetApplications = TARGET_ALL_KNOWN;
+  }
+  
+  public String getTitle() {
+    return title;
+  }
+  
+  public void setTitle(String title) {
+    this.title = title;
+  }
+
+  public void setTitleByID(int titleID) {
+    title = activity.getString(titleID);
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  public void setMessageByID(int messageID) {
+    message = activity.getString(messageID);
+  }
+
+  public String getButtonYes() {
+    return buttonYes;
+  }
+
+  public void setButtonYes(String buttonYes) {
+    this.buttonYes = buttonYes;
+  }
+
+  public void setButtonYesByID(int buttonYesID) {
+    buttonYes = activity.getString(buttonYesID);
+  }
+
+  public String getButtonNo() {
+    return buttonNo;
+  }
+
+  public void setButtonNo(String buttonNo) {
+    this.buttonNo = buttonNo;
+  }
+
+  public void setButtonNoByID(int buttonNoID) {
+    buttonNo = activity.getString(buttonNoID);
+  }
+  
+  public Collection<String> getTargetApplications() {
+    return targetApplications;
+  }
+  
+  public final void setTargetApplications(List<String> targetApplications) {
+    if (targetApplications.isEmpty()) {
+      throw new IllegalArgumentException("No target applications");
+    }
+    this.targetApplications = targetApplications;
+  }
+  
+  public void setSingleTargetApplication(String targetApplication) {
+    this.targetApplications = Collections.singletonList(targetApplication);
+  }
+
+  public Map<String,?> getMoreExtras() {
+    return moreExtras;
+  }
+
+  public final void addExtra(String key, Object value) {
+    moreExtras.put(key, value);
+  }
+
+  /**
+   * Initiates a scan for all known barcode types with the default camera.
+   *
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise.
+   */
+  public final AlertDialog initiateScan() {
+    return initiateScan(ALL_CODE_TYPES, -1);
+  }
+  
+  /**
+   * Initiates a scan for all known barcode types with the specified camera.
+   *
+   * @param cameraId camera ID of the camera to use. A negative value means "no preference".
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise.
+   */
+  public final AlertDialog initiateScan(int cameraId) {
+    return initiateScan(ALL_CODE_TYPES, cameraId);
+  }
+
+  /**
+   * Initiates a scan, using the default camera, only for a certain set of barcode types, given as strings corresponding
+   * to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
+   * like {@link #PRODUCT_CODE_TYPES} for example.
+   *
+   * @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise.
+   */
+  public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats) {
+    return initiateScan(desiredBarcodeFormats, -1);
+  }
+  
+  /**
+   * Initiates a scan, using the specified camera, only for a certain set of barcode types, given as strings corresponding
+   * to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
+   * like {@link #PRODUCT_CODE_TYPES} for example.
+   *
+   * @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
+   * @param cameraId camera ID of the camera to use. A negative value means "no preference".
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise
+   */
+  public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats, int cameraId) {
+    Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
+    intentScan.addCategory(Intent.CATEGORY_DEFAULT);
+
+    // check which types of codes to scan for
+    if (desiredBarcodeFormats != null) {
+      // set the desired barcode types
+      StringBuilder joinedByComma = new StringBuilder();
+      for (String format : desiredBarcodeFormats) {
+        if (joinedByComma.length() > 0) {
+          joinedByComma.append(',');
+        }
+        joinedByComma.append(format);
+      }
+      intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
+    }
+
+    // check requested camera ID
+    if (cameraId >= 0) {
+      intentScan.putExtra("SCAN_CAMERA_ID", cameraId);
+    }
+
+    String targetAppPackage = findTargetAppPackage(intentScan);
+    if (targetAppPackage == null) {
+      return showDownloadDialog();
+    }
+    intentScan.setPackage(targetAppPackage);
+    intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+    intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    attachMoreExtras(intentScan);
+    startActivityForResult(intentScan, REQUEST_CODE);
+    return null;
+  }
+
+  /**
+   * Start an activity. This method is defined to allow different methods of activity starting for
+   * newer versions of Android and for compatibility library.
+   *
+   * @param intent Intent to start.
+   * @param code Request code for the activity
+   * @see android.app.Activity#startActivityForResult(android.content.Intent, int)
+   * @see android.app.Fragment#startActivityForResult(android.content.Intent, int)
+   */
+  protected void startActivityForResult(Intent intent, int code) {
+    if (fragment == null) {
+      activity.startActivityForResult(intent, code);
+    } else {
+      fragment.startActivityForResult(intent, code);
+    }
+  }
+  
+  private String findTargetAppPackage(Intent intent) {
+    PackageManager pm = activity.getPackageManager();
+    List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+    if (availableApps != null) {
+      for (String targetApp : targetApplications) {
+        if (contains(availableApps, targetApp)) {
+          return targetApp;
+        }
+      }
+    }
+    return null;
+  }
+  
+  private static boolean contains(Iterable<ResolveInfo> availableApps, String targetApp) {
+    for (ResolveInfo availableApp : availableApps) {
+      String packageName = availableApp.activityInfo.packageName;
+      if (targetApp.equals(packageName)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private AlertDialog showDownloadDialog() {
+    AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
+    downloadDialog.setTitle(title);
+    downloadDialog.setMessage(message);
+    downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
+      @Override
+      public void onClick(DialogInterface dialogInterface, int i) {
+        String packageName;
+        if (targetApplications.contains(BS_PACKAGE)) {
+          // Prefer to suggest download of BS if it's anywhere in the list
+          packageName = BS_PACKAGE;
+        } else {
+          // Otherwise, first option:
+          packageName = targetApplications.get(0);
+        }
+        Uri uri = Uri.parse("market://details?id=" + packageName);
+        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+        try {
+          if (fragment == null) {
+            activity.startActivity(intent);
+          } else {
+            fragment.startActivity(intent);
+          }
+        } catch (ActivityNotFoundException anfe) {
+          // Hmm, market is not installed
+          Log.w(TAG, "Google Play is not installed; cannot install " + packageName);
+        }
+      }
+    });
+    downloadDialog.setNegativeButton(buttonNo, null);
+    downloadDialog.setCancelable(true);
+    return downloadDialog.show();
+  }
+
+
+  /**
+   * <p>Call this from your {@link android.app.Activity}'s
+   * {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)} method.</p>
+   *
+   * @param requestCode request code from {@code onActivityResult()}
+   * @param resultCode result code from {@code onActivityResult()}
+   * @param intent {@link android.content.Intent} from {@code onActivityResult()}
+   * @return null if the event handled here was not related to this class, or
+   *  else an {@link com.google.zxing.integration.android.IntentResult} containing the result of the scan. If the user cancelled scanning,
+   *  the fields will be null.
+   */
+  public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
+    if (requestCode == REQUEST_CODE) {
+      if (resultCode == Activity.RESULT_OK) {
+        String contents = intent.getStringExtra("SCAN_RESULT");
+        String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
+        byte[] rawBytes = intent.getByteArrayExtra("SCAN_RESULT_BYTES");
+        int intentOrientation = intent.getIntExtra("SCAN_RESULT_ORIENTATION", Integer.MIN_VALUE);
+        Integer orientation = intentOrientation == Integer.MIN_VALUE ? null : intentOrientation;
+        String errorCorrectionLevel = intent.getStringExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL");
+        return new IntentResult(contents,
+                                formatName,
+                                rawBytes,
+                                orientation,
+                                errorCorrectionLevel);
+      }
+      return new IntentResult();
+    }
+    return null;
+  }
+
+
+  /**
+   * Defaults to type "TEXT_TYPE".
+   *
+   * @param text the text string to encode as a barcode
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise
+   * @see #shareText(CharSequence, CharSequence)
+   */
+  public final AlertDialog shareText(CharSequence text) {
+    return shareText(text, "TEXT_TYPE");
+  }
+
+  /**
+   * Shares the given text by encoding it as a barcode, such that another user can
+   * scan the text off the screen of the device.
+   *
+   * @param text the text string to encode as a barcode
+   * @param type type of data to encode. See {@code com.google.zxing.client.android.Contents.Type} constants.
+   * @return the {@link android.app.AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise
+   */
+  public final AlertDialog shareText(CharSequence text, CharSequence type) {
+    Intent intent = new Intent();
+    intent.addCategory(Intent.CATEGORY_DEFAULT);
+    intent.setAction(BS_PACKAGE + ".ENCODE");
+    intent.putExtra("ENCODE_TYPE", type);
+    intent.putExtra("ENCODE_DATA", text);
+    String targetAppPackage = findTargetAppPackage(intent);
+    if (targetAppPackage == null) {
+      return showDownloadDialog();
+    }
+    intent.setPackage(targetAppPackage);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    attachMoreExtras(intent);
+    if (fragment == null) {
+      activity.startActivity(intent);
+    } else {
+      fragment.startActivity(intent);
+    }
+    return null;
+  }
+  
+  private static List<String> list(String... values) {
+    return Collections.unmodifiableList(Arrays.asList(values));
+  }
+
+  private void attachMoreExtras(Intent intent) {
+    for (Map.Entry<String,Object> entry : moreExtras.entrySet()) {
+      String key = entry.getKey();
+      Object value = entry.getValue();
+      // Kind of hacky
+      if (value instanceof Integer) {
+        intent.putExtra(key, (Integer) value);
+      } else if (value instanceof Long) {
+        intent.putExtra(key, (Long) value);
+      } else if (value instanceof Boolean) {
+        intent.putExtra(key, (Boolean) value);
+      } else if (value instanceof Double) {
+        intent.putExtra(key, (Double) value);
+      } else if (value instanceof Float) {
+        intent.putExtra(key, (Float) value);
+      } else if (value instanceof Bundle) {
+        intent.putExtra(key, (Bundle) value);
+      } else {
+        intent.putExtra(key, value.toString());
+      }
+    }
+  }
+
+}
diff --git a/QRScanner/mobile/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentResult.java b/QRScanner/mobile/src/main/java/cz/cvut/fel/dce/qrscanner/integration/IntentResult.java
new file mode 100644 (file)
index 0000000..294a38d
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * 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.
+ */
+
+package cz.cvut.fel.dce.qrscanner.integration;
+
+/**
+ * <p>Encapsulates the result of a barcode scan invoked through {@link com.google.zxing.integration.android.IntentIntegrator}.</p>
+ *
+ * @author Sean Owen
+ */
+public final class IntentResult {
+
+  private final String contents;
+  private final String formatName;
+  private final byte[] rawBytes;
+  private final Integer orientation;
+  private final String errorCorrectionLevel;
+
+  IntentResult() {
+    this(null, null, null, null, null);
+  }
+
+  IntentResult(String contents,
+               String formatName,
+               byte[] rawBytes,
+               Integer orientation,
+               String errorCorrectionLevel) {
+    this.contents = contents;
+    this.formatName = formatName;
+    this.rawBytes = rawBytes;
+    this.orientation = orientation;
+    this.errorCorrectionLevel = errorCorrectionLevel;
+  }
+
+  /**
+   * @return raw content of barcode
+   */
+  public String getContents() {
+    return contents;
+  }
+
+  /**
+   * @return name of format, like "QR_CODE", "UPC_A". See {@code BarcodeFormat} for more format names.
+   */
+  public String getFormatName() {
+    return formatName;
+  }
+
+  /**
+   * @return raw bytes of the barcode content, if applicable, or null otherwise
+   */
+  public byte[] getRawBytes() {
+    return rawBytes;
+  }
+
+  /**
+   * @return rotation of the image, in degrees, which resulted in a successful scan. May be null.
+   */
+  public Integer getOrientation() {
+    return orientation;
+  }
+
+  /**
+   * @return name of the error correction level used in the barcode, if applicable
+   */
+  public String getErrorCorrectionLevel() {
+    return errorCorrectionLevel;
+  }
+  
+  @Override
+  public String toString() {
+    StringBuilder dialogText = new StringBuilder(100);
+    dialogText.append("Format: ").append(formatName).append('\n');
+    dialogText.append("Contents: ").append(contents).append('\n');
+    int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
+    dialogText.append("Raw bytes: (").append(rawBytesLength).append(" bytes)\n");
+    dialogText.append("Orientation: ").append(orientation).append('\n');
+    dialogText.append("EC level: ").append(errorCorrectionLevel).append('\n');
+    return dialogText.toString();
+  }
+
+}
diff --git a/QRScanner/mobile/src/main/res/drawable-hdpi/ic_launcher.png b/QRScanner/mobile/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..96a442e
Binary files /dev/null and b/QRScanner/mobile/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/QRScanner/mobile/src/main/res/drawable-mdpi/ic_launcher.png b/QRScanner/mobile/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..359047d
Binary files /dev/null and b/QRScanner/mobile/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/QRScanner/mobile/src/main/res/drawable-xhdpi/ic_launcher.png b/QRScanner/mobile/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..71c6d76
Binary files /dev/null and b/QRScanner/mobile/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/QRScanner/mobile/src/main/res/drawable-xxhdpi/ic_launcher.png b/QRScanner/mobile/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..4df1894
Binary files /dev/null and b/QRScanner/mobile/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/QRScanner/mobile/src/main/res/layout/activity_main.xml b/QRScanner/mobile/src/main/res/layout/activity_main.xml
new file mode 100644 (file)
index 0000000..53ce557
--- /dev/null
@@ -0,0 +1,16 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                xmlns:tools="http://schemas.android.com/tools"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:paddingLeft="@dimen/activity_horizontal_margin"
+                android:paddingRight="@dimen/activity_horizontal_margin"
+                android:paddingTop="@dimen/activity_vertical_margin"
+                android:paddingBottom="@dimen/activity_vertical_margin"
+                tools:context=".MainActivity">
+
+    <TextView
+        android:text="@string/hello_world"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+</RelativeLayout>
diff --git a/QRScanner/mobile/src/main/res/menu/menu_main.xml b/QRScanner/mobile/src/main/res/menu/menu_main.xml
new file mode 100644 (file)
index 0000000..2a55825
--- /dev/null
@@ -0,0 +1,9 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:app="http://schemas.android.com/apk/res-auto"
+      xmlns:tools="http://schemas.android.com/tools"
+      tools:context=".MainActivity">
+    <item android:id="@+id/start_scan"
+          android:title="@string/start_scan"
+          android:orderInCategory="100"
+          app:showAsAction="never"/>
+</menu>
diff --git a/QRScanner/mobile/src/main/res/values-w820dp/dimens.xml b/QRScanner/mobile/src/main/res/values-w820dp/dimens.xml
new file mode 100644 (file)
index 0000000..63fc816
--- /dev/null
@@ -0,0 +1,6 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/QRScanner/mobile/src/main/res/values/dimens.xml b/QRScanner/mobile/src/main/res/values/dimens.xml
new file mode 100644 (file)
index 0000000..47c8224
--- /dev/null
@@ -0,0 +1,5 @@
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/QRScanner/mobile/src/main/res/values/strings.xml b/QRScanner/mobile/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..d4e435a
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">QR Scanner</string>
+    <string name="hello_world">Hello world!</string>
+    <string name="action_settings">Settings</string>
+    <string name="start_scan">Scan</string>
+
+</resources>
diff --git a/QRScanner/mobile/src/main/res/values/styles.xml b/QRScanner/mobile/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..766ab99
--- /dev/null
@@ -0,0 +1,8 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+    </style>
+
+</resources>
diff --git a/QRScanner/settings.gradle b/QRScanner/settings.gradle
new file mode 100644 (file)
index 0000000..8afcea4
--- /dev/null
@@ -0,0 +1 @@
+include ':mobile', ':glass'
diff --git a/documents/1K0947105N_Abbildung.pdf b/documents/1K0947105N_Abbildung.pdf
new file mode 100644 (file)
index 0000000..b4a2daa
Binary files /dev/null and b/documents/1K0947105N_Abbildung.pdf differ
diff --git a/documents/1K0947105N_Angaben.pdf b/documents/1K0947105N_Angaben.pdf
new file mode 100644 (file)
index 0000000..65cb82e
Binary files /dev/null and b/documents/1K0947105N_Angaben.pdf differ
diff --git a/documents/3T0947105M_Abbildung.pdf b/documents/3T0947105M_Abbildung.pdf
new file mode 100644 (file)
index 0000000..f009add
Binary files /dev/null and b/documents/3T0947105M_Abbildung.pdf differ
diff --git a/documents/3T0947105M_Angaben.pdf b/documents/3T0947105M_Angaben.pdf
new file mode 100644 (file)
index 0000000..05a67ee
Binary files /dev/null and b/documents/3T0947105M_Angaben.pdf differ
diff --git a/documents/5E0947105E_Abbildung.pdf b/documents/5E0947105E_Abbildung.pdf
new file mode 100644 (file)
index 0000000..412a0ab
Binary files /dev/null and b/documents/5E0947105E_Abbildung.pdf differ
diff --git a/documents/5E0947105E_Angaben.pdf b/documents/5E0947105E_Angaben.pdf
new file mode 100644 (file)
index 0000000..937b9e4
Binary files /dev/null and b/documents/5E0947105E_Angaben.pdf differ
diff --git a/documents/Arbeitseinleitung.pdf b/documents/Arbeitseinleitung.pdf
new file mode 100644 (file)
index 0000000..34aa378
Binary files /dev/null and b/documents/Arbeitseinleitung.pdf differ
diff --git a/documents/Bild_Arbeitseinleitung.pdf b/documents/Bild_Arbeitseinleitung.pdf
new file mode 100644 (file)
index 0000000..bbe65e3
Binary files /dev/null and b/documents/Bild_Arbeitseinleitung.pdf differ
diff --git a/documents/Werkstatt_Einleitung.pdf b/documents/Werkstatt_Einleitung.pdf
new file mode 100644 (file)
index 0000000..4dea3a9
Binary files /dev/null and b/documents/Werkstatt_Einleitung.pdf differ