diff --git a/build.sbt b/build.sbt index 11342b6bc2..079b67795b 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 6b7c4a3302..9bb5bf5619 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -1,12 +1,13 @@ + @@ -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() + } +} +