Commit 398db4f4 authored by Max Lv's avatar Max Lv

Add back internal QR scanner. #1273

parent 8208ac15
...@@ -36,6 +36,7 @@ libraryDependencies ++= ...@@ -36,6 +36,7 @@ libraryDependencies ++=
"com.twofortyfouram" % "android-plugin-api-for-locale" % "1.0.2" :: "com.twofortyfouram" % "android-plugin-api-for-locale" % "1.0.2" ::
"dnsjava" % "dnsjava" % "2.1.8" :: "dnsjava" % "dnsjava" % "2.1.8" ::
"eu.chainfire" % "libsuperuser" % "1.0.0.201704021214" :: "eu.chainfire" % "libsuperuser" % "1.0.0.201704021214" ::
"me.dm7.barcodescanner" % "zxing" % "1.9.3" ::
"net.glxn.qrgen" % "android" % "2.0" :: "net.glxn.qrgen" % "android" % "2.0" ::
Nil Nil
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.touchscreen" <uses-feature android:name="android.hardware.touchscreen"
android:required="false"/> android:required="false"/>
...@@ -11,6 +12,8 @@ ...@@ -11,6 +12,8 @@
android:required="false"/> android:required="false"/>
<uses-feature android:name="android.software.leanback" <uses-feature android:name="android.software.leanback"
android:required="false"/> android:required="false"/>
<uses-feature android:name="android.hardware.camera"
android:required="false"/>
<uses-sdk <uses-sdk
android:minSdkVersion="19" android:minSdkVersion="19"
...@@ -75,6 +78,12 @@ ...@@ -75,6 +78,12 @@
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:launchMode="singleTask"/> android:launchMode="singleTask"/>
<activity
android:name=".ScannerActivity"
android:label="@string/add_profile_methods_scan_qr_code"
android:parentActivityName=".MainActivity"
android:excludeFromRecents="true"/>
<activity android:name=".TaskerActivity" <activity android:name=".TaskerActivity"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<intent-filter> <intent-filter>
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar_light_dark" />
<me.dm7.barcodescanner.zxing.ZXingScannerView android:id="@+id/scanner"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
<string name="add_profile_methods_scan_qr_code">"QR コードを読み取る"</string> <string name="add_profile_methods_scan_qr_code">"QR コードを読み取る"</string>
<string name="add_profile_methods_manual_settings">"手動設定"</string> <string name="add_profile_methods_manual_settings">"手動設定"</string>
<string name="add_profile_scanner_not_installed">"Zxingに準拠したQRコードスキャンアプリをインストールして下さい"</string> <string name="add_profile_scanner_not_installed">"Zxingに準拠したQRコードスキャンアプリをインストールして下さい"</string>
<string name="add_profile_scanner_permission_required">QRコードを読み取るにはカメラの使用権限が必要です。</string>
<plurals name="removed"> <plurals name="removed">
<item quantity="other">"削除済み"</item> <item quantity="other">"削除済み"</item>
</plurals> </plurals>
......
...@@ -96,6 +96,7 @@ ...@@ -96,6 +96,7 @@
<string name="add_profile_methods_scan_qr_code">"Сканировать QR-код"</string> <string name="add_profile_methods_scan_qr_code">"Сканировать QR-код"</string>
<string name="add_profile_methods_manual_settings">"Ручные настройки"</string> <string name="add_profile_methods_manual_settings">"Ручные настройки"</string>
<string name="add_profile_scanner_not_installed">"Пожалуйста, установите любое ZXing-совместимое приложение для сканирования QR-кодов."</string> <string name="add_profile_scanner_not_installed">"Пожалуйста, установите любое ZXing-совместимое приложение для сканирования QR-кодов."</string>
<string name="add_profile_scanner_permission_required">Разрешение камеры требуется для сканирования QR код.</string>
<plurals name="removed"> <plurals name="removed">
<item quantity="one">"Удалено"</item> <item quantity="one">"Удалено"</item>
<item quantity="few">"Удалено %d элемента"</item> <item quantity="few">"Удалено %d элемента"</item>
......
...@@ -92,6 +92,7 @@ ...@@ -92,6 +92,7 @@
<string name="add_profile_methods_scan_qr_code">"扫描二维码"</string> <string name="add_profile_methods_scan_qr_code">"扫描二维码"</string>
<string name="add_profile_methods_manual_settings">"手动设置"</string> <string name="add_profile_methods_manual_settings">"手动设置"</string>
<string name="add_profile_scanner_not_installed">"请安装任意兼容 ZXing 的二维码扫描应用。"</string> <string name="add_profile_scanner_not_installed">"请安装任意兼容 ZXing 的二维码扫描应用。"</string>
<string name="add_profile_scanner_permission_required">扫描二维码需要相机权限。</string>
<plurals name="removed"> <plurals name="removed">
<item quantity="other">"已删除 %d 项"</item> <item quantity="other">"已删除 %d 项"</item>
</plurals> </plurals>
......
...@@ -90,6 +90,7 @@ ...@@ -90,6 +90,7 @@
<string name="add_profile_methods_scan_qr_code">"掃描 QR 碼"</string> <string name="add_profile_methods_scan_qr_code">"掃描 QR 碼"</string>
<string name="add_profile_methods_manual_settings">"手動設定"</string> <string name="add_profile_methods_manual_settings">"手動設定"</string>
<string name="add_profile_scanner_not_installed">"請安裝任何相容 ZXing 的 QR 碼掃描應用程式。"</string> <string name="add_profile_scanner_not_installed">"請安裝任何相容 ZXing 的 QR 碼掃描應用程式。"</string>
<string name="add_profile_scanner_permission_required">掃描 QR 碼需要相機權限。</string>
<plurals name="removed"> <plurals name="removed">
<item quantity="other">"已移除 %d 項"</item> <item quantity="other">"已移除 %d 項"</item>
</plurals> </plurals>
......
...@@ -104,6 +104,7 @@ ...@@ -104,6 +104,7 @@
<string name="add_profile_methods_scan_qr_code">Scan QR code</string> <string name="add_profile_methods_scan_qr_code">Scan QR code</string>
<string name="add_profile_methods_manual_settings">Manual Settings</string> <string name="add_profile_methods_manual_settings">Manual Settings</string>
<string name="add_profile_scanner_not_installed">Please install any ZXing-compliant QR code scanning app.</string> <string name="add_profile_scanner_not_installed">Please install any ZXing-compliant QR code scanning app.</string>
<string name="add_profile_scanner_permission_required">Camera permission is required for scanning QR code.</string>
<plurals name="removed"> <plurals name="removed">
<item quantity="one">Removed</item> <item quantity="one">Removed</item>
<item quantity="other">%d items removed</item> <item quantity="other">%d items removed</item>
......
...@@ -352,21 +352,16 @@ final class ProfilesFragment extends ToolbarFragment with Toolbar.OnMenuItemClic ...@@ -352,21 +352,16 @@ final class ProfilesFragment extends ToolbarFragment with Toolbar.OnMenuItemClic
def onMenuItemClick(item: MenuItem): Boolean = item.getItemId match { def onMenuItemClick(item: MenuItem): Boolean = item.getItemId match {
case R.id.action_scan_qr_code => case R.id.action_scan_qr_code =>
def installScanner() = {
Toast.makeText(getActivity, R.string.add_profile_scanner_not_installed, Toast.LENGTH_LONG).show()
try startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.zxing.client.android"))) catch {
case exc: ActivityNotFoundException => exc.printStackTrace()
}
}
try startActivityForResult(new Intent("com.google.zxing.client.android.SCAN") try startActivityForResult(new Intent("com.google.zxing.client.android.SCAN")
.addCategory(Intent.CATEGORY_DEFAULT) .addCategory(Intent.CATEGORY_DEFAULT)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_DOCUMENT), .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_DOCUMENT),
REQUEST_SCAN_QR_CODE) catch { REQUEST_SCAN_QR_CODE) catch {
case _: ActivityNotFoundException => installScanner() case _: ActivityNotFoundException =>
startActivity(new Intent(getActivity, classOf[ScannerActivity]))
case e: SecurityException => case e: SecurityException =>
e.printStackTrace() e.printStackTrace()
app.track(e) app.track(e)
installScanner() startActivity(new Intent(getActivity, classOf[ScannerActivity]))
} }
true true
case R.id.action_import => case R.id.action_import =>
......
/*******************************************************************************/
/* */
/* Copyright (C) 2016 by Max Lv <max.c.lv@gmail.com> */
/* Copyright (C) 2016 by Mygod Studio <contact-shadowsocks-android@mygod.be> */
/* */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation, either version 3 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*******************************************************************************/
package com.github.shadowsocks
import android.app.{Activity, TaskStackBuilder}
import android.content.Intent
import android.content.pm.{PackageManager, ShortcutManager}
import android.os.{Build, Bundle}
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.text.TextUtils
import android.widget.Toast
import com.google.zxing.Result
import com.github.shadowsocks.ShadowsocksApplication.app
import com.github.shadowsocks.utils.Parser
import me.dm7.barcodescanner.zxing.ZXingScannerView
object ScannerActivity {
private final val MY_PERMISSIONS_REQUEST_CAMERA = 1
}
class ScannerActivity extends AppCompatActivity with ZXingScannerView.ResultHandler {
import ScannerActivity._
private var scannerView: ZXingScannerView = _
override def onRequestPermissionsResult(requestCode: Int, permissions: Array[String],
grantResults: Array[Int]) {
if (requestCode == MY_PERMISSIONS_REQUEST_CAMERA) {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults(0) == PackageManager.PERMISSION_GRANTED) {
scannerView.setResultHandler(this)
scannerView.startCamera()
} else {
Toast.makeText(this, R.string.add_profile_scanner_permission_required, Toast.LENGTH_SHORT).show()
finish()
}
}
}
def navigateUp() {
val intent = getParentActivityIntent
if (shouldUpRecreateTask(intent) || isTaskRoot)
TaskStackBuilder.create(this).addNextIntentWithParentStack(intent).startActivities()
else finish()
}
override def onCreate(state: Bundle) {
super.onCreate(state)
setContentView(R.layout.layout_scanner)
val toolbar = findViewById(R.id.toolbar).asInstanceOf[Toolbar]
toolbar.setTitle(getTitle)
toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_material)
toolbar.setNavigationOnClickListener(_ => navigateUp())
scannerView = findViewById(R.id.scanner).asInstanceOf[ZXingScannerView]
if (Build.VERSION.SDK_INT >= 25) getSystemService(classOf[ShortcutManager]).reportShortcutUsed("scan")
}
override def onResume() {
super.onResume()
val permissionCheck = ContextCompat.checkSelfPermission(this,
android.Manifest.permission.CAMERA)
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
scannerView.setResultHandler(this) // Register ourselves as a handler for scan results.
scannerView.startCamera() // Start camera on resume
} else {
ActivityCompat.requestPermissions(this,
Array(android.Manifest.permission.CAMERA), MY_PERMISSIONS_REQUEST_CAMERA)
}
}
override def onPause() {
super.onPause()
scannerView.stopCamera() // Stop camera on pause
}
override def handleResult(rawResult: Result) = {
val uri = rawResult.getText
if (!TextUtils.isEmpty(uri))
Parser.findAll(uri).foreach(app.profileManager.createProfile)
navigateUp()
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment