diff --git a/build.sbt b/build.sbt
index cb4a85590f..b641dfc448 100644
--- a/build.sbt
+++ b/build.sbt
@@ -55,6 +55,7 @@ libraryDependencies ++=
"com.twofortyfouram" % "android-plugin-api-for-locale" % "1.0.2" ::
"dnsjava" % "dnsjava" % "2.1.7" ::
"eu.chainfire" % "libsuperuser" % "1.0.0.+" ::
+ "me.dm7.barcodescanner" % "zxing" % "1.9.8" ::
"net.glxn.qrgen" % "android" % "2.0" ::
"com.squareup.okhttp3" % "okhttp" % "3.8.0" ::
"com.google.code.findbugs" % "jsr305" % "1.3.+" ::
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 1bf14c83f3..b7abdae63d 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -7,6 +7,7 @@
+
@@ -16,6 +17,8 @@
android:required="false"/>
+
- val dialog = new AlertDialog.Builder(this, R.style.Theme_Material_Dialog_Alert)
+ /*val dialog = new AlertDialog.Builder(this, R.style.Theme_Material_Dialog_Alert)
.setTitle(R.string.scan_qrcode_install_title)
.setPositiveButton(android.R.string.yes, ((_, _) => {
val marketUri = Uri.parse("market://details?id=com.google.zxing.client.android")
@@ -586,7 +586,9 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
.setNegativeButton(android.R.string.no, ((_, _) => finish()): DialogInterface.OnClickListener)
.setMessage(R.string.scan_qrcode_install_text)
.create()
- dialog.show()
+ dialog.show()*/
+ menu.toggle(false)
+ startActivity(new Intent(this, classOf[ScannerActivity]))
}
}
diff --git a/src/main/scala/com/github/shadowsocks/ScannerActivity.scala b/src/main/scala/com/github/shadowsocks/ScannerActivity.scala
new file mode 100644
index 0000000000..8d203f073a
--- /dev/null
+++ b/src/main/scala/com/github/shadowsocks/ScannerActivity.scala
@@ -0,0 +1,92 @@
+
+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.setAutoFocus(true)
+ 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)
+ Parser.findAll_ssr(uri).foreach(app.profileManager.createProfile)
+ }
+ navigateUp()
+ }
+}
+