diff --git a/SampleApp/build.gradle b/SampleApp/build.gradle index 01d4c570..fd30195a 100644 --- a/SampleApp/build.gradle +++ b/SampleApp/build.gradle @@ -1,14 +1,16 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:3.0.1' } } repositories { jcenter() + google() maven { url "https://jitpack.io" } @@ -17,13 +19,12 @@ repositories { apply plugin: 'com.android.application' android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 27 defaultConfig { applicationId "io.card.development" minSdkVersion 18 - targetSdkVersion 25 + targetSdkVersion 27 versionCode 1 versionName "1.0.0" testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner' @@ -37,10 +38,9 @@ android { } android.applicationVariants.all { variant -> - variant.outputs.each { output -> - def outputFile = output.outputFile - if (outputFile != null && outputFile.name.endsWith('.apk')) { - output.outputFile = new File(outputFile.parent, "card.io-sample-app-${variant.name}.apk") + variant.outputs.all { + if (outputFileName.endsWith('.apk')) { + outputFileName = "card.io-sample-app-${variant.name}.apk" } } } @@ -48,13 +48,11 @@ android { dependencies { if (parent != null) { - compile project(':card.io') + implementation project(':card.io') } else { - compile 'io.card:android-sdk:REPLACE_VERSION' + implementation 'io.card:android-sdk:REPLACE_VERSION' } - - debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4' - - androidTestCompile "com.android.support.test.espresso:espresso-core:2.2.2" - androidTestCompile "com.github.lkorth:device-automator:01d85912ec" + debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.4' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2-alpha1' + androidTestImplementation 'com.github.lkorth:device-automator:01d85912ec' } diff --git a/SampleApp/src/main/java/io/card/development/SampleActivity.java b/SampleApp/src/main/java/io/card/development/SampleActivity.java index ac3a5120..8c8aa7b0 100644 --- a/SampleApp/src/main/java/io/card/development/SampleActivity.java +++ b/SampleApp/src/main/java/io/card/development/SampleActivity.java @@ -56,6 +56,8 @@ public class SampleActivity extends Activity { private CheckBox mUseCardIOLogoToggle; private CheckBox mShowPayPalActionBarIconToggle; private CheckBox mKeepApplicationThemeToggle; + private CheckBox mLockOrientationToggle; + private CheckBox mAddOverlayToggle; private Spinner mLanguageSpinner; private EditText mUnblurEdit; @@ -64,29 +66,32 @@ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.sample_activity); - mManualToggle = (CheckBox) findViewById(R.id.force_manual); - mEnableExpiryToggle = (CheckBox) findViewById(R.id.gather_expiry); - mScanExpiryToggle = (CheckBox) findViewById(R.id.scan_expiry); - mCvvToggle = (CheckBox) findViewById(R.id.gather_cvv); - mPostalCodeToggle = (CheckBox) findViewById(R.id.gather_postal_code); - mPostalCodeNumericOnlyToggle = (CheckBox) findViewById(R.id.postal_code_numeric_only); - mCardholderNameToggle = (CheckBox) findViewById(R.id.gather_cardholder_name); - mSuppressManualToggle = (CheckBox) findViewById(R.id.suppress_manual); - mSuppressConfirmationToggle = (CheckBox) findViewById(R.id.suppress_confirmation); - mSuppressScanToggle = (CheckBox) findViewById(R.id.detect_only); - - mUseCardIOLogoToggle = (CheckBox) findViewById(R.id.use_card_io_logo); - mShowPayPalActionBarIconToggle = (CheckBox) findViewById(R.id.show_paypal_action_bar_icon); - mKeepApplicationThemeToggle = (CheckBox) findViewById(R.id.keep_application_theme); - - mLanguageSpinner = (Spinner) findViewById(R.id.language); - mUnblurEdit = (EditText) findViewById(R.id.unblur); - - mResultLabel = (TextView) findViewById(R.id.result); - mResultImage = (ImageView) findViewById(R.id.result_image); - mResultCardTypeImage = (ImageView) findViewById(R.id.result_card_type_image); - - TextView version = (TextView) findViewById(R.id.version); + mManualToggle = findViewById(R.id.force_manual); + mEnableExpiryToggle = findViewById(R.id.gather_expiry); + mScanExpiryToggle = findViewById(R.id.scan_expiry); + mCvvToggle = findViewById(R.id.gather_cvv); + mPostalCodeToggle = findViewById(R.id.gather_postal_code); + mPostalCodeNumericOnlyToggle = findViewById(R.id.postal_code_numeric_only); + mCardholderNameToggle = findViewById(R.id.gather_cardholder_name); + mSuppressManualToggle = findViewById(R.id.suppress_manual); + mSuppressConfirmationToggle = findViewById(R.id.suppress_confirmation); + mSuppressScanToggle = findViewById(R.id.detect_only); + + mUseCardIOLogoToggle = findViewById(R.id.use_card_io_logo); + mShowPayPalActionBarIconToggle = findViewById(R.id.show_paypal_action_bar_icon); + mKeepApplicationThemeToggle = findViewById(R.id.keep_application_theme); + + mLockOrientationToggle = findViewById(R.id.lock_orientation); + mAddOverlayToggle = findViewById(R.id.add_overlay); + + mLanguageSpinner = findViewById(R.id.language); + mUnblurEdit = findViewById(R.id.unblur); + + mResultLabel = findViewById(R.id.result); + mResultImage = findViewById(R.id.result_image); + mResultCardTypeImage = findViewById(R.id.result_card_type_image); + + TextView version = findViewById(R.id.version); version.setText("card.io library: " + CardIOActivity.sdkVersion() + "\n" + "Build date: " + CardIOActivity.sdkBuildDate()); @@ -116,11 +121,16 @@ public void onScan(View pressed) { .putExtra(CardIOActivity.EXTRA_LANGUAGE_OR_LOCALE, (String) mLanguageSpinner.getSelectedItem()) .putExtra(CardIOActivity.EXTRA_USE_PAYPAL_ACTIONBAR_ICON, mShowPayPalActionBarIconToggle.isChecked()) .putExtra(CardIOActivity.EXTRA_KEEP_APPLICATION_THEME, mKeepApplicationThemeToggle.isChecked()) + .putExtra(CardIOActivity.EXTRA_LOCK_ORIENTATION, mLockOrientationToggle.isChecked()) .putExtra(CardIOActivity.EXTRA_GUIDE_COLOR, Color.GREEN) .putExtra(CardIOActivity.EXTRA_SUPPRESS_CONFIRMATION, mSuppressConfirmationToggle.isChecked()) .putExtra(CardIOActivity.EXTRA_SUPPRESS_SCAN, mSuppressScanToggle.isChecked()) .putExtra(CardIOActivity.EXTRA_RETURN_CARD_IMAGE, true); + if (mAddOverlayToggle.isChecked()) { + intent.putExtra(CardIOActivity.EXTRA_SCAN_OVERLAY_LAYOUT_ID, R.layout.overlay_layout); + } + try { int unblurDigits = Integer.parseInt(mUnblurEdit.getText().toString()); intent.putExtra(CardIOActivity.EXTRA_UNBLUR_DIGITS, unblurDigits); diff --git a/SampleApp/src/main/res/layout/overlay_layout.xml b/SampleApp/src/main/res/layout/overlay_layout.xml new file mode 100644 index 00000000..1906e5e9 --- /dev/null +++ b/SampleApp/src/main/res/layout/overlay_layout.xml @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/SampleApp/src/main/res/layout/sample_activity.xml b/SampleApp/src/main/res/layout/sample_activity.xml index 5444e783..59b39029 100644 --- a/SampleApp/src/main/res/layout/sample_activity.xml +++ b/SampleApp/src/main/res/layout/sample_activity.xml @@ -110,6 +110,18 @@ android:layout_height="wrap_content" android:text="Keep application theme"/> + + + + true, the scanner view will + * remain in portrait mode. Default value is {@code false}. + */ + public static final String EXTRA_LOCK_ORIENTATION = "io.card.payment.lockOrientation"; + /** * Boolean extra. Used for testing only. @@ -305,6 +311,8 @@ public final class CardIOActivity extends Activity { private boolean manualEntryFallbackOrForced = false; + private boolean mOrientationLocked; + /** * Static variable for the decorated card image. This is ugly, but works. Parceling and * unparceling card image data to pass to the next {@link android.app.Activity} does not work because the image @@ -326,6 +334,8 @@ protected void onCreate(Bundle savedInstanceState) { final Intent clientData = this.getIntent(); + mOrientationLocked = clientData.getBooleanExtra(EXTRA_LOCK_ORIENTATION, false); + useApplicationTheme = getIntent().getBooleanExtra(CardIOActivity.EXTRA_KEEP_APPLICATION_THEME, false); ActivityHelper.setActivityTheme(this, useApplicationTheme); @@ -468,13 +478,15 @@ private void showCameraScannerOverlay() { setPreviewLayout(); - orientationListener = new OrientationEventListener(this, - SensorManager.SENSOR_DELAY_UI) { - @Override - public void onOrientationChanged(int orientation) { - doOrientationChange(orientation); - } - }; + if (!mOrientationLocked) { + orientationListener = new OrientationEventListener(this, + SensorManager.SENSOR_DELAY_UI) { + @Override + public void onOrientationChanged(int orientation) { + doOrientationChange(orientation); + } + }; + } } catch (Exception e) { handleGeneralExceptionError(e); @@ -497,7 +509,7 @@ private void doOrientationChange(int orientation) { return; } - orientation += mCardScanner.getRotationalOffset(); + orientation += mOrientationLocked ? 0 : mCardScanner.getRotationalOffset(); // Check if we have gone too far forward with // rotation adjustment, keep the result between 0-360 @@ -560,7 +572,10 @@ protected void onResume() { ActivityHelper.setFlagSecure(this); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - orientationListener.enable(); + + if (orientationListener != null && !mOrientationLocked) { + orientationListener.enable(); + } if (!restartPreview()) { StringKey error = StringKey.ERROR_CAMERA_UNEXPECTED_FAIL; @@ -571,7 +586,7 @@ protected void onResume() { setFlashOn(false); } - doOrientationChange(mLastDegrees); + doOrientationChange(mOrientationLocked ? 0 : mLastDegrees); } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0a48d7d6..d09d2ec7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip