Add Internal Activity for QR Code Scanner (#1556)

* add internal QR Scanner Activity

* add CAMERA permission to Manifest

* add dimension for Button Height

* remove non-existent RestartActivity from Manifest

* accept licenses for Android SDK 29

* rollback gradle to 3.6.3

* add dependency for zxing:core:3.3.0 to support Android API 14+
This commit is contained in:
Sumit Anantwar 2020-10-09 09:52:38 +03:00 committed by GitHub
parent 16d4f532a9
commit e12663f321
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 157 additions and 11 deletions

View File

@ -26,6 +26,7 @@ before_install:
- eval "$(gimme stable)"
# Hack to accept Android licenses
- yes | sdkmanager "platforms;android-28"
- yes | sdkmanager "platforms;android-29"
# Cache gradle dependencies
# https://docs.travis-ci.com/user/languages/android/#Caching

View File

@ -7,12 +7,15 @@ plugins {
dependencies {
implementation 'eu.chainfire:libsuperuser:1.1.0.202004101746'
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.google.zxing:android-integration:3.3.0'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'org.mindrot:jbcrypt:0.4'
implementation 'com.google.guava:guava:29.0-android'
implementation 'com.annimon:stream:1.2.1'
implementation 'com.android.volley:volley:1.1.1'
implementation ('com.journeyapps:zxing-android-embedded:3.6.0') { transitive = false }
implementation 'com.google.zxing:core:3.3.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.dagger:dagger:2.29.1'
annotationProcessor "com.google.dagger:dagger-compiler:2.29.1"

View File

@ -21,6 +21,8 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- ACCESS_FINE_LOCATION is required to get WiFi's SSID on 10 "Q" -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- CAMERA is required for the QR Code Scanner -->
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="false"
@ -95,9 +97,6 @@
android:name="android.support.UI_OPTIONS"
android:value="splitActionBarWhenNarrow" />
</activity>
<activity android:name=".activities.RestartActivity"
android:theme="@style/Theme.Syncthing.Translucent"
android:launchMode="singleTop"/>
<activity android:name=".activities.DeviceActivity"
android:parentActivityName=".activities.MainActivity">
<meta-data
@ -154,6 +153,13 @@
android:name="android.support.PARENT_ACTIVITY"
android:value="com.nutomic.syncthingandroid.activities.FolderActivity" />
</activity>
<activity android:name=".activities.QRScannerActivity"
android:label="QR Code Scanner"
android:parentActivityName=".activities.DeviceActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.nutomic.syncthingandroid.activities.DeviceActivity" />
</activity>
</application>
</manifest>

View File

@ -1,5 +1,6 @@
package com.nutomic.syncthingandroid.activities;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
@ -61,6 +62,7 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
private static final String IS_SHOWING_DISCARD_DIALOG = "DISCARD_FOLDER_DIALOG_STATE";
private static final String IS_SHOWING_COMPRESSION_DIALOG = "COMPRESSION_FOLDER_DIALOG_STATE";
private static final String IS_SHOWING_DELETE_DIALOG = "DELETE_FOLDER_DIALOG_STATE";
private static final int QR_SCAN_REQUEST_CODE = 777;
private static final List<String> DYNAMIC_ADDRESS = Collections.singletonList("dynamic");
@ -393,10 +395,14 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanResult != null) {
mDevice.deviceID = scanResult.getContents();
mIdView.setText(mDevice.deviceID);
if (requestCode == QR_SCAN_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
String scanResult = intent.getStringExtra(QRScannerActivity.QR_RESULT_ARG);
if (scanResult != null) {
mDevice.deviceID = scanResult;
mIdView.setText(mDevice.deviceID);
}
}
}
}
@ -448,8 +454,8 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
if (v.equals(mCompressionContainer)) {
showCompressionDialog();
} else if (v.equals(mQrButton)){
IntentIntegrator integrator = new IntentIntegrator(DeviceActivity.this);
integrator.initiateScan();
Intent qrIntent = QRScannerActivity.intent(this);
startActivityForResult(qrIntent, QR_SCAN_REQUEST_CODE);
} else if (v.equals(mIdContainer)) {
Util.copyDeviceId(this, mDevice.deviceID);
}

View File

@ -0,0 +1,104 @@
package com.nutomic.syncthingandroid.activities;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.zxing.ResultPoint;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import com.nutomic.syncthingandroid.R;
import java.util.List;
public class QRScannerActivity extends ThemedAppCompatActivity implements BarcodeCallback {
// region === Static ===
static final String QR_RESULT_ARG = "QR_CODE";
static Intent intent(Context context) {
return new Intent(context, QRScannerActivity.class);
}
// endregion
private final int RC_HANDLE_CAMERA_PERM = 888;
private DecoratedBarcodeView barcodeView;
private TextView cancleButton;
// region === Activity Lifecycle ===
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_qr_scanner);
this.barcodeView = findViewById(R.id.bar_code_scanner_view);
findViewById(R.id.cancel_button).setOnClickListener(view -> {
pauseScanner();
finish();
});
checkPermissionAndStartScanner();
}
// endregion
// region === Permissions Callback ===
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == RC_HANDLE_CAMERA_PERM) {
if (grantResults.length !=0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startScanner();
} else {
finish();
}
}
}
// endregion
// region === BarcodeCallback ===
@Override
public void barcodeResult(BarcodeResult result) {
String code = result.getText();
Intent intent = new Intent();
intent.putExtra(QR_RESULT_ARG, code);
setResult(Activity.RESULT_OK, intent);
finish();
}
@Override
public void possibleResultPoints(List<ResultPoint> resultPoints) {
// Unused
}
// endregion
// region === Private Methods ===
private void checkPermissionAndStartScanner() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
String[] permissions = {Manifest.permission.CAMERA};
ActivityCompat.requestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM);
} else {
startScanner();
}
}
private void startScanner() {
this.barcodeView.resume();
this.barcodeView.decodeSingle(this);
}
private void pauseScanner() {
this.barcodeView.pause();
}
// endregion
}

View File

@ -0,0 +1,24 @@
<?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">
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:id="@+id/bar_code_scanner_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<TextView
android:id="@+id/cancel_button"
android:layout_width="match_parent"
android:layout_height="@dimen/button_height"
android:background="@android:color/black"
android:fontFamily="sans-serif"
android:gravity="center"
android:text="@string/cancel_title"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>

View File

@ -10,4 +10,5 @@
<dimen name="slide_title">30sp</dimen>
<dimen name="slide_desc">16sp</dimen>
<dimen name="desc_padding">40dp</dimen>
<dimen name="button_height">44dp</dimen>
</resources>

View File

@ -1,5 +1,6 @@
#Mon Oct 05 14:20:28 EEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.2-bin.zip