Refactor: SDK 28, androidx, ... (#221)

This commit is contained in:
Jonas Bögle 2019-05-06 09:01:33 +02:00 committed by ligi
parent b95ff6d63a
commit a6baee2ca2
157 changed files with 1093 additions and 1134 deletions

1
.gitignore vendored
View file

@ -5,7 +5,6 @@ build
bin
gen
project.properties
gradle.properties
local.properties
*iml

View file

@ -1,5 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'spoon'
apply plugin: 'com.jaredsburrows.spoon'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
@ -10,20 +10,21 @@ apply plugin: 'com.github.triplet.play'
repositories {
jcenter()
mavenLocal()
google()
maven { url 'https://jitpack.io' }
maven { url 'https://maven.google.com' }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } // For Spoon snapshot, until 2.0.0 is released
}
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
versionCode 349
versionName "3.4.9"
minSdkVersion 9
targetSdkVersion 25
minSdkVersion 14
targetSdkVersion 28
applicationId "org.ligi.passandroid"
testInstrumentationRunner "org.ligi.passandroid.AppReplacingRunner"
archivesBaseName = "PassAndroid-$versionName"
@ -62,6 +63,14 @@ android {
}
}
// hacky workaround to add spoon task that executes all variants
task spoon {
dependsOn {
tasks.findAll { task -> task.name != 'spoon' && task.name.startsWith('spoon') }
}
}
android.variantFilter { variant ->
def maps = variant.getFlavors().get(0).name
def analytics = variant.getFlavors().get(1).name
@ -85,7 +94,6 @@ android {
exclude 'META-INF/maven/com.google.guava/guava/pom.properties'
exclude 'META-INF/maven/com.google.guava/guava/pom.xml'
}
lintOptions {
@ -100,100 +108,97 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
}
}
}
configurations {
// http://stackoverflow.com/questions/30578243/why-would-adding-espresso-contrib-cause-an-inflateexception
androidTestCompile.exclude group: 'com.android.support', module: 'appcompat-v7'
androidTestCompile.exclude group: 'com.android.support', module: 'design'
androidTestCompile.exclude group: 'com.android.support', module: 'support-v4'
androidTestCompile.exclude group: 'com.android.support', module: 'support-annotations'
androidTestCompile.exclude group: 'com.android.support', module: 'preference-v7'
androidTestCompile.exclude module: 'recyclerview-v7'
androidTestCompile.exclude module: 'kotlin-stdlib'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
dependencies {
compile 'com.github.hotchemi:permissionsdispatcher:2.3.2'
kapt 'com.github.hotchemi:permissionsdispatcher-processor:2.3.2'
implementation 'org.permissionsdispatcher:permissionsdispatcher:4.3.0'
kapt 'org.permissionsdispatcher:permissionsdispatcher-processor:4.3.0'
compile 'com.github.salomonbrys.kodein:kodein:4.1.0'
implementation 'com.github.salomonbrys.kodein:kodein:4.1.0'
compileOnly 'org.glassfish:javax.annotation:3.1.1'
provided 'org.glassfish:javax.annotation:10.0-b28'
// spoon snapshot, until 2.0.0 is released
androidTestImplementation 'com.squareup.spoon:spoon-client:2.0.0-SNAPSHOT'
androidTestImplementation 'com.github.ligi:trulesk:0.28'
androidTestImplementation 'androidx.test:core:1.1.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.1'
androidTestImplementation 'com.squareup.assertj:assertj-android:1.2.0'
androidTestImplementation "org.mockito:mockito-core:$mockito_version"
androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.21.0'
androidTestImplementation 'com.google.code.findbugs:jsr305:3.0.2'
androidTestImplementation 'androidx.appcompat:appcompat:1.0.2'
androidTestImplementation 'com.google.android.material:material:1.0.0'
androidTestCompile 'com.github.ligi:trulesk:0.21'
implementation 'com.github.ligi:TouchImageView:2.1'
implementation 'com.github.ligi:ExtraCompats:0.5'
implementation 'net.lingala.zip4j:zip4j:1.3.2'
implementation 'com.jakewharton.threetenabp:threetenabp:1.2.0'
implementation 'org.greenrobot:eventbus:3.1.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:3.0.1'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.preference:preference:1.0.0'
implementation 'androidx.annotation:annotation:1.0.2'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'net.i2p.android.ext:floatingactionbutton:1.10.1'
androidTestCompile 'com.squareup.assertj:assertj-android:1.1.1'
implementation 'com.github.ligi:KAXT:0.22'
implementation 'com.github.ligi:KAXTUI:0.8'
implementation 'com.github.ligi:loadtoast:1.10.11'
implementation 'com.github.ligi:tracedroid:2.1'
androidTestCompile "org.mockito:mockito-core:$mockito_version"
androidTestCompile 'com.linkedin.dexmaker:dexmaker-mockito:2.2.0'
forPlayImplementation 'com.github.ligi.snackengage:snackengage-playrate:0.18'
forFDroidImplementation 'com.github.ligi.snackengage:snackengage-playrate:0.18'
forAmazonImplementation 'com.github.ligi.snackengage:snackengage-amazonrate:0.18'
androidTestCompile 'com.google.code.findbugs:jsr305:3.0.2'
// https://medium.com/square-corner-blog/okhttp-3-13-requires-android-5-818bb78d07ce
// Don't update to >=3.13 before minSDK 21 + Java 8
//noinspection GradleDependency
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
androidTestCompile "com.android.support:appcompat-v7:$support_version"
androidTestCompile "com.android.support:design:$support_version"
implementation 'com.larswerkman:HoloColorPicker:1.5'
implementation 'com.google.code.findbugs:jsr305:3.0.2'
compile 'com.github.ligi:TouchImageView:2.1'
compile 'com.github.ligi:ExtraCompats:0.4'
// https://github.com/square/moshi/issues/738
// either wait for ProGuard update or use R8 instead (android.enableR8=true)
//noinspection GradleDependency
implementation 'com.squareup.moshi:moshi:1.7.0'
compile 'net.lingala.zip4j:zip4j:1.3.2'
compile 'com.jakewharton.threetenabp:threetenabp:1.1.0'
compile 'org.greenrobot:eventbus:3.0.0'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "com.android.support:support-annotations:$support_version"
compile "com.android.support:recyclerview-v7:$support_version"
compile "com.android.support:appcompat-v7:$support_version"
compile "com.android.support:cardview-v7:$support_version"
compile "com.android.support:design:$support_version"
compile "com.android.support:preference-v7:$support_version"
compile 'net.i2p.android.ext:floatingactionbutton:1.10.1'
compile 'com.github.ligi:KAXT:0.20'
compile 'com.github.ligi:KAXTUI:0.4'
compile 'com.github.ligi:loadtoast:1.10.11'
compile 'com.github.ligi:tracedroid:1.4'
forPlayCompile 'com.github.ligi.snackengage:snackengage-playrate:0.15'
forFDroidCompile 'com.github.ligi.snackengage:snackengage-playrate:0.15'
forAmazonCompile 'com.github.ligi.snackengage:snackengage-amazonrate:0.15'
compile 'com.squareup.okhttp3:okhttp:3.11.0'
compile 'com.larswerkman:HoloColorPicker:1.5'
compile 'com.google.code.findbugs:jsr305:3.0.2'
compile 'com.squareup.moshi:moshi:1.4.0'
compile "com.chibatching.kotpref:kotpref:2.6.0"
compile "com.chibatching.kotpref:initializer:2.6.0"
testCompile "com.android.support:support-annotations:$support_version"
testCompile 'com.squareup.assertj:assertj-android:1.1.1'
testCompile 'junit:junit:4.12'
testCompile "org.mockito:mockito-core:${mockito_version}"
testCompile 'org.threeten:threetenbp:1.3.7'
implementation 'com.chibatching.kotpref:kotpref:2.6.0'
implementation 'com.chibatching.kotpref:initializer:2.6.0'
testImplementation 'androidx.annotation:annotation:1.0.2'
testImplementation 'com.squareup.assertj:assertj-android:1.2.0'
testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-core:$mockito_version"
testImplementation 'org.threeten:threetenbp:1.3.8'
// https://github.com/ligi/PassAndroid/issues/181
// Don't update to 3.3.1 before minSDK 19 - or replace zxing
compile 'com.google.zxing:core:3.3.0'
// Don't upgrade before minSDK 19 - or replace zxing
//noinspection GradleDependency
implementation 'com.google.zxing:core:3.3.0'
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
withAnalyticsCompile "com.google.android.gms:play-services-analytics:$play_version"
withMapsCompile "com.google.android.gms:play-services-maps:$play_version"
// requires minSDK 16 according to docs, not sure if it causes an issue
withAnalyticsImplementation 'com.google.android.gms:play-services-analytics:16.0.8'
withMapsImplementation 'com.google.android.gms:play-services-maps:16.1.0'
}
spoon {
debug = true
grantAllPermissions = true
grantAll = true
baseOutputDir = "build/spoon"
}
play {
jsonFile = file('/media/ligi/USBCRED/play.json')
uploadImages = true
}
}

View file

@ -20,31 +20,24 @@
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# optimize
-optimizationpasses 2
-optimizations !code/simplification/arithmetic
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-optimizationpasses 2
-optimizations !code/simplification/arithmetic
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
# AppCompat
# Keep line numbers to alleviate debugging stack traces
-dontwarn android.support.v7.**
-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }
# Keep line numbers to alleviate debugging stack traces
-renamesourcefileattribute SourceFile
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
### for api client
-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
-keepclassmembers class * {
@ -54,7 +47,6 @@
# Needed by Guava
# See https://groups.google.com/forum/#!topic/guava-discuss/YCZzeCiIVoI
-dontwarn sun.misc.Unsafe
-dontwarn com.google.common.collect.MinMaxPriorityQueue
@ -72,9 +64,6 @@
-keep class **$$ViewBinder { *; }
-keepnames class * { @butterknife.Bind *;}
#### for support 22
-dontwarn android.support.**
#### for guava
-dontwarn javax.annotation.**
-dontwarn javax.inject.**
@ -105,23 +94,20 @@
-dontwarn java.nio.file.OpenOption
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-keep public class com.google.android.gms.**
-dontwarn com.google.android.gms.**
## New rules for EventBus 3.0.x ##
# http://greenrobot.org/eventbus/documentation/proguard/
-keepattributes *Annotation*
-keepclassmembers class ** {
-keepclassmembers class * {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
}
### for moshi

View file

@ -15,7 +15,7 @@
"message":"",
"transfer":"barcode_QR",
"alternative": {
"order":1,
"order":1
}
},

View file

@ -60,6 +60,6 @@ class TestApp : App() {
fixedPassListPassStore().setList(emptyList())
}
fun fixedPassListPassStore() = passStore() as FixedPassListPassStore
private fun fixedPassListPassStore() = passStore() as FixedPassListPassStore
}
}

View file

@ -3,14 +3,14 @@ package org.ligi.passandroid
import android.app.Activity.RESULT_CANCELED
import android.app.Instrumentation
import android.provider.CalendarContract
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.intent.Intents.intended
import android.support.test.espresso.intent.Intents.intending
import android.support.test.espresso.intent.matcher.IntentMatchers.hasExtra
import android.support.test.espresso.intent.matcher.IntentMatchers.hasType
import android.support.test.espresso.matcher.ViewMatchers.*
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.Intents.intending
import androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra
import androidx.test.espresso.intent.matcher.IntentMatchers.hasType
import androidx.test.espresso.matcher.ViewMatchers.*
import org.hamcrest.CoreMatchers.not
import org.hamcrest.Matchers.allOf
import org.junit.Rule
@ -23,8 +23,8 @@ import org.threeten.bp.ZonedDateTime
class TheAddToCalendar {
val time = ZonedDateTime.now()
val time2 = ZonedDateTime.now().plusHours(3)
private val time = ZonedDateTime.now()
private val time2 = ZonedDateTime.now().plusHours(3)
@get:Rule
var rule = TruleskIntentRule(PassListActivity::class.java, false)

View file

@ -1,13 +1,13 @@
package org.ligi.passandroid
import android.support.test.espresso.Espresso.closeSoftKeyboard
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.*
import android.support.test.espresso.assertion.ViewAssertions.doesNotExist
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.*
import android.support.test.filters.SdkSuppress
import android.support.test.runner.AndroidJUnit4
import androidx.test.espresso.Espresso.closeSoftKeyboard
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.*
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import com.github.salomonbrys.kodein.instance
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
@ -27,9 +27,11 @@ class TheBarCodeEditing {
val passStore: PassStore = App.kodein.instance()
lateinit var currentPass: PassImpl
private lateinit var currentPass: PassImpl
fun start(setupPass: (pass: PassImpl) -> Unit = {}) {
private fun start(setupPass: (pass: PassImpl) -> Unit = {}) {
TestApp.populatePassStoreWithSinglePass()
currentPass = passStore.currentPass as PassImpl

View file

@ -1,6 +1,5 @@
package org.ligi.passandroid
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Fail.fail
import org.junit.Test
@ -48,7 +47,6 @@ class TheBarcodeHelper {
} catch (e: Exception) {
fail("could not create barcode", e)
}
}
fun testBitmapSizeIsSane(format: PassBarCodeFormat) {
@ -59,6 +57,5 @@ class TheBarcodeHelper {
} catch (e: Exception) {
fail("could not create barcode", e)
}
}
}

View file

@ -1,9 +1,9 @@
package org.ligi.passandroid
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.withId
import android.support.test.espresso.matcher.ViewMatchers.withText
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import org.hamcrest.CoreMatchers.containsString
import org.junit.Rule
import org.junit.Test

View file

@ -1,10 +1,10 @@
package org.ligi.passandroid
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.isDisplayed
import android.support.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import org.junit.Rule
import org.junit.Test
import org.ligi.passandroid.R.id.emptyView

View file

@ -1,10 +1,10 @@
package org.ligi.passandroid
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.replaceText
import android.support.test.espresso.action.ViewActions.scrollTo
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.*
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.action.ViewActions.scrollTo
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import org.junit.Test

View file

@ -2,10 +2,10 @@ package org.ligi.passandroid
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.isDisplayed
import android.support.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import android.widget.ImageView
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
@ -19,9 +19,9 @@ import org.ligi.passandroid.ui.FullscreenBarcodeActivity
import org.ligi.trulesk.TruleskIntentRule
import java.util.*
class TheFullscreenBarcodeActivity {
private const val BARCODE_MESSAGE = "2323"
private val BARCODE_MESSAGE = "2323"
class TheFullscreenBarcodeActivity {
@get:Rule
var rule = TruleskIntentRule(FullscreenBarcodeActivity::class.java, false)
@ -78,11 +78,11 @@ class TheFullscreenBarcodeActivity {
val bitmap = bitmapDrawable.bitmap
val bitmapToTest: Bitmap
if (format === PassBarCodeFormat.AZTEC) {
bitmapToTest = if (format === PassBarCodeFormat.AZTEC) {
// not sure why - but for the decoder to pick up AZTEC it must have moar pixelz - smells like a zxing bug
bitmapToTest = Bitmap.createScaledBitmap(bitmap, bitmap.width * 2, bitmap.height * 2, false)
Bitmap.createScaledBitmap(bitmap, bitmap.width * 2, bitmap.height * 2, false)
} else {
bitmapToTest = bitmap
bitmap
}
assertThat(bitmapToTest.decodeBarCode()).isEqualTo(BARCODE_MESSAGE)

View file

@ -1,9 +1,9 @@
package org.ligi.passandroid
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.*
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import org.junit.Test

View file

@ -5,15 +5,15 @@ import android.app.Activity.RESULT_CANCELED
import android.app.Instrumentation.ActivityResult
import android.content.Intent.ACTION_SEND
import android.content.Intent.ACTION_VIEW
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.Espresso.pressBack
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.contrib.DrawerActions.open
import android.support.test.espresso.intent.Intents.intended
import android.support.test.espresso.intent.Intents.intending
import android.support.test.espresso.intent.matcher.IntentMatchers.*
import android.support.test.espresso.matcher.ViewMatchers.*
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.Espresso.pressBack
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.DrawerActions.open
import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.Intents.intending
import androidx.test.espresso.intent.matcher.IntentMatchers.*
import androidx.test.espresso.matcher.ViewMatchers.*
import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.not
import org.junit.Rule
@ -61,19 +61,6 @@ class TheNavigationDrawer {
intended(allOf(hasAction(ACTION_VIEW), hasData("https://play.google.com/apps/testing/org.ligi.passandroid")))
}
@Test
fun testCommunityClick() {
testThatNavigationDrawerOpens()
rule.screenShot("open_drawer")
intending(hasAction(ACTION_VIEW)).respondWith(ActivityResult(RESULT_CANCELED, null))
onView(withText(nav_community_on_google)).perform(click())
intended(allOf(hasAction(ACTION_VIEW), hasData("https://plus.google.com/communities/116353894782342292067")))
}
@Test
fun testGitHubClick() {
testThatNavigationDrawerOpens()

View file

@ -4,18 +4,16 @@ import android.annotation.TargetApi
import android.app.Activity
import android.app.Instrumentation
import android.content.Intent
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.*
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.intent.Intents.intended
import android.support.test.espresso.intent.Intents.intending
import android.support.test.espresso.intent.matcher.IntentMatchers.hasAction
import android.support.test.espresso.matcher.ViewMatchers.*
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.*
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.Intents.intending
import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
import androidx.test.espresso.matcher.ViewMatchers.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import org.junit.Test
import org.ligi.passandroid.R.id.*
import org.ligi.passandroid.R.string.*
import org.ligi.passandroid.model.pass.PassType.COUPON
import org.ligi.passandroid.model.pass.PassType.EVENT
import org.ligi.passandroid.ui.PassEditActivity
@ -27,15 +25,16 @@ class ThePassEditActivity {
val passStore = TestApp.passStore()
@get:Rule
var rule = TruleskIntentRule(PassEditActivity::class.java)
var rule = TruleskIntentRule(PassEditActivity::class.java) {
TestApp.populatePassStoreWithSinglePass()
}
@Test
fun testSetToEventWorks() {
onView(withId(R.id.categoryView)).perform(click())
onView(withId(categoryView)).perform(click())
onView(withText(select_category_dialog_title)).perform(click())
onView(withText(category_event)).perform(click())
onView(withText(R.string.select_category_dialog_title)).perform(click())
onView(withText(R.string.category_event)).perform(click())
assertThat(passStore.currentPass!!.type).isEqualTo(EVENT)
rule.screenShot("edit_set_event")
@ -43,10 +42,10 @@ class ThePassEditActivity {
@Test
fun testSetToCouponWorks() {
onView(withId(categoryView)).perform(click())
onView(withId(R.id.categoryView)).perform(click())
onView(withText(select_category_dialog_title)).perform(click())
onView(withText(category_coupon)).perform(click())
onView(withText(R.string.select_category_dialog_title)).perform(click())
onView(withText(R.string.category_coupon)).perform(click())
assertThat(passStore.currentPass!!.type).isEqualTo(COUPON)
rule.screenShot("edit_set_coupon")
@ -55,7 +54,7 @@ class ThePassEditActivity {
@Test
fun testSetDescriptionWorks() {
onView(withId(passTitle)).perform(clearText(), typeText("test description"))
onView(withId(R.id.passTitle)).perform(clearText(), typeText("test description"))
assertThat(passStore.currentPass!!.description).isEqualTo("test description")
rule.screenShot("edit_set_description")
@ -65,10 +64,10 @@ class ThePassEditActivity {
@Test
fun testColorWheelIsThere() {
onView(withId(categoryView)).perform(click())
onView(withText(change_color_dialog_title)).perform(click())
onView(withId(R.id.categoryView)).perform(click())
onView(withText(R.string.change_color_dialog_title)).perform(click())
onView(withId(colorPicker)).check(matches(isDisplayed()))
onView(withId(R.id.colorPicker)).check(matches(isDisplayed()))
rule.screenShot("edit_set_color")
}

View file

@ -2,11 +2,11 @@ package org.ligi.passandroid
import android.annotation.TargetApi
import android.os.Build
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.Espresso.pressBack
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.*
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.Espresso.pressBack
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import org.junit.Rule
import org.junit.Test
import org.ligi.passandroid.R.id.pass_recyclerview

View file

@ -1,11 +1,11 @@
package org.ligi.passandroid
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.action.ViewActions.typeText
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.*
import android.support.v7.widget.helper.ItemTouchHelper
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.recyclerview.widget.ItemTouchHelper
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import org.junit.Test
@ -14,6 +14,8 @@ import org.ligi.passandroid.ui.PassListActivity
import org.ligi.passandroid.ui.PassListFragment
import org.ligi.trulesk.TruleskIntentRule
const val CUSTOM_PROBE = "FOO_PROBE"
class ThePassListSwiping {
@get:Rule
@ -42,7 +44,6 @@ class ThePassListSwiping {
@Test
fun testWeCanMoveToCustom() {
val CUSTOM_PROBE = "FOO_PROBE"
fakeSwipeLeft()

View file

@ -1,12 +1,13 @@
package org.ligi.passandroid
import android.annotation.TargetApi
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.assertion.ViewAssertions.doesNotExist
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.*
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import org.hamcrest.core.IsNot.not
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.ligi.passandroid.model.pass.BarCode
@ -21,11 +22,16 @@ import java.util.*
@TargetApi(14)
class ThePassViewActivity {
internal fun getActPass() = TestApp.passStore().currentPass as PassImpl
private fun getActPass() = TestApp.passStore().currentPass as PassImpl
@get:Rule
var rule = TruleskActivityRule(PassViewActivity::class.java, false)
@Before
fun before() {
TestApp.populatePassStoreWithSinglePass()
}
@Test
fun testThatDescriptionIsThere() {
rule.launchActivity(null)
@ -35,7 +41,7 @@ class ThePassViewActivity {
@Test
fun testDateIsGoneWhenPassbookHasNoDate() {
getActPass().validTimespans = ArrayList<PassImpl.TimeSpan>()
getActPass().validTimespans = ArrayList()
rule.launchActivity(null)
onView(withId(R.id.date)).check(matches(not(isDisplayed())))
@ -92,7 +98,7 @@ class ThePassViewActivity {
@Test
fun testLinkToCalendarIsNotThereWhenPassbookHasNoDate() {
getActPass().validTimespans = ArrayList<PassImpl.TimeSpan>()
getActPass().validTimespans = ArrayList()
rule.launchActivity(null)
onView(withText(R.string.pass_to_calendar)).check(matches(not(isDisplayed())))

View file

@ -1,9 +1,9 @@
package org.ligi.passandroid
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.assertion.ViewAssertions
import android.support.test.espresso.matcher.ViewMatchers.isDisplayed
import android.support.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import org.hamcrest.CoreMatchers.not
import org.junit.Rule
import org.junit.Test
@ -16,7 +16,10 @@ import org.threeten.bp.ZonedDateTime
class ThePassViewHolder {
val currentPass by lazy { App.passStore.currentPass as PassImpl }
private val currentPass by lazy {
TestApp.populatePassStoreWithSinglePass()
App.passStore.currentPass as PassImpl
}
@get:Rule
var rule = TruleskActivityRule(PassListActivity::class.java, false)

View file

@ -2,7 +2,7 @@ package org.ligi.passandroid
import android.content.Context
import android.content.SharedPreferences
import android.support.test.InstrumentationRegistry.getInstrumentation
import androidx.test.platform.app.InstrumentationRegistry
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Rule
@ -17,13 +17,14 @@ class ThePastLocationsStore {
@get:Rule
var rule = TruleskActivityRule(PassViewActivity::class.java) {
TestApp.populatePassStoreWithSinglePass()
MockitoAnnotations.initMocks(this)
}
@Mock
lateinit var tracker: Tracker
val prefs: SharedPreferences by lazy { getInstrumentation().context.getSharedPreferences("" + System.currentTimeMillis() / 100000, Context.MODE_PRIVATE) }
private val prefs: SharedPreferences by lazy { InstrumentationRegistry.getInstrumentation().context.getSharedPreferences("" + System.currentTimeMillis() / 100000, Context.MODE_PRIVATE) }
@After
fun tearDown() {
@ -34,7 +35,7 @@ class ThePastLocationsStore {
fun testPastLocationsStoreShouldNeverContainMoreThanMaxElements() {
val tested = PastLocationsStore(prefs, tracker)
for (i in 0..PastLocationsStore.MAX_ELEMENTS * 2 - 1) {
for (i in 0 until PastLocationsStore.MAX_ELEMENTS * 2) {
tested.putLocation("" + i)
}
@ -44,7 +45,7 @@ class ThePastLocationsStore {
@Test
fun testPastLocationsStoreShouldStoreOnlyOneOfAKind() {
val tested = PastLocationsStore(prefs, tracker!!)
val tested = PastLocationsStore(prefs, tracker)
for (i in 0..2) {
tested.putLocation("foo")

View file

@ -1,10 +1,10 @@
package org.ligi.passandroid
import android.os.Build
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.matcher.ViewMatchers.withText
import android.support.v7.app.AppCompatDelegate
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.appcompat.app.AppCompatDelegate
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import org.junit.Test
@ -20,7 +20,7 @@ class ThePreferenceActivity {
@get:Rule
val rule = TruleskActivityRule(PreferenceActivity::class.java)
val androidSettings by lazy { AndroidSettings(rule.activity) }
private val androidSettings by lazy { AndroidSettings(rule.activity) }
@Test
fun autoLightToggles() {

View file

@ -1,6 +1,6 @@
package org.ligi.passandroid;
import android.support.test.InstrumentationRegistry;
import androidx.test.platform.app.InstrumentationRegistry;
import java.io.InputStream;
import org.junit.Before;
import org.junit.Test;
@ -27,7 +27,7 @@ public class TheUnzipPassController {
PassStore passStore;
@Before
public void setUp() throws Exception {
public void setUp() {
MockitoAnnotations.initMocks(this);
}

View file

@ -1,8 +1,8 @@
package org.ligi.passandroid.functions
import android.support.test.espresso.UiController
import android.support.test.espresso.ViewAction
import android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
import android.view.View
import net.i2p.android.ext.floatingactionbutton.FloatingActionsMenu
import org.hamcrest.Description

View file

@ -1,12 +1,11 @@
package org.ligi.passandroid.functions
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.isDisplayed
import android.support.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import org.ligi.passandroid.R
fun checkThatHelpIsThere() {
onView(withId(R.id.help_text)).check(matches(isDisplayed()))
}

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.functions
import android.content.Context
import android.support.test.InstrumentationRegistry
import androidx.test.platform.app.InstrumentationRegistry
import org.assertj.core.api.Fail.fail
import org.ligi.passandroid.model.InputStreamWithSource
import org.ligi.passandroid.model.PassStore

View file

@ -10,7 +10,7 @@ class FixedPassListPassStore(private var passes: List<Pass>) : PassStore {
override lateinit var classifier: PassClassifier
init {
classifier = PassClassifier(HashMap<String, String>(), this)
classifier = PassClassifier(HashMap(), this)
}
fun setList(newPasses: List<Pass>, newCurrentPass: Pass? = newPasses.firstOrNull()) {
@ -19,7 +19,7 @@ class FixedPassListPassStore(private var passes: List<Pass>) : PassStore {
passMap.clear()
passMap.putAll(createHashMap())
classifier = PassClassifier(HashMap<String, String>(), this)
classifier = PassClassifier(HashMap(), this)
}
override var currentPass: Pass? = null
@ -31,7 +31,7 @@ class FixedPassListPassStore(private var passes: List<Pass>) : PassStore {
private fun createHashMap(): HashMap<String, Pass> {
val hashMap = HashMap<String, Pass>()
passes.forEach { hashMap.put(it.id, it) }
passes.forEach { hashMap[it.id] = it }
return hashMap
}

View file

@ -29,6 +29,7 @@
<receiver
android:name=".InstallListener"
android:permission="android.permission.INSTALL_PACKAGES"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER"/>
@ -36,7 +37,7 @@
</receiver>
<provider
android:name="android.support.v4.content.FileProvider"
android:name="androidx.core.content.FileProvider"
android:authorities="@string/authority_fileprovider"
android:grantUriPermissions="true"
android:exported="false">
@ -122,47 +123,35 @@
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:mimeType="application/vnd.espass-espass"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="http" android:mimeType="application/vnd.espass-espass"/>
<data android:scheme="https" android:mimeType="application/vnd.espass-espass"/>
<data android:scheme="content" android:mimeType="application/vnd.espass-espass"/>
<data android:scheme="file" android:mimeType="application/vnd.espass-espass"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http" android:mimeType="application/vnd.espass-espass+zip"/>
<data android:scheme="https" android:mimeType="application/vnd.espass-espass+zip"/>
<data android:scheme="content" android:mimeType="application/vnd.espass-espass+zip"/>
<data android:scheme="file" android:mimeType="application/vnd.espass-espass+zip"/>
<data android:mimeType="application/vnd.espass-espass+zip"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="http" android:mimeType="application/vnd.apple.pkpass"/>
<data android:scheme="https" android:mimeType="application/vnd.apple.pkpass"/>
<data android:scheme="content" android:mimeType="application/vnd.apple.pkpass"/>
<data android:scheme="file" android:mimeType="application/vnd.apple.pkpass"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http" android:mimeType="application/pkpass"/>
<data android:scheme="https" android:mimeType="application/pkpass"/>
<data android:scheme="content" android:mimeType="application/pkpass"/>
<data android:scheme="file" android:mimeType="application/pkpass"/>
<data android:mimeType="application/vnd.apple.pkpass"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="http" android:mimeType="application/vndapplepkpass"/>
<data android:scheme="https" android:mimeType="application/vndapplepkpass"/>
<data android:scheme="content" android:mimeType="application/vndapplepkpass"/>
<data android:scheme="file" android:mimeType="application/vndapplepkpass"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:mimeType="application/pkpass"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:mimeType="application/vndapplepkpass"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:mimeType="application/vnd-com.apple.pkpass"/>
<data android:scheme="http" android:mimeType="application/vnd-com.apple.pkpass"/>
<data android:scheme="https" android:mimeType="application/vnd-com.apple.pkpass"/>
<data android:scheme="content" android:mimeType="application/vnd-com.apple.pkpass"/>
<data android:scheme="file" android:mimeType="application/vnd-com.apple.pkpass"/>
</intent-filter>
<intent-filter>
@ -616,17 +605,9 @@
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:mimeType="application/x-pdf"/>
<data android:scheme="content" android:mimeType="application/x-pdf"/>
<data android:scheme="content" android:mimeType="application/pdf"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:mimeType="application/pdf"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
@ -1071,22 +1052,6 @@
android:pathPattern="/.*\\.pkpass"
android:scheme="content"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:mimeType="application/vnd.apple.pkpass"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:mimeType="application/vnd-com.apple.pkpass"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>

View file

@ -1,9 +1,9 @@
/**
*******************************************************************************
* Copyright (C) 2005-2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
/*
*******************************************************************************
* Copyright (C) 2005 - 2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.text;
import java.io.IOException;
@ -35,6 +35,7 @@ import java.util.List;
* <p/>
* @stable ICU 3.4
*/
@SuppressWarnings("ALL")
public class CharsetDetector {
// Question: Should we have getters corresponding to the setters for input text
@ -182,7 +183,7 @@ public class CharsetDetector {
* @stable ICU 3.4
*/
public CharsetMatch[] detectAll() {
ArrayList<CharsetMatch> matches = new ArrayList<CharsetMatch>();
ArrayList<CharsetMatch> matches = new ArrayList<>();
MungeInput(); // Strip html markup, collect byte stats.
@ -344,7 +345,7 @@ public class CharsetDetector {
* it by removing what appears to be html markup.
*/
private void MungeInput() {
int srci = 0;
int srci;
int dsti = 0;
byte b;
boolean inMarkup = false;
@ -473,7 +474,7 @@ public class CharsetDetector {
private static final List<CSRecognizerInfo> ALL_CS_RECOGNIZERS;
static {
List<CSRecognizerInfo> list = new ArrayList<CSRecognizerInfo>();
List<CSRecognizerInfo> list = new ArrayList<>();
list.add(new CSRecognizerInfo(new CharsetRecog_UTF8(), true));
list.add(new CSRecognizerInfo(new CharsetRecog_Unicode.CharsetRecog_UTF_16_BE(), true));
@ -522,7 +523,7 @@ public class CharsetDetector {
*/
@Deprecated
public String[] getDetectableCharsets() {
List<String> csnames = new ArrayList<String>(ALL_CS_RECOGNIZERS.size());
List<String> csnames = new ArrayList<>(ALL_CS_RECOGNIZERS.size());
for (int i = 0; i < ALL_CS_RECOGNIZERS.size(); i++) {
CSRecognizerInfo rcinfo = ALL_CS_RECOGNIZERS.get(i);
boolean active = (fEnabledRecognizers == null) ? rcinfo.isDefaultEnabled : fEnabledRecognizers[i];
@ -530,7 +531,7 @@ public class CharsetDetector {
csnames.add(rcinfo.recognizer.getName());
}
}
return csnames.toArray(new String[csnames.size()]);
return csnames.toArray(new String[0]);
}
/**

View file

@ -1,9 +1,9 @@
/**
*******************************************************************************
* Copyright (C) 2005-2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
/*
*******************************************************************************
* Copyright (C) 2005 - 2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.text;
import java.io.ByteArrayInputStream;
@ -26,6 +26,7 @@ import java.io.Reader;
*
* @stable ICU 3.4
*/
@SuppressWarnings("ALL")
public class CharsetMatch implements Comparable<CharsetMatch> {
@ -85,13 +86,13 @@ public class CharsetMatch implements Comparable<CharsetMatch> {
* @stable ICU 3.4
*/
public String getString(int maxLength) throws java.io.IOException {
String result = null;
String result;
if (fInputStream != null) {
StringBuilder sb = new StringBuilder();
char[] buffer = new char[1024];
Reader reader = getReader();
int max = maxLength < 0? Integer.MAX_VALUE : maxLength;
int bytesRead = 0;
int bytesRead;
while ((bytesRead = reader.read(buffer, 0, Math.min(max, 1024))) >= 0) {
sb.append(buffer, 0, bytesRead);
@ -108,6 +109,7 @@ public class CharsetMatch implements Comparable<CharsetMatch> {
* be used to open a charset (e.g. IBM424_rtl). The ending '_rtl' or 'ltr'
* should be stripped off before creating the string.
*/
//noinspection IndexOfReplaceableByContains
int startSuffix = name.indexOf("_rtl") < 0 ? name.indexOf("_ltr") : name.indexOf("_rtl");
if (startSuffix > 0) {
name = name.substring(0, startSuffix);
@ -234,7 +236,7 @@ public class CharsetMatch implements Comparable<CharsetMatch> {
// If user gave us a byte array, this is it.
private int fRawLength; // Length of data in fRawInput array.
private InputStream fInputStream = null; // User's input stream, or null if the user
private InputStream fInputStream; // User's input stream, or null if the user
// gave us a byte array.
private String fCharsetName; // The name of the charset this CharsetMatch

View file

@ -1,9 +1,9 @@
/*
*******************************************************************************
* Copyright (C) 2005 - 2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
*******************************************************************************
* Copyright (C) 2005 - 2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.text;
/**
@ -14,6 +14,7 @@ package com.ibm.icu.text;
*
* The separate classes are nested within this class.
*/
@SuppressWarnings("ALL")
abstract class CharsetRecog_2022 extends CharsetRecognizer {
@ -44,7 +45,7 @@ abstract class CharsetRecog_2022 extends CharsetRecognizer {
byte [] seq = escapeSequences[escN];
if ((textLen - i) < seq.length) {
continue checkEscapes;
continue;
}
for (j=1; j<seq.length; j++) {
@ -92,9 +93,6 @@ abstract class CharsetRecog_2022 extends CharsetRecognizer {
return quality;
}
static class CharsetRecog_2022JP extends CharsetRecog_2022 {
private byte [] [] escapeSequences = {
{0x1b, 0x24, 0x28, 0x43}, // KS X 1001:1992

View file

@ -1,14 +1,15 @@
/**
*******************************************************************************
* Copyright (C) 2005 - 2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
/*
*******************************************************************************
* Copyright (C) 2005 - 2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.text;
/**
* Charset recognizer for UTF-8
*/
@SuppressWarnings("ALL")
class CharsetRecog_UTF8 extends CharsetRecognizer {
String getName() {
@ -24,7 +25,7 @@ class CharsetRecog_UTF8 extends CharsetRecognizer {
int numInvalid = 0;
byte input[] = det.fRawInput;
int i;
int trailBytes = 0;
int trailBytes;
int confidence;
if (det.fRawLength >= 3 &&

View file

@ -12,6 +12,7 @@ package com.ibm.icu.text;
* This class matches UTF-16 and UTF-32, both big- and little-endian. The
* BOM will be used if it is present.
*/
@SuppressWarnings("ALL")
abstract class CharsetRecog_Unicode extends CharsetRecognizer {
/* (non-Javadoc)
@ -171,7 +172,7 @@ abstract class CharsetRecog_Unicode extends CharsetRecognizer {
{
int getChar(byte[] input, int index)
{
return (input[index + 0] & 0xFF) << 24 | (input[index + 1] & 0xFF) << 16 |
return (input[index] & 0xFF) << 24 | (input[index + 1] & 0xFF) << 16 |
(input[index + 2] & 0xFF) << 8 | (input[index + 3] & 0xFF);
}
@ -187,7 +188,7 @@ abstract class CharsetRecog_Unicode extends CharsetRecognizer {
int getChar(byte[] input, int index)
{
return (input[index + 3] & 0xFF) << 24 | (input[index + 2] & 0xFF) << 16 |
(input[index + 1] & 0xFF) << 8 | (input[index + 0] & 0xFF);
(input[index + 1] & 0xFF) << 8 | (input[index] & 0xFF);
}
String getName()

View file

@ -1,9 +1,8 @@
/*
****************************************************************************
* Copyright (C) 2005-2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
****************************************************************************
*
*******************************************************************************
* Copyright (C) 2005 - 2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.text;
@ -21,6 +20,7 @@ import java.util.Arrays;
* encodings to be checked. The specific encoding being recognized
* is determined by subclass.
*/
@SuppressWarnings("ALL")
abstract class CharsetRecog_mbcs extends CharsetRecognizer {
/**
@ -157,8 +157,7 @@ abstract class CharsetRecog_mbcs extends CharsetRecognizer {
done = true;
return -1;
}
int byteValue = (int)det.fRawInput[nextIndex++] & 0x00ff;
return byteValue;
return (int)det.fRawInput[nextIndex++] & 0x00ff;
}
}
@ -321,9 +320,9 @@ abstract class CharsetRecog_mbcs extends CharsetRecognizer {
boolean nextChar(iteratedChar it, CharsetDetector det) {
it.index = it.nextIndex;
it.error = false;
int firstByte = 0;
int secondByte = 0;
int thirdByte = 0;
int firstByte;
int secondByte;
int thirdByte;
//int fourthByte = 0;
buildChar: {
@ -372,7 +371,7 @@ abstract class CharsetRecog_mbcs extends CharsetRecognizer {
}
}
return (it.done == false);
return (!it.done);
}
/**
@ -461,10 +460,10 @@ abstract class CharsetRecog_mbcs extends CharsetRecognizer {
boolean nextChar(iteratedChar it, CharsetDetector det) {
it.index = it.nextIndex;
it.error = false;
int firstByte = 0;
int secondByte = 0;
int thirdByte = 0;
int fourthByte = 0;
int firstByte;
int secondByte;
int thirdByte;
int fourthByte;
buildChar: {
firstByte = it.charValue = it.nextByte(det);
@ -483,7 +482,7 @@ abstract class CharsetRecog_mbcs extends CharsetRecognizer {
secondByte = it.nextByte(det);
it.charValue = (it.charValue << 8) | secondByte;
if (firstByte >= 0x81 && firstByte <= 0xFE) {
if (firstByte <= 0xFE) {
// Two byte Char
if ((secondByte >= 0x40 && secondByte <= 0x7E) || (secondByte >=80 && secondByte <=0xFE)) {
break buildChar;
@ -504,11 +503,10 @@ abstract class CharsetRecog_mbcs extends CharsetRecognizer {
}
it.error = true;
break buildChar;
}
}
return (it.done == false);
return !it.done;
}
static int [] commonChars =

View file

@ -1,17 +1,16 @@
/*
****************************************************************************
* Copyright (C) 2005-2013, International Business Machines Corporation and *
* others. All Rights Reserved. *
************************************************************************** *
*
*******************************************************************************
* Copyright (C) 2005 - 2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.text;
/**
* This class recognizes single-byte encodings. Because the encoding scheme is so
* simple, language statistics are used to do the matching.
*/
@SuppressWarnings("ALL")
abstract class CharsetRecog_sbcs extends CharsetRecognizer {
/* (non-Javadoc)
@ -25,7 +24,7 @@ abstract class CharsetRecog_sbcs extends CharsetRecognizer {
private static final int N_GRAM_MASK = 0xFFFFFF;
protected int byteIndex = 0;
private int ngram = 0;
private int ngram;
private int[] ngramList;
protected byte[] byteMap;
@ -161,7 +160,7 @@ abstract class CharsetRecog_sbcs extends CharsetRecognizer {
return (int) (rawPercent * 300.0);
}
}
static class NGramParser_IBM420 extends NGramParser
{
private byte alef = 0x00;
@ -273,7 +272,7 @@ abstract class CharsetRecog_sbcs extends CharsetRecognizer {
return parser.parse(det, spaceChar);
}
int matchIBM420(CharsetDetector det, int[] ngrams, byte[] byteMap, byte spaceChar){
int matchIBM420(CharsetDetector det, int[] ngrams, byte[] byteMap, @SuppressWarnings("SameParameterValue") byte spaceChar){
NGramParser_IBM420 parser = new NGramParser_IBM420(ngrams, byteMap);
return parser.parse(det, spaceChar);
}

View file

@ -1,9 +1,9 @@
/**
*******************************************************************************
* Copyright (C) 2005-2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
/*
*******************************************************************************
* Copyright (C) 2005 - 2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.text;
/**
@ -20,6 +20,7 @@ package com.ibm.icu.text;
* The WILL be shared by multiple instances of CharsetDetector.
* They encapsulate const charset-specific information.
*/
@SuppressWarnings("ALL")
abstract class CharsetRecognizer {
/**
* Get the IANA name of this charset.

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid
import android.app.Application
import android.support.v7.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate
import com.github.salomonbrys.kodein.*
import com.jakewharton.threetenabp.AndroidThreeTen
import com.squareup.leakcanary.LeakCanary

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid;
import android.support.annotation.Nullable;
import androidx.annotation.Nullable;
public interface Tracker {
void trackException(String s, Throwable e, boolean fatal);

View file

@ -3,15 +3,15 @@ package org.ligi.passandroid.functions
import android.content.ActivityNotFoundException
import android.content.Intent
import android.provider.CalendarContract
import android.support.annotation.VisibleForTesting
import android.support.design.widget.Snackbar
import android.support.v7.app.AlertDialog
import androidx.annotation.VisibleForTesting
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AlertDialog
import android.view.View
import org.ligi.passandroid.R
import org.ligi.passandroid.model.pass.Pass
import org.ligi.passandroid.model.pass.PassImpl
val DEFAULT_EVENT_LENGTH_IN_HOURS = 8L
const val DEFAULT_EVENT_LENGTH_IN_HOURS = 8L
fun tryAddDateToCalendar(pass: Pass, contextView: View, timeSpan: PassImpl.TimeSpan) {
if (pass.calendarTimespan == null) {

View file

@ -33,26 +33,26 @@ fun generateBarCodeBitmap(data: String, type: PassBarCodeFormat): Bitmap? {
// create buffered image to draw to
// NTFS Bitmap.Config.ALPHA_8 sounds like an awesome idea - been there - done that ..
val barcode_image = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565)
val barcodeImage = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565)
// iterate through the matrix and draw the pixels to the image
for (y in 0..height - 1) {
for (x in 0..width - 1) {
barcode_image.setPixel(x, y, if (matrix.get(x, if (is1D) 0 else y)) 0 else 0xFFFFFF)
for (y in 0 until height) {
for (x in 0 until width) {
barcodeImage.setPixel(x, y, if (matrix.get(x, if (is1D) 0 else y)) 0 else 0xFFFFFF)
}
}
return barcode_image
return barcodeImage
} catch (e: com.google.zxing.WriterException) {
Log.w("could not write image " + e)
Log.w("could not write image: $e")
// TODO check if we should better return some rescue Image here
return null
} catch (e: IllegalArgumentException) {
Log.w("could not write image " + e)
Log.w("could not write image: $e")
return null
} catch (e: ArrayIndexOutOfBoundsException) {
// happens for ITF barcode on certain inputs
Log.w("could not write image " + e)
Log.w("could not write image: $e")
return null
}

View file

@ -1,9 +1,9 @@
package org.ligi.passandroid.functions
import android.graphics.Color
import android.support.annotation.ColorInt
import android.support.annotation.DrawableRes
import android.support.annotation.StringRes
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import org.ligi.passandroid.R
import org.ligi.passandroid.model.pass.PassType

View file

@ -9,7 +9,7 @@ import org.ligi.passandroid.model.InputStreamWithSource
import java.io.BufferedInputStream
import java.net.URL
val IPHONE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53"
const val IPHONE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53"
fun fromURI(context: Context, uri: Uri): InputStreamWithSource? {
App.tracker.trackEvent("protocol", "to_inputstream", uri.scheme, null)

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.functions
import android.app.Activity
import android.support.design.widget.Snackbar
import com.google.android.material.snackbar.Snackbar
import org.ligi.passandroid.R
import org.ligi.passandroid.model.PassClassifier
import org.ligi.passandroid.model.pass.Pass
@ -9,7 +9,7 @@ import org.ligi.passandroid.model.pass.Pass
fun moveWithUndoSnackbar(passClassifier: PassClassifier, pass: Pass, topic: String, activity: Activity) {
val oldTopic = passClassifier.getTopic(pass, "")
Snackbar.make(activity.window.decorView.findViewById(R.id.fam), "Pass moved to " + topic, Snackbar.LENGTH_LONG)
Snackbar.make(activity.window.decorView.findViewById(R.id.fam), "Pass moved to $topic", Snackbar.LENGTH_LONG)
.setAction(R.string.undo) { passClassifier.moveToTopic(pass, oldTopic) }
.show()
passClassifier.moveToTopic(pass, topic)

View file

@ -15,7 +15,7 @@ import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.util.*
val APP = "passandroid"
const val APP = "passandroid"
fun createAndAddEmptyPass(passStore: PassStore, resources: Resources): Pass {
val pass = createBasePass()

View file

@ -40,7 +40,7 @@ class AndroidFileSystemPassStore(private val context: Context, settings: Setting
if (BuildConfig.DEBUG) {
val of = com.squareup.moshi.JsonWriter.of(buffer)
of.setIndent(" ")
of.indent = " "
jsonAdapter.toJson(of, pass as PassImpl)
buffer.close()
of.close()
@ -86,7 +86,7 @@ class AndroidFileSystemPassStore(private val context: Context, settings: Setting
if (dirty) {
save(result)
}
passMap.put(id, result)
passMap[id] = result
notifyChange()
}

View file

@ -2,7 +2,7 @@ package org.ligi.passandroid.model
import android.content.Context
import android.preference.PreferenceManager
import android.support.v7.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate
import org.ligi.passandroid.R
import org.ligi.passandroid.R.string.preference_key_autolight
import org.ligi.passandroid.R.string.preference_key_condensed
@ -11,12 +11,12 @@ import java.io.File
class AndroidSettings(val context: Context) : Settings {
internal val sharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(context) }
private val sharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(context) }
override fun getSortOrder(): PassSortOrder {
val key = context.getString(R.string.preference_key_sort)
val stringValue = sharedPreferences.getString(key, "0")
val id = Integer.valueOf(stringValue)!!
val id = Integer.valueOf(stringValue!!)
return PassSortOrder.values().first { it.int == id }
}

View file

@ -24,7 +24,7 @@ class ApplePassbookQuirkCorrector(val tracker: Tracker) {
tryToFindDate(pass)
}
fun tryToFindDate(pass: PassImpl) {
private fun tryToFindDate(pass: PassImpl) {
if (pass.calendarTimespan == null) {
val foundDate = pass.fields.filter { "date" == it.key }.map {
@ -44,11 +44,11 @@ class ApplePassbookQuirkCorrector(val tracker: Tracker) {
}
private fun getPassFieldForKey(pass: PassImpl, key: String): PassField? {
return pass.fields.firstOrNull() { it.key != null && it.key == key }
return pass.fields.firstOrNull { it.key != null && it.key == key }
}
private fun getPassFieldThatMatchesLabel(pass: PassImpl, matcher: String): PassField? {
return pass.fields.firstOrNull() {
return pass.fields.firstOrNull {
val label = it.label
label != null && label.matches(matcher.toRegex())
}

View file

@ -1,8 +1,8 @@
package org.ligi.passandroid.model;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.ibm.icu.text.CharsetDetector;
import com.ibm.icu.text.CharsetMatch;
import java.io.DataInputStream;
@ -12,7 +12,6 @@ import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import org.ligi.passandroid.App;
@VisibleForTesting
public class AppleStylePassTranslation extends HashMap<String, String> {
public String translate(String key) {
@ -63,6 +62,7 @@ public class AppleStylePassTranslation extends HashMap<String, String> {
if (fileData[0] == (byte) 0xEF && fileData[1] == (byte) 0xBB && fileData[2] == (byte) 0xBF) {
final byte[] crop = new byte[fileData.length - 3];
System.arraycopy(fileData, 3, crop, 0, crop.length);
//noinspection CharsetObjectCanBeUsed
return new String(crop, "utf-8");
}

View file

@ -14,7 +14,7 @@ open class PassClassifier(val topicByIdMap: MutableMap<String, String>, private
}
fun moveToTopic(pass: Pass, newTopic: String) {
topicByIdMap.put(pass.id, newTopic)
topicByIdMap[pass.id] = newTopic
processDataChange()
}
@ -24,7 +24,7 @@ open class PassClassifier(val topicByIdMap: MutableMap<String, String>, private
}
fun getPassListByTopic(topic: String): List<Pass> {
return topicByIdMap.filter { it.value.equals(topic) }.map { passStore.getPassbookForId(it.key) }.filterNotNull()
return topicByIdMap.filter { it.value == topic }.map { passStore.getPassbookForId(it.key) }.filterNotNull()
}
fun getTopic(pass: Pass, default: String): String {
@ -38,7 +38,7 @@ open class PassClassifier(val topicByIdMap: MutableMap<String, String>, private
}
if (!default.isEmpty()) {
topicByIdMap.put(id, default)
topicByIdMap[id] = default
processDataChange()
}
return default

View file

@ -4,7 +4,7 @@ import org.ligi.passandroid.model.comparator.PassSortOrder
import org.ligi.passandroid.model.pass.Pass
import java.util.*
class PassStoreProjection(private val passStore: PassStore, val topic: String, private val passSortOrder: PassSortOrder? = null) {
class PassStoreProjection(private val passStore: PassStore, private val topic: String, private val passSortOrder: PassSortOrder? = null) {
var passList: List<Pass> = ArrayList()
private set

View file

@ -1,18 +1,12 @@
package org.ligi.passandroid.model
import android.annotation.TargetApi
import android.content.SharedPreferences
import android.os.Build
import org.ligi.passandroid.Tracker
import java.util.*
class PastLocationsStore constructor(private val sharedPreferences: SharedPreferences, private val tracker: Tracker) {
fun putLocation(path: String) {
if (Build.VERSION.SDK_INT < 11) {
// feature not available for these versions
return
}
val pastLocations = sharedPreferences.getStringSet(KEY_PAST_LOCATIONS, HashSet<String>())
if (pastLocations!!.size >= MAX_ELEMENTS) {
@ -39,17 +33,11 @@ class PastLocationsStore constructor(private val sharedPreferences: SharedPrefer
// feature not available for these versions
val locations: Set<String>
@TargetApi(11)
get() {
if (Build.VERSION.SDK_INT < 11) {
return HashSet()
}
return sharedPreferences.getStringSet(KEY_PAST_LOCATIONS, HashSet<String>())
}
get() = sharedPreferences.getStringSet(KEY_PAST_LOCATIONS, emptySet<String>())
companion object {
val KEY_PAST_LOCATIONS = "past_locations"
val MAX_ELEMENTS = 5
const val KEY_PAST_LOCATIONS = "past_locations"
const val MAX_ELEMENTS = 5
}
}

View file

@ -9,7 +9,7 @@ class DirectionAwarePassByTimeComparator(private val direction: Int) : PassByTim
}
companion object {
val DIRECTION_DESC = -1
val DIRECTION_ASC = 1
const val DIRECTION_DESC = -1
const val DIRECTION_ASC = 1
}
}

View file

@ -7,9 +7,9 @@ import java.util.*
open class PassByTimeComparator : Comparator<Pass> {
override fun compare(lhs: Pass, rhs: Pass): Int {
return calculateCompareForNullValues(lhs, rhs, { leftDate: ZonedDateTime, rightDate: ZonedDateTime ->
return calculateCompareForNullValues(lhs, rhs) { leftDate: ZonedDateTime, rightDate: ZonedDateTime ->
return@calculateCompareForNullValues leftDate.compareTo(rightDate)
})
}
}
protected fun calculateCompareForNullValues(lhs: Pass, rhs: Pass, foo: (leftDate: ZonedDateTime, rightDate: ZonedDateTime) -> Int): Int {

View file

@ -11,10 +11,10 @@ class PassByTypeFirstAndTimeSecondComparator : Comparator<Pass> {
override fun compare(lhs: Pass, rhs: Pass): Int {
val compareResult = lhs.type.compareTo(rhs.type)
if (compareResult != 0) {
return compareResult
return if (compareResult != 0) {
compareResult
} else {
return passByTimeComparator.compare(lhs, rhs)
passByTimeComparator.compare(lhs, rhs)
}
}
}

View file

@ -9,12 +9,10 @@ enum class PassSortOrder constructor(val int: Int) {
TYPE(1),
DATE_DIFF(2);
fun toComparator(): Comparator<Pass> {
when (this) {
TYPE -> return PassByTypeFirstAndTimeSecondComparator()
DATE_DESC -> return DirectionAwarePassByTimeComparator(DirectionAwarePassByTimeComparator.DIRECTION_DESC)
DATE_DIFF -> return PassTemporalDistanceComparator()
DATE_ASC -> return DirectionAwarePassByTimeComparator(DirectionAwarePassByTimeComparator.DIRECTION_ASC)
}
fun toComparator(): Comparator<Pass> = when (this) {
TYPE -> PassByTypeFirstAndTimeSecondComparator()
DATE_DESC -> DirectionAwarePassByTimeComparator(DirectionAwarePassByTimeComparator.DIRECTION_DESC)
DATE_DIFF -> PassTemporalDistanceComparator()
DATE_ASC -> DirectionAwarePassByTimeComparator(DirectionAwarePassByTimeComparator.DIRECTION_ASC)
}
}

View file

@ -8,11 +8,11 @@ import org.threeten.bp.ZonedDateTime
class PassTemporalDistanceComparator : PassByTimeComparator() {
override fun compare(lhs: Pass, rhs: Pass): Int {
return calculateCompareForNullValues(lhs, rhs, { leftDate: ZonedDateTime, rightDate: ZonedDateTime ->
return calculateCompareForNullValues(lhs, rhs) { leftDate: ZonedDateTime, rightDate: ZonedDateTime ->
val durationLeft = Duration.between(LocalDateTime.now(), leftDate).abs()
val durationRight = Duration.between(LocalDateTime.now(), rightDate).abs()
return@calculateCompareForNullValues durationLeft.compareTo(durationRight)
})
}
}
}

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.model.pass
import android.graphics.Bitmap
import android.support.annotation.StringDef
import androidx.annotation.StringDef
import org.ligi.passandroid.model.PassBitmapDefinitions.*
import org.ligi.passandroid.model.PassStore

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.model.pass
import android.content.res.Resources
import android.support.annotation.StringRes
import androidx.annotation.StringRes
class PassField(var key: String?, var label: String?, var value: String?, var hide: Boolean) {

View file

@ -59,13 +59,13 @@ class PassImpl(override val id: String) : Pass {
override var passIdent: String? = null
override fun getBitmap(passStore: PassStore, @Pass.PassBitmap passBitmap: String): Bitmap? {
try {
return try {
val file = File(passStore.getPathForID(id), passBitmap + FILETYPE_IMAGES)
return BitmapFactory.decodeStream(FileInputStream(file))
BitmapFactory.decodeStream(FileInputStream(file))
} catch (expectedInSomeCases_willJustReturnNull: FileNotFoundException) {
return null
null
} catch (e: OutOfMemoryError) {
return null
null
}
}
@ -84,7 +84,7 @@ class PassImpl(override val id: String) : Pass {
}
companion object {
val FILETYPE_IMAGES = ".png"
const val FILETYPE_IMAGES = ".png"
}
}

View file

@ -69,7 +69,7 @@ class PassPrintDocumentAdapter(private val context: Context, private val pass: P
val centerPaint = Paint()
centerPaint.textAlign = Paint.Align.CENTER
canvas.drawText(pass.description, canvas.width / 2f, centerPaint.textSize, centerPaint)
canvas.drawText(pass.description!!, canvas.width / 2f, centerPaint.textSize, centerPaint)
var currentBottom = centerPaint.textSize * 3
val barCode = pass.barCode
@ -83,14 +83,14 @@ class PassPrintDocumentAdapter(private val context: Context, private val pass: P
val destRect = Rect(0, 0, (bitmap.width * ratio).toInt(), (bitmap.height * ratio).toInt())
destRect.offset(((canvas.width - destRect.width()) / 2).toInt(), currentBottom.toInt())
destRect.offset((canvas.width - destRect.width()) / 2, currentBottom.toInt())
currentBottom += destRect.bottom
canvas.drawBitmap(bitmap, srcRect, destRect, centerPaint)
if (barCode.alternativeText != null) {
canvas.drawText(barCode.alternativeText, destRect.centerX().toFloat(), destRect.bottom.toFloat() + 7 + centerPaint.textSize, centerPaint)
canvas.drawText(barCode.alternativeText!!, destRect.centerX().toFloat(), destRect.bottom.toFloat() + 7 + centerPaint.textSize, centerPaint)
currentBottom += 7 + centerPaint.textSize * 2
}
}

View file

@ -32,76 +32,76 @@ object AppleStylePassReader {
val pass = PassImpl(passFile.name)
var pass_json: JSONObject? = null
var passJSON: JSONObject? = null
val localized_path = findLocalizedPath(passFile, language)
val localizedPath = findLocalizedPath(passFile, language)
if (localized_path != null) {
val file = File(localized_path, "pass.strings")
if (localizedPath != null) {
val file = File(localizedPath, "pass.strings")
translation.loadFromFile(file)
}
copyBitmapFile(passFile, localized_path, PassBitmapDefinitions.BITMAP_ICON)
copyBitmapFile(passFile, localized_path, PassBitmapDefinitions.BITMAP_LOGO)
copyBitmapFile(passFile, localized_path, PassBitmapDefinitions.BITMAP_STRIP)
copyBitmapFile(passFile, localized_path, PassBitmapDefinitions.BITMAP_THUMBNAIL)
copyBitmapFile(passFile, localized_path, PassBitmapDefinitions.BITMAP_FOOTER)
copyBitmapFile(passFile, localizedPath, PassBitmapDefinitions.BITMAP_ICON)
copyBitmapFile(passFile, localizedPath, PassBitmapDefinitions.BITMAP_LOGO)
copyBitmapFile(passFile, localizedPath, PassBitmapDefinitions.BITMAP_STRIP)
copyBitmapFile(passFile, localizedPath, PassBitmapDefinitions.BITMAP_THUMBNAIL)
copyBitmapFile(passFile, localizedPath, PassBitmapDefinitions.BITMAP_FOOTER)
val file = File(passFile, "pass.json")
try {
val plainJsonString = AppleStylePassTranslation.readFileAsStringGuessEncoding(file)
pass_json = readJSONSafely(plainJsonString)
passJSON = readJSONSafely(plainJsonString)
} catch (e: Exception) {
Log.i("PassParse Exception " + e)
Log.i("PassParse Exception: $e")
}
if (pass_json == null) {
if (passJSON == null) {
// I had got a strange passbook with UCS-2 which could not be parsed before
// was searching for a auto-detection, but could not find one with support for this encoding
// and the right license
for (charset in Charset.availableCharsets().values) {
try {
val json_str = file.bufferedReader(charset).readText()
pass_json = readJSONSafely(json_str)
val json = file.bufferedReader(charset).readText()
passJSON = readJSONSafely(json)
} catch (ignored: Exception) {
// we try with next charset
}
if (pass_json != null) {
if (passJSON != null) {
break
}
}
}
if (pass_json == null) {
if (passJSON == null) {
Log.w("could not load pass.json from passcode ")
App.tracker.trackEvent("problem_event", "pass", "without_pass_json", null)
return null
}
try {
val barcode_json = pass_json.getBarcodeJson()
if (barcode_json != null) {
val barcodeFormatString = barcode_json.getString("format")
val barcodeJSON = passJSON.getBarcodeJson()
if (barcodeJSON != null) {
val barcodeFormatString = barcodeJSON.getString("format")
App.tracker.trackEvent("measure_event", "barcode_format", barcodeFormatString, 0L)
val barcodeFormat = BarCode.getFormatFromString(barcodeFormatString)
val barCode = BarCode(barcodeFormat, barcode_json.getString("message"))
val barCode = BarCode(barcodeFormat, barcodeJSON.getString("message"))
pass.barCode = barCode
if (barcode_json.has("altText")) {
pass.barCode!!.alternativeText = barcode_json.getString("altText")
if (barcodeJSON.has("altText")) {
pass.barCode!!.alternativeText = barcodeJSON.getString("altText")
}
}
// TODO should check a bit more with barcode here - this can be dangerous
} catch (ignored: Exception) {
}
if (pass_json.has("relevantDate")) {
if (passJSON.has("relevantDate")) {
try {
pass.calendarTimespan = PassImpl.TimeSpan(from = ZonedDateTime.parse(pass_json.getString("relevantDate")))
pass.calendarTimespan = PassImpl.TimeSpan(from = ZonedDateTime.parse(passJSON.getString("relevantDate")))
} catch (e: JSONException) {
// be robust when it comes to bad dates - had a RL crash with "2013-12-25T00:00-57:00" here
// OK then we just have no date here
@ -112,9 +112,9 @@ object AppleStylePassReader {
}
if (pass_json.has("expirationDate")) {
if (passJSON.has("expirationDate")) {
try {
pass.validTimespans = listOf(PassImpl.TimeSpan(to = ZonedDateTime.parse(pass_json.getString("expirationDate"))))
pass.validTimespans = listOf(PassImpl.TimeSpan(to = ZonedDateTime.parse(passJSON.getString("expirationDate"))))
} catch (e: JSONException) {
// be robust when it comes to bad dates - had a RL crash with "2013-12-25T00:00-57:00" here
// OK then we just have no date here
@ -125,17 +125,17 @@ object AppleStylePassReader {
}
pass.serial = readJsonSafeAsOptional(pass_json, "serialNumber")
pass.authToken = readJsonSafeAsOptional(pass_json, "authenticationToken")
pass.webServiceURL = readJsonSafeAsOptional(pass_json, "webServiceURL")
pass.passIdent = readJsonSafeAsOptional(pass_json, "passTypeIdentifier")
pass.serial = readJsonSafeAsOptional(passJSON, "serialNumber")
pass.authToken = readJsonSafeAsOptional(passJSON, "authenticationToken")
pass.webServiceURL = readJsonSafeAsOptional(passJSON, "webServiceURL")
pass.passIdent = readJsonSafeAsOptional(passJSON, "passTypeIdentifier")
val locations = ArrayList<PassLocation>()
try {
val locations_json = pass_json.getJSONArray("locations")
for (i in 0..locations_json.length() - 1) {
val obj = locations_json.getJSONObject(i)
val locationsJSON = passJSON.getJSONArray("locations")
for (i in 0 until locationsJSON.length()) {
val obj = locationsJSON.getJSONObject(i)
val location = PassLocation()
location.lat = obj.getDouble("latitude")
@ -153,13 +153,13 @@ object AppleStylePassReader {
pass.locations = locations
readJsonSafe(pass_json, "backgroundColor", object : JsonStringReadCallback {
readJsonSafe(passJSON, "backgroundColor", object : JsonStringReadCallback {
override fun onString(string: String) {
pass.accentColor = string.parseColor(Color.BLACK)
}
})
readJsonSafe(pass_json, "description", object : JsonStringReadCallback {
readJsonSafe(passJSON, "description", object : JsonStringReadCallback {
override fun onString(string: String) {
pass.description = translation.translate(string)
}
@ -169,22 +169,22 @@ object AppleStylePassReader {
// try to find in a predefined set of tickets
PassDefinitions.TYPE_TO_NAME.forEach {
if (pass_json!!.has(it.value)) {
if (passJSON.has(it.value)) {
pass.type = it.key
}
}
try {
val type = PassDefinitions.TYPE_TO_NAME[pass.type]
val type_json = pass_json.getJSONObject(type)
if (type_json != null) {
val typeJSON = passJSON.getJSONObject(type)
if (typeJSON != null) {
val fieldList: ArrayList<PassField> = ArrayList()
addFields(fieldList, type_json, "primaryFields", translation)
addFields(fieldList, type_json, "headerFields", translation)
addFields(fieldList, type_json, "secondaryFields", translation)
addFields(fieldList, type_json, "auxiliaryFields", translation)
addFields(fieldList, type_json, "backFields", translation, hide = true)
addFields(fieldList, typeJSON, "primaryFields", translation)
addFields(fieldList, typeJSON, "headerFields", translation)
addFields(fieldList, typeJSON, "secondaryFields", translation)
addFields(fieldList, typeJSON, "auxiliaryFields", translation)
addFields(fieldList, typeJSON, "backFields", translation, hide = true)
fieldList.add(PassField("", context.getString(R.string.type), context.getString(getHumanCategoryString(pass.type)), false))
pass.fields = fieldList
@ -195,7 +195,7 @@ object AppleStylePassReader {
try {
pass.creator = pass_json.getString("organizationName")
pass.creator = passJSON.getString("organizationName")
App.tracker.trackEvent("measure_event", "organisation_parse", pass.creator, 1L)
} catch (ignored: JSONException) {
// ok - we have no organisation - big deal ..-)
@ -220,7 +220,7 @@ object AppleStylePassReader {
private fun addFields(list: ArrayList<PassField>, type_json: JSONObject, fieldsName: String, translation: AppleStylePassTranslation, hide: Boolean = false) {
try {
val jsonArray = type_json.getJSONArray(fieldsName)
for (i in 0..jsonArray.length() - 1) {
for (i in 0 until jsonArray.length()) {
try {
val jsonObject = jsonArray.getJSONObject(i)
val field = PassField(key = getField(jsonObject, "key", translation),
@ -230,19 +230,18 @@ object AppleStylePassReader {
list.add(field)
} catch (e: JSONException) {
Log.w("could not process PassField from JSON for $fieldsName cause:$e")
Log.w("could not process PassField from JSON for $fieldsName cause: $e")
}
}
} catch (e: JSONException) {
Log.w("could not process PassFields $fieldsName from JSON$e")
Log.w("could not process PassFields $fieldsName from JSON: $e")
}
}
private fun findLocalizedPath(path: File, language: String): String? {
val localized = File(path, language + ".lproj")
val localized = File(path, "$language.lproj")
if (localized.exists() && localized.isDirectory) {
App.tracker.trackEvent("measure_event", "pass", language + "_native_lproj", null)
@ -282,7 +281,6 @@ object AppleStylePassReader {
} catch (e: JSONException) {
// some passes just do not have the field
}
}
}
@ -294,7 +292,6 @@ object AppleStylePassReader {
} catch (e: Exception) {
e.printStackTrace()
}
}
}
@ -329,6 +326,4 @@ object AppleStylePassReader {
}
return null
}
}

View file

@ -21,47 +21,47 @@ object PassReader {
try {
val plainJsonString = file.bufferedReader().readText()
val pass_json = readJSONSafely(plainJsonString)!!
val passJSON = readJSONSafely(plainJsonString)!!
if (pass_json.has("what")) {
val what_json = pass_json.getJSONObject("what")
pass.description = what_json.getString("description")
if (passJSON.has("what")) {
val whatJSON = passJSON.getJSONObject("what")
pass.description = whatJSON.getString("description")
}
if (pass_json.has("meta")) {
val meta_json = pass_json.getJSONObject("meta")
pass.type = PassDefinitions.NAME_TO_TYPE[meta_json.getString("type")] ?: PassType.GENERIC
pass.creator = meta_json.getString("organisation")
pass.app = meta_json.getString("app")
if (passJSON.has("meta")) {
val metaJSON = passJSON.getJSONObject("meta")
pass.type = PassDefinitions.NAME_TO_TYPE[metaJSON.getString("type")] ?: PassType.GENERIC
pass.creator = metaJSON.getString("organisation")
pass.app = metaJSON.getString("app")
}
if (pass_json.has("ui")) {
val ui_json = pass_json.getJSONObject("ui")
pass.accentColor = Color.parseColor(ui_json.getString("bgColor"))
if (passJSON.has("ui")) {
val uiJSON = passJSON.getJSONObject("ui")
pass.accentColor = Color.parseColor(uiJSON.getString("bgColor"))
}
if (pass_json.has("barcode")) {
val barcode_json = pass_json.getJSONObject("barcode")
val barcodeFormatString = barcode_json.getString("type")
if (passJSON.has("barcode")) {
val barcodeJSON = passJSON.getJSONObject("barcode")
val barcodeFormatString = barcodeJSON.getString("type")
val barcodeFormat = BarCode.getFormatFromString(barcodeFormatString)
val barCode = BarCode(barcodeFormat, barcode_json.getString("message"))
val barCode = BarCode(barcodeFormat, barcodeJSON.getString("message"))
pass.barCode = barCode
if (barcode_json.has("altText")) {
barCode.alternativeText = barcode_json.getString("altText")
if (barcodeJSON.has("altText")) {
barCode.alternativeText = barcodeJSON.getString("altText")
}
}
if (pass_json.has("when")) {
val dateTime = pass_json.getJSONObject("when").getString("dateTime")
if (passJSON.has("when")) {
val dateTime = passJSON.getJSONObject("when").getString("dateTime")
pass.calendarTimespan = PassImpl.TimeSpan()
pass.calendarTimespan = PassImpl.TimeSpan(from = ZonedDateTime.parse(dateTime))
}
} catch (e: Exception) {
Log.i("PassParse Exception " + e)
Log.i("PassParse Exception: $e")
}
return pass

View file

@ -4,14 +4,15 @@ import android.app.Activity
import android.view.View
import android.view.View.*
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.barcode.view.*
import org.ligi.kaxt.getSmallestSide
import org.ligi.passandroid.model.pass.BarCode
internal class BarcodeUIController(val rootView: View, private val barCode: BarCode?, activity: Activity, private val passViewHelper: PassViewHelper) {
internal class BarcodeUIController(private val rootView: View, private val barCode: BarCode?, activity: Activity, private val passViewHelper: PassViewHelper) {
fun getBarcodeView() = rootView.barcode_img
fun getBarcodeView(): ImageView = rootView.barcode_img
private var currentBarcodeWidth: Int = 0

View file

@ -22,10 +22,12 @@ class ExtractURLAsIphoneActivity : PassAndroidActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
progressDialog.show()
tracker.trackEvent("quirk_fix", "unpack_attempt", intent.data.host, null)
if (intent?.data != null) {
progressDialog.show()
tracker.trackEvent("quirk_fix", "unpack_attempt", intent?.data?.host, null)
DownloadExtractAndStartImportTask().execute()
DownloadExtractAndStartImportTask().execute()
}
}
private inner class DownloadExtractAndStartImportTask : AsyncTask<Void, Void, String>() {
@ -34,7 +36,7 @@ class ExtractURLAsIphoneActivity : PassAndroidActivity() {
val client = OkHttpClient()
try {
val requestBuilder = Request.Builder().url(URI(intent.data.toString()).toURL())
val requestBuilder = Request.Builder().url(URI(intent?.data.toString()).toURL())
requestBuilder.header("User-Agent", IPHONE_USER_AGENT)
val body = client.newCall(requestBuilder.build()).execute().body()
@ -46,7 +48,7 @@ class ExtractURLAsIphoneActivity : PassAndroidActivity() {
val url = extractURL(bodyString) ?: return null
if (!url.startsWith("http")) {
return intent.data.scheme + "://" + intent.data.host + "/" + url
return intent?.data?.scheme + "://" + intent?.data?.host + "/" + url
}
return url
@ -79,7 +81,7 @@ class ExtractURLAsIphoneActivity : PassAndroidActivity() {
return
}
tracker.trackEvent("quirk_fix", "unpack_success", intent.data.host, null)
tracker.trackEvent("quirk_fix", "unpack_success", intent?.data?.host, null)
val intent = Intent(this@ExtractURLAsIphoneActivity, PassImportActivity::class.java)
intent.data = Uri.parse(s)

View file

@ -2,6 +2,7 @@ package org.ligi.passandroid.ui
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.WindowManager
@ -15,12 +16,19 @@ class FullscreenBarcodeActivity : PassViewActivityBase() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fullscreen_image)
if (Build.VERSION.SDK_INT >= 27) {
setShowWhenLocked(true)
setTurnScreenOn(true)
} else {
this.window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
}
}
override fun onResume() {
super.onResume()
if (currentPass == null || currentPass.barCode == null) {
if (currentPass.barCode == null) {
Log.w("FullscreenBarcodeActivity in bad state")
finish() // this should never happen, but better safe than sorry
return
@ -47,7 +55,6 @@ class FullscreenBarcodeActivity : PassViewActivityBase() {
* ( reverse orientation / sensor is the problem here ..)
*/
private fun setBestFittingOrientationForBarCode() {
if (currentPass.barCode!!.format!!.isQuadratic()) {
when (requestedOrientation) {
@ -72,9 +79,4 @@ class FullscreenBarcodeActivity : PassViewActivityBase() {
}
}
override fun onAttachedToWindow() {
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
}
}

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.ui
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import android.text.Editable
import android.text.Html
import android.text.method.LinkMovementMethod

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.ui
import android.app.Activity
import android.support.v7.app.AlertDialog
import androidx.appcompat.app.AlertDialog
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
@ -26,16 +26,18 @@ internal class MoveToNewTopicUI(private val context: Activity, private val passS
dialog.dismiss()
}
val newTopicEditText = dialog.findViewById(R.id.new_topic_edit) as EditText
val suggestionButtonContainer= dialog.findViewById(R.id.topic_suggestions_button_container) as ViewGroup
val newTopicEditText = dialog.findViewById<EditText>(R.id.new_topic_edit)
val suggestionButtonContainer = dialog.findViewById<ViewGroup>(R.id.topic_suggestions_button_container)
// we need to do this here so the dialog does not get dismissed
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
if (newTopicEditText.text.toString().isEmpty()) {
newTopicEditText.error = context.getString(R.string.cannot_be_empty)
newTopicEditText.requestFocus()
} else {
move(newTopicEditText.text.toString())
if (newTopicEditText != null) {
// we need to do this here so the dialog does not get dismissed
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
if (newTopicEditText.text.toString().isEmpty()) {
newTopicEditText.error = context.getString(R.string.cannot_be_empty)
newTopicEditText.requestFocus()
} else {
move(newTopicEditText.text.toString())
}
}
}
@ -43,12 +45,12 @@ internal class MoveToNewTopicUI(private val context: Activity, private val passS
val suggestionTopicStringIds = intArrayOf(R.string.topic_trash, R.string.topic_archive, R.string.topic_new)
suggestionTopicStringIds.map { context.getString(it) }.forEach {
if (it != oldTopic) {
suggestionTopicStringIds.map { context.getString(it) }.forEach { topic ->
if (topic != oldTopic) {
val button = Button(context)
button.text = it
suggestionButtonContainer.addView(button)
button.setOnClickListener { _ -> move(it) }
button.text = topic
suggestionButtonContainer?.addView(button)
button.setOnClickListener { move(topic) }
}
}
}

View file

@ -2,32 +2,36 @@ package org.ligi.passandroid.ui;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.view.ViewCompat;
import com.google.android.material.appbar.AppBarLayout;
import androidx.annotation.NonNull;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.material.snackbar.Snackbar;
import android.util.AttributeSet;
import android.view.View;
import net.i2p.android.ext.floatingactionbutton.FloatingActionsMenu;
import org.ligi.passandroid.R;
@SuppressWarnings("WeakerAccess")
public class MyShyFABBehavior extends CoordinatorLayout.Behavior<FloatingActionsMenu> {
public MyShyFABBehavior() {
}
public MyShyFABBehavior() {}
public MyShyFABBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionsMenu child, View dependency) {
public boolean layoutDependsOn(@NonNull CoordinatorLayout parent,
@NonNull FloatingActionsMenu child,
@NonNull View dependency) {
return dependency instanceof Snackbar.SnackbarLayout || dependency instanceof AppBarLayout;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionsMenu child, View dependency) {
public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent,
@NonNull FloatingActionsMenu child,
@NonNull View dependency) {
if (dependency instanceof Snackbar.SnackbarLayout) {
updateFabTranslationForSnackbar(child, dependency);
}
@ -40,23 +44,24 @@ public class MyShyFABBehavior extends CoordinatorLayout.Behavior<FloatingActions
} else {
distanceToScroll = (int) (child.getContext().getResources().getDimension(R.dimen.fab_size_normal) + 2 * fabBottomMargin);
}
final float ratio = ViewCompat.getY(dependency) / getToolbarHeight(dependency.getContext());
final float ratio = dependency.getY() / getToolbarHeight(dependency.getContext());
ViewCompat.setTranslationY(child, -distanceToScroll * ratio);
child.setTranslationY(-distanceToScroll * ratio);
}
return false;
}
@Override
public void onDependentViewRemoved(final CoordinatorLayout parent, final FloatingActionsMenu child, final View dependency) {
public void onDependentViewRemoved(@NonNull final CoordinatorLayout parent,
@NonNull final FloatingActionsMenu child,
@NonNull final View dependency) {
super.onDependentViewRemoved(parent, child, dependency);
onDependentViewChanged(parent,child,dependency);
}
private void updateFabTranslationForSnackbar(FloatingActionsMenu child, View dependency) {
final float translationY = ViewCompat.getTranslationY(dependency) - dependency.getHeight();
final float translationYClipped = Math.min(0, translationY);
ViewCompat.setTranslationY(child, translationYClipped);
final float translationY = dependency.getTranslationY() - dependency.getHeight();
child.setTranslationY(Math.min(0, translationY));
}
private int getToolbarHeight(Context context) {

View file

@ -4,7 +4,7 @@ import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.support.v7.app.AlertDialog
import androidx.appcompat.app.AlertDialog
import org.ligi.passandroid.R
import org.ligi.passandroid.model.pass.Pass
import org.ligi.passandroid.model.pass.PassLocation
@ -15,25 +15,26 @@ import java.net.URLEncoder
fun Activity.showNavigateToLocationsDialog(pass: Pass, finishOnDone: Boolean) {
val locations = pass.locations
if (locations.isEmpty()) {
done(this, finishOnDone)
} else if (locations.size == 1) {
startIntentForLocation(this, locations.first(), pass)
done(this, finishOnDone)
} else if (locations.size > 1) {
val locationDescriptions = arrayOfNulls<String>(locations.size)
var i = 0
for (loc in locations) {
locationDescriptions[i++] = loc.getNameWithFallback(pass)
when {
locations.isEmpty() -> done(this, finishOnDone)
locations.size == 1 -> {
startIntentForLocation(this, locations.first(), pass)
done(this, finishOnDone)
}
AlertDialog.Builder(this).setTitle(this.getString(R.string.choose_location))
.setItems(locationDescriptions) { _, which ->
startIntentForLocation(this, locations[which], pass)
done(this, finishOnDone)
}
.show()
locations.size > 1 -> {
val locationDescriptions = arrayOfNulls<String>(locations.size)
var i = 0
for (loc in locations) {
locationDescriptions[i++] = loc.getNameWithFallback(pass)
}
AlertDialog.Builder(this).setTitle(this.getString(R.string.choose_location))
.setItems(locationDescriptions) { _, which ->
startIntentForLocation(this, locations[which], pass)
done(this, finishOnDone)
}
.show()
}
}
}

View file

@ -1,9 +1,9 @@
package org.ligi.passandroid.ui
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.CardView
import android.support.v7.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import com.github.salomonbrys.kodein.instance
@ -26,12 +26,11 @@ class PassAdapter(private val passListActivity: AppCompatActivity, private val p
val inflater = LayoutInflater.from(viewGroup.context)
val res = inflater.inflate(R.layout.pass_list_item, viewGroup, false) as CardView
if (settings.isCondensedModeEnabled()) {
return CondensedPassViewHolder(res)
return if (settings.isCondensedModeEnabled()) {
CondensedPassViewHolder(res)
} else {
return VerbosePassViewHolder(res)
VerbosePassViewHolder(res)
}
}
override fun onBindViewHolder(viewHolder: PassViewHolder, position: Int) {

View file

@ -1,9 +1,8 @@
package org.ligi.passandroid.ui
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import com.github.salomonbrys.kodein.instance
import org.greenrobot.eventbus.EventBus
import org.ligi.kaxt.recreateWhenPossible
import org.ligi.passandroid.App
import org.ligi.passandroid.Tracker
import org.ligi.passandroid.model.PassStore
@ -22,7 +21,7 @@ open class PassAndroidActivity : AppCompatActivity() {
super.onResume()
if (lastSetNightMode != null && lastSetNightMode != settings.getNightMode()) {
recreateWhenPossible()
recreate()
}
lastSetNightMode = settings.getNightMode()
}

View file

@ -3,11 +3,12 @@ package org.ligi.passandroid.ui
import android.Manifest
import android.content.Intent
import android.os.Bundle
import android.support.annotation.IdRes
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import androidx.annotation.IdRes
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.ImageView
import com.github.salomonbrys.kodein.instance
import kotlinx.android.synthetic.main.edit.*
@ -58,7 +59,7 @@ class PassEditActivity : AppCompatActivity() {
when (i) {
0 -> showCategoryPickDialog(this@PassEditActivity, currentPass, bus)
1 -> showColorPickDialog(this@PassEditActivity, currentPass, bus)
2 -> PassEditActivityPermissionsDispatcher.pickImageWithCheck(this@PassEditActivity, ImageEditHelper.REQ_CODE_PICK_ICON)
2 -> pickImageWithPermissionCheck(ImageEditHelper.REQ_CODE_PICK_ICON)
}
}.show()
}
@ -103,7 +104,7 @@ class PassEditActivity : AppCompatActivity() {
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
PassEditActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults)
onRequestPermissionsResult(requestCode, grantResults)
}
private fun refresh(pass: Pass) {
@ -126,14 +127,14 @@ class PassEditActivity : AppCompatActivity() {
val bitmap = currentPass.getBitmap(passStore, imageString)
val addButton = findViewById(add_logo)!!
val addButton = findViewById<Button>(add_logo)!!
addButton.visibility = if (bitmap == null) View.VISIBLE else View.GONE
val listener = View.OnClickListener {
PassEditActivityPermissionsDispatcher.pickImageWithCheck(this@PassEditActivity, requestCode)
pickImageWithPermissionCheck(requestCode)
}
val logoImage = findViewById(logo_img) as ImageView
val logoImage = findViewById<ImageView>(logo_img)
passViewHelper.setBitmapSafe(logoImage, bitmap)
logoImage.setOnClickListener(listener)
addButton.setOnClickListener(listener)
@ -159,7 +160,5 @@ class PassEditActivity : AppCompatActivity() {
true
}
else -> super.onOptionsItemSelected(item)
}
}

View file

@ -4,35 +4,35 @@ import android.app.Activity
import android.app.ProgressDialog
import android.content.Intent
import android.os.Handler
import android.support.annotation.UiThread
import android.support.v4.content.FileProvider
import androidx.annotation.UiThread
import androidx.core.content.FileProvider
import android.widget.Toast
import org.ligi.passandroid.App
import org.ligi.passandroid.R
import java.io.File
internal open class PassExportTaskAndShare(protected val activity: Activity, val inputPath: File) {
internal open class PassExportTaskAndShare(protected val activity: Activity, private val inputPath: File) {
@UiThread
fun execute() {
val file = File(activity.filesDir, "share/share.espass") // important - the FileProvider must be configured for this path
val passExporter = PassExporter(inputPath, file)
val progress_dialog = ProgressDialog(activity)
progress_dialog.setTitle(R.string.preparing_pass)
progress_dialog.setMessage(activity.getString(R.string.please_wait))
progress_dialog.show()
val progressDialog = ProgressDialog(activity)
progressDialog.setTitle(R.string.preparing_pass)
progressDialog.setMessage(activity.getString(R.string.please_wait))
progressDialog.show()
val handler = Handler()
Thread(Runnable {
passExporter.export()
handler.post {
if (!activity.isFinishing && progress_dialog.isShowing) {
progress_dialog.dismiss()
if (!activity.isFinishing && progressDialog.isShowing) {
progressDialog.dismiss()
}
if (passExporter.exception != null) {
App.tracker.trackException("passExporterException", passExporter.exception, false)
Toast.makeText(activity, "could not export pass " + passExporter.exception, Toast.LENGTH_LONG).show()
App.tracker.trackException("passExporterException", passExporter.exception!!, false)
Toast.makeText(activity, "could not export pass: " + passExporter.exception, Toast.LENGTH_LONG).show()
} else {
val uriForFile = FileProvider.getUriForFile(activity, activity.getString(R.string.authority_fileprovider), file)
val it = Intent(Intent.ACTION_SEND)

View file

@ -2,9 +2,8 @@ package org.ligi.passandroid.ui
import android.Manifest
import android.app.ProgressDialog
import android.content.DialogInterface
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import com.github.salomonbrys.kodein.instance
import org.ligi.kaxt.dismissIfShowing
import org.ligi.kaxt.startActivityFromClass
@ -44,22 +43,21 @@ class PassImportActivity : AppCompatActivity() {
progressDialog.show()
doImport(false)
doImportWithPermissionCheck(false)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
PassImportActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults)
onRequestPermissionsResult(requestCode, grantResults)
}
@NeedsPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
fun doImport(withPermission: Boolean) {
Thread({
Thread {
try {
val fromURI = fromURI(this, intent.data)
val fromURI = fromURI(this, intent!!.data!!)
runOnUiThread({
runOnUiThread {
progressDialog.dismissIfShowing()
if (fromURI == null) {
@ -87,25 +85,20 @@ class PassImportActivity : AppCompatActivity() {
}
}
}
})
}
} catch (e: Exception) {
if (e.message?.contains("Permission") == true && !withPermission) {
PassImportActivityPermissionsDispatcher.doImportWithCheck(this@PassImportActivity, true)
doImportWithPermissionCheck(true)
} else {
tracker.trackException("Error in import", e, false)
}
}
}).start()
}.start()
}
@OnPermissionDenied(Manifest.permission.READ_EXTERNAL_STORAGE)
fun showDeniedDialog() {
progressDialog.dismissIfShowing()
alert(R.string.error_no_permission_msg, R.string.error_no_permission_title, onOKListener = DialogInterface.OnClickListener { _, _ -> finish() })
alert(R.string.error_no_permission_msg, R.string.error_no_permission_title, onOK = { finish() })
}
}

View file

@ -10,11 +10,11 @@ import android.content.Intent
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v4.view.GravityCompat
import android.support.v4.view.ViewPager
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AlertDialog
import com.google.android.material.snackbar.Snackbar
import androidx.core.view.GravityCompat
import androidx.viewpager.widget.ViewPager
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog
import android.view.Menu
import android.view.MenuItem
import android.view.View
@ -99,7 +99,7 @@ class PassListActivity : PassAndroidActivity() {
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
PassListActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults)
onRequestPermissionsResult(requestCode, grantResults)
}
@TargetApi(VERSION_STARTING_TO_SUPPORT_STORAGE_FRAMEWORK)
@ -162,7 +162,7 @@ class PassListActivity : PassAndroidActivity() {
override fun onPageSelected(position: Int) {
State.lastSelectedTab = position
supportInvalidateOptionsMenu()
invalidateOptionsMenu()
}
override fun onPageScrollStateChanged(state: Int) {
@ -189,7 +189,7 @@ class PassListActivity : PassAndroidActivity() {
}
fab_action_scan.setOnClickListener {
PassListActivityPermissionsDispatcher.scanWithCheck(this)
scanWithPermissionCheck()
fam.collapse()
}
@ -214,18 +214,21 @@ class PassListActivity : PassAndroidActivity() {
}
R.id.menu_emptytrash -> {
AlertDialog.Builder(this).setMessage(getString(R.string.empty_trash_dialog_message)).setIcon(R.drawable.ic_alert_warning).setTitle(getString(R.string.empty_trash_dialog_title)).setPositiveButton(R.string.emtytrash_label) { dialog, which ->
val passStoreProjection = PassStoreProjection(passStore,
getString(R.string.topic_trash),
null)
AlertDialog.Builder(this)
.setMessage(getString(R.string.empty_trash_dialog_message))
.setIcon(R.drawable.ic_alert_warning)
.setTitle(getString(R.string.empty_trash_dialog_title))
.setPositiveButton(R.string.emtytrash_label) { _, _ ->
val passStoreProjection = PassStoreProjection(passStore,
getString(R.string.topic_trash),
null)
for (pass in passStoreProjection.passList) {
passStore.deletePassWithId(pass.id)
}
for (pass in passStoreProjection.passList) {
passStore.deletePassWithId(pass.id)
}
}.setNegativeButton(android.R.string.cancel, null).show()
true
}
else -> drawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item)
}
@ -269,7 +272,7 @@ class PassListActivity : PassAndroidActivity() {
setupWithViewPagerIfNeeded()
supportInvalidateOptionsMenu()
invalidateOptionsMenu()
val empty = passStore.classifier.topicByIdMap.isEmpty()
emptyView.visibility = if (empty) View.VISIBLE else View.GONE
@ -284,7 +287,6 @@ class PassListActivity : PassAndroidActivity() {
}
private fun areTabLayoutAndViewPagerInSync(): Boolean {
if (adapter.count != tab_layout.tabCount) {
return false
}
@ -296,7 +298,6 @@ class PassListActivity : PassAndroidActivity() {
}
}
return true
}
override fun onBackPressed() {
@ -306,5 +307,4 @@ class PassListActivity : PassAndroidActivity() {
else -> super.onBackPressed()
}
}
}

View file

@ -1,13 +1,14 @@
package org.ligi.passandroid.ui
import android.os.Bundle
import android.support.annotation.VisibleForTesting
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.helper.ItemTouchHelper
import android.support.v7.widget.helper.ItemTouchHelper.*
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.ItemTouchHelper.*
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -38,7 +39,7 @@ class PassListFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val inflate = inflater.inflate(R.layout.pass_recycler, container, false)
passStoreProjection = PassStoreProjection(passStore, arguments.getString(BUNDLE_KEY_TOPIC)!!, settings.getSortOrder())
passStoreProjection = PassStoreProjection(passStore, arguments?.getString(BUNDLE_KEY_TOPIC)!!, settings.getSortOrder())
adapter = PassAdapter(activity as AppCompatActivity, passStoreProjection)
inflate.pass_recyclerview.adapter = adapter
@ -47,10 +48,10 @@ class PassListFragment : Fragment() {
val simpleItemTouchCallback = object : SimpleCallback(0, LEFT or RIGHT) {
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder)
override fun onMove(recyclerView: RecyclerView, viewHolder: ViewHolder, target: ViewHolder)
= false
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
override fun onSwiped(viewHolder: ViewHolder, swipeDir: Int) {
this@PassListFragment.onSwiped(viewHolder.adapterPosition, swipeDir)
}
}
@ -67,10 +68,12 @@ class PassListFragment : Fragment() {
val pass = passStoreProjection.passList[pos]
val nextTopic = passStore.classifier.getTopicWithOffset(pass, if (swipeDir == LEFT) -1 else 1)
if (nextTopic != null) {
moveWithUndoSnackbar(passStore.classifier, pass, nextTopic, activity)
} else {
MoveToNewTopicUI(activity, passStore, pass).show()
activity?.let {
if (nextTopic != null) {
moveWithUndoSnackbar(passStore.classifier, pass, nextTopic, it)
} else {
MoveToNewTopicUI(it, passStore, pass).show()
}
}
}
@ -93,12 +96,12 @@ class PassListFragment : Fragment() {
}
companion object {
private val BUNDLE_KEY_TOPIC = "topic"
private const val BUNDLE_KEY_TOPIC = "topic"
fun newInstance(topic: String) = PassListFragment().apply {
arguments = Bundle()
arguments.putString(BUNDLE_KEY_TOPIC, topic)
val bundle = Bundle()
bundle.putString(BUNDLE_KEY_TOPIC, topic)
arguments = bundle
}
}

View file

@ -2,8 +2,8 @@ package org.ligi.passandroid.ui
import android.app.Activity
import android.content.Intent
import android.support.v4.app.NavUtils
import android.support.v7.app.AlertDialog
import androidx.core.app.NavUtils
import androidx.appcompat.app.AlertDialog
import android.view.LayoutInflater
import android.view.MenuItem
import com.github.salomonbrys.kodein.instance

View file

@ -1,9 +1,10 @@
package org.ligi.passandroid.ui
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.support.design.widget.NavigationView
import com.google.android.material.navigation.NavigationView
import android.util.AttributeSet
import com.github.salomonbrys.kodein.instance
import kotlinx.android.synthetic.main.navigation_drawer_header.view.*
@ -20,9 +21,8 @@ class PassNavigationView(context: Context, attrs: AttributeSet) : NavigationView
val passStore: PassStore = App.kodein.instance()
val bus: EventBus = App.kodein.instance()
fun getIntent(id: Int) = when (id) {
private fun getIntent(id: Int) = when (id) {
R.id.menu_settings -> Intent(context, PreferenceActivity::class.java)
R.id.menu_plus -> intentFromUrl("https://plus.google.com/communities/116353894782342292067")
R.id.menu_github -> intentFromUrl("https://github.com/ligi/PassAndroid")
R.id.menu_beta -> intentFromUrl("https://play.google.com/apps/testing/org.ligi.passandroid")
R.id.menu_language -> intentFromUrl("https://transifex.com/projects/p/passandroid")
@ -33,8 +33,9 @@ class PassNavigationView(context: Context, attrs: AttributeSet) : NavigationView
else -> null
}
fun intentFromUrl(url: String) = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url) }
private fun intentFromUrl(url: String) = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url) }
@SuppressLint("RestrictedApi") // FIXME: temporary workaround for false-positive
override fun onAttachedToWindow() {
super.onAttachedToWindow()
@ -50,6 +51,7 @@ class PassNavigationView(context: Context, attrs: AttributeSet) : NavigationView
onPassStoreChangeEvent(PassStoreChangeEvent)
}
@SuppressLint("RestrictedApi") // FIXME: temporary workaround for false-positive
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
bus.unregister(this)

View file

@ -1,13 +1,13 @@
package org.ligi.passandroid.ui
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentStatePagerAdapter
import android.support.v4.view.PagerAdapter
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.viewpager.widget.PagerAdapter
import org.ligi.passandroid.model.PassClassifier
class PassTopicFragmentPagerAdapter(private val passClassifier: PassClassifier, fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
private lateinit var topic_array: Array<String>
private lateinit var topics: Array<String>
init {
notifyDataSetChanged()
@ -15,15 +15,16 @@ class PassTopicFragmentPagerAdapter(private val passClassifier: PassClassifier,
override fun notifyDataSetChanged() {
val topics = passClassifier.getTopics()
topic_array = topics.toTypedArray()
this.topics = topics.toTypedArray()
super.notifyDataSetChanged()
}
override fun getItem(position: Int) = PassListFragment.newInstance(topic_array[position])
override fun getItem(position: Int) = PassListFragment.newInstance(topics[position])
override fun getItemPosition(`object`: Any?) = PagerAdapter.POSITION_NONE // TODO - return POSITION_UNCHANGED in some cases
// TODO - return POSITION_UNCHANGED in some cases
override fun getItemPosition(`object`: Any) = PagerAdapter.POSITION_NONE
override fun getCount() = topic_array.size
override fun getCount() = topics.size
override fun getPageTitle(position: Int) = topic_array[position]
override fun getPageTitle(position: Int) = topics[position]
}

View file

@ -2,11 +2,14 @@ package org.ligi.passandroid.ui
import android.os.Build
import android.os.Bundle
import android.support.v4.app.*
import android.support.v4.view.ViewPager
import androidx.core.app.*
import androidx.viewpager.widget.ViewPager
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import kotlinx.android.synthetic.main.activity_pass_view_base.*
import org.ligi.kaxt.disableRotation
import org.ligi.passandroid.R
@ -20,6 +23,13 @@ class PassViewActivity : PassViewActivityBase() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= 27) {
setShowWhenLocked(true)
setTurnScreenOn(true)
} else {
this.window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
}
disableRotation()
setContentView(R.layout.activity_pass_view)
@ -30,8 +40,8 @@ class PassViewActivity : PassViewActivityBase() {
viewPager.adapter = pagerAdapter
viewPager.currentItem = pagerAdapter.getPos(currentPass)
viewPager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(i: Int) {
currentPass = pagerAdapter.getPass(i)
override fun onPageSelected(pos: Int) {
currentPass = pagerAdapter.getPass(pos)
passStore.currentPass = currentPass
}
})
@ -95,18 +105,18 @@ class PassViewActivity : PassViewActivityBase() {
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
android.R.id.home -> {
val upIntent = NavUtils.getParentActivityIntent(this)
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities()
finish()
} else {
NavUtils.navigateUpTo(this, upIntent)
if (upIntent != null) {
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities()
finish()
} else {
NavUtils.navigateUpTo(this, upIntent)
}
true
}
true
else false
}
else -> super.onOptionsItemSelected(item)
}
override fun onAttachedToWindow() = window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
}

View file

@ -5,12 +5,15 @@ import android.app.Dialog
import android.app.ProgressDialog
import android.content.ComponentName
import android.content.Intent
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.Icon
import android.os.Build
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v7.app.AlertDialog
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AlertDialog
import android.view.*
import okhttp3.OkHttpClient
import okhttp3.Request
@ -25,6 +28,7 @@ import org.ligi.passandroid.ui.UnzipPassController.InputStreamUnzipControllerSpe
import permissions.dispatcher.NeedsPermission
import permissions.dispatcher.RuntimePermissions
import java.io.IOException
import java.util.*
@SuppressLint("Registered")
@RuntimePermissions
@ -44,10 +48,8 @@ open class PassViewActivityBase : PassAndroidActivity() {
try {
val config = ViewConfiguration.get(this)
val menuKeyField = ViewConfiguration::class.java.getDeclaredField("sHasPermanentMenuKey")
if (menuKeyField != null) {
menuKeyField.isAccessible = true
menuKeyField.setBoolean(config, false)
}
menuKeyField.isAccessible = true
menuKeyField.setBoolean(config, false)
} catch (ex: Exception) {
// Ignore - but at least we tried ;-)
}
@ -82,7 +84,7 @@ open class PassViewActivityBase : PassAndroidActivity() {
}
if (passStore.currentPass == null) {
tracker.trackException("pass not present in " + this, false)
tracker.trackException("pass not present in $this", false)
finish()
return
}
@ -127,7 +129,7 @@ open class PassViewActivityBase : PassAndroidActivity() {
}
R.id.install_shortcut -> {
PassViewActivityBasePermissionsDispatcher.createShortcutWithCheck(this)
createShortcutWithPermissionCheck()
true
}
@ -143,28 +145,39 @@ open class PassViewActivityBase : PassAndroidActivity() {
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
PassViewActivityBasePermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults)
onRequestPermissionsResult(requestCode, grantResults)
}
@NeedsPermission("com.android.launcher.permission.INSTALL_SHORTCUT")
fun createShortcut() {
val intent = Intent("com.android.launcher.action.INSTALL_SHORTCUT")
val shortcutIntent = Intent()
shortcutIntent.putExtra(EXTRA_KEY_UUID, currentPass.id)
val component = ComponentName(BuildConfig.APPLICATION_ID, BuildConfig.APPLICATION_ID + ".ui.PassViewActivity")
shortcutIntent.component = component
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent)
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, currentPass.description)
shortcutIntent.component = ComponentName(BuildConfig.APPLICATION_ID,
BuildConfig.APPLICATION_ID + ".ui.PassViewActivity")
val passBitmap = currentPass.getBitmap(passStore, BITMAP_ICON)
val bitmapToUse = if (passBitmap != null) {
val shortcutIcon = if (passBitmap != null) {
Bitmap.createScaledBitmap(passBitmap, 128, 128, true)
} else {
BitmapFactory.decodeResource(resources, R.drawable.ic_launcher)
}
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmapToUse)
sendBroadcast(intent)
if (Build.VERSION.SDK_INT >= 25) {
val shortcutManager = getSystemService<ShortcutManager>(ShortcutManager::class.java)
val shortcut = ShortcutInfo.Builder(this, "id1")
.setShortLabel(currentPass.description ?: "")
.setIcon(Icon.createWithBitmap(shortcutIcon))
.setIntent(shortcutIntent)
.build()
shortcutManager.dynamicShortcuts = Arrays.asList(shortcut)
} else {
val intent = Intent("com.android.launcher.action.INSTALL_SHORTCUT")
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent)
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, currentPass.description)
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, shortcutIcon)
sendBroadcast(intent)
}
}
inner class UpdateAsync : Runnable {
@ -183,7 +196,7 @@ open class PassViewActivityBase : PassAndroidActivity() {
val url = pass.webServiceURL + "/v1/passes/" + pass.passIdent + "/" + pass.serial
val requestBuilder = Request.Builder().url(url)
requestBuilder.addHeader("Authorization", "ApplePass " + pass.authToken!!)
requestBuilder.addHeader("Authorization", "ApplePass " + pass.authToken)
val request = requestBuilder.build()
@ -250,7 +263,7 @@ open class PassViewActivityBase : PassAndroidActivity() {
params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL
win.attributes = params
fullBrightnessSet = true
supportInvalidateOptionsMenu()
invalidateOptionsMenu()
}
companion object {

View file

@ -2,14 +2,15 @@ package org.ligi.passandroid.ui
import android.content.Intent
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.text.util.LinkifyCompat
import androidx.fragment.app.Fragment
import androidx.core.text.util.LinkifyCompat
import android.text.util.Linkify
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.fragment.app.FragmentActivity
import com.github.salomonbrys.kodein.instance
import kotlinx.android.synthetic.main.activity_pass_view.*
import kotlinx.android.synthetic.main.barcode.*
@ -27,7 +28,7 @@ import org.ligi.passandroid.ui.pass_view_holder.VerbosePassViewHolder
class PassViewFragment : Fragment() {
private val passViewHelper by lazy { PassViewHelper(activity) }
private val passViewHelper by lazy { PassViewHelper(requireActivity()) }
private var passStore : PassStore = App.kodein.instance()
lateinit var pass : Pass
@ -57,10 +58,10 @@ class PassViewFragment : Fragment() {
}
barcode_img.setOnClickListener {
activity.startActivityFromClass(FullscreenBarcodeActivity::class.java)
activity?.startActivityFromClass(FullscreenBarcodeActivity::class.java)
}
BarcodeUIController(view!!, pass.barCode, activity, passViewHelper)
BarcodeUIController(view!!, pass.barCode, activity!!, passViewHelper)
processImage(logo_img_view, PassBitmapDefinitions.BITMAP_LOGO, pass)
processImage(footer_img_view, PassBitmapDefinitions.BITMAP_FOOTER, pass)
@ -68,7 +69,7 @@ class PassViewFragment : Fragment() {
processImage(strip_img_view, PassBitmapDefinitions.BITMAP_STRIP, pass)
if (map_container != null) {
if (!(pass.locations.isNotEmpty() && PassbookMapsFacade.init(activity))) {
if (!(pass.locations.isNotEmpty() && PassbookMapsFacade.init(activity as FragmentActivity))) {
@Suppress("PLUGIN_WARNING")
map_container.visibility = View.GONE
}
@ -82,15 +83,15 @@ class PassViewFragment : Fragment() {
if (field.hide) {
backStrBuilder.append(field.toHtmlSnippet())
} else {
val v = activity.layoutInflater.inflate(R.layout.main_field_item, front_field_container, false)
val key = v.findViewById(R.id.key) as TextView
key.text = field.label
val value = v.findViewById(R.id.value) as TextView
value.text = field.value
val v = activity!!.layoutInflater.inflate(R.layout.main_field_item, front_field_container, false)
val key = v?.findViewById<TextView>(R.id.key)
key?.text = field.label
val value = v?.findViewById<TextView>(R.id.value)
value?.text = field.value
front_field_container.addView(v)
LinkifyCompat.addLinks(key, Linkify.ALL)
LinkifyCompat.addLinks(value, Linkify.ALL)
key?.let { LinkifyCompat.addLinks(it, Linkify.ALL) }
value?.let { LinkifyCompat.addLinks(it, Linkify.ALL) }
}
}
@ -104,8 +105,7 @@ class PassViewFragment : Fragment() {
LinkifyCompat.addLinks(back_fields, Linkify.ALL)
val passViewHolder = VerbosePassViewHolder(pass_card)
passViewHolder.apply(pass, passStore, activity)
passViewHolder.apply(pass, passStore, activity!!)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
@ -114,7 +114,6 @@ class PassViewFragment : Fragment() {
val rootView = inflater.inflate(R.layout.activity_pass_view_page, container, false)
arguments?.takeIf { it.containsKey(PassViewActivityBase.EXTRA_KEY_UUID) }?.apply {
val uuid = getString(PassViewActivityBase.EXTRA_KEY_UUID)
pass = if (uuid != null) {
passStore.getPassbookForId(uuid) ?: passStore.currentPass!!
} else {
@ -125,10 +124,10 @@ class PassViewFragment : Fragment() {
return rootView
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val passExtrasView = activity.layoutInflater.inflate(R.layout.pass_view_extra_data, passExtrasContainer, false)
val passExtrasView = activity!!.layoutInflater.inflate(R.layout.pass_view_extra_data, passExtrasContainer, false)
passExtrasContainer.addView(passExtrasView)
}
}

View file

@ -17,13 +17,13 @@ class PassViewHelper(private val context: Activity) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap)
imageView.visibility = View.VISIBLE
imageView.layoutParams = getLayoutParamsSoThatWeHaveMinimumAFingerInHeight(imageView, bitmap)
imageView.layoutParams = getLayoutParamsMinHeight(imageView, bitmap)
} else {
imageView.visibility = View.GONE
}
}
fun getLayoutParamsSoThatWeHaveMinimumAFingerInHeight(imageView: ImageView, bitmap: Bitmap)
private fun getLayoutParamsMinHeight(imageView: ImageView, bitmap: Bitmap)
= imageView.layoutParams!!.apply {
height = if (bitmap.height < fingerSize) {
fingerSize
@ -33,5 +33,4 @@ class PassViewHelper(private val context: Activity) {
}
val windowWidth by lazy { context.windowManager.getSizeAsPointCompat().x }
}

View file

@ -2,7 +2,7 @@ package org.ligi.passandroid.ui
import android.annotation.SuppressLint
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import android.view.MenuItem
import org.ligi.passandroid.R

View file

@ -3,10 +3,9 @@ package org.ligi.passandroid.ui
import android.Manifest
import android.content.SharedPreferences
import android.os.Bundle
import android.support.v7.app.AppCompatDelegate
import android.support.v7.app.AppCompatDelegate.MODE_NIGHT_AUTO
import android.support.v7.preference.PreferenceFragmentCompat
import org.ligi.kaxt.recreateWhenPossible
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO
import androidx.preference.PreferenceFragmentCompat
import org.ligi.passandroid.App
import org.ligi.passandroid.R
import permissions.dispatcher.NeedsPermission
@ -27,15 +26,14 @@ class PrefsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPref
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
if (key == getString(R.string.preference_key_nightmode)) {
@AppCompatDelegate.NightMode val nightMode = App.settings.getNightMode()
if (nightMode == MODE_NIGHT_AUTO) {
PrefsFragmentPermissionsDispatcher.ensureDayNightWithCheck(this)
ensureDayNightWithPermissionCheck()
}
AppCompatDelegate.setDefaultNightMode(nightMode)
activity.recreateWhenPossible()
activity?.recreate()
}
}
@ -51,7 +49,7 @@ class PrefsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPref
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
PrefsFragmentPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults)
onRequestPermissionsResult(requestCode, grantResults)
}
}

View file

@ -8,7 +8,7 @@ import android.content.Intent
import android.net.Uri
import android.os.Environment
import android.preference.PreferenceManager
import android.support.v4.app.NotificationCompat
import androidx.core.app.NotificationCompat
import com.github.salomonbrys.kodein.instance
import org.greenrobot.eventbus.EventBus
import org.ligi.passandroid.App
@ -57,7 +57,7 @@ class SearchPassesIntentService : IntentService("SearchPassesIntentService") {
val preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
for (path in PastLocationsStore(preferences, tracker).locations) {
search_in(File(path), false)
searchIn(File(path), false)
}
// note to future_me: yea one thinks we only need to search root here, but root was /system for me and so
@ -69,19 +69,19 @@ class SearchPassesIntentService : IntentService("SearchPassesIntentService") {
// up the refreshing of passes as it took so long to traverse all files on the SDCard
// one could think about not going there anymore but a short look at this showed that it seems cost more time to check than what it gains
// in download there are mostly single files in a flat dir - no huge tree behind this imho
search_in(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), true)
searchIn(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), true)
// | /system
search_in(Environment.getRootDirectory(), true)
searchIn(Environment.getRootDirectory(), true)
// | /mnt/sdcard
search_in(Environment.getExternalStorageDirectory(), true)
searchIn(Environment.getExternalStorageDirectory(), true)
// | /cache
search_in(Environment.getDownloadCacheDirectory(), true)
searchIn(Environment.getDownloadCacheDirectory(), true)
// | /data
search_in(Environment.getDataDirectory(), true)
searchIn(Environment.getDataDirectory(), true)
notifyManager!!.cancel(PROGRESS_NOTIFICATION_ID)
bus.post(ScanFinishedEvent(foundList!!))
@ -90,7 +90,7 @@ class SearchPassesIntentService : IntentService("SearchPassesIntentService") {
/**
* recursive voyage starting at path to find files named .pkpass
*/
private fun search_in(path: File, recursive: Boolean) {
private fun searchIn(path: File, recursive: Boolean) {
if (System.currentTimeMillis() - lastProgressUpdate > 1000) {
lastProgressUpdate = System.currentTimeMillis()
@ -114,7 +114,7 @@ class SearchPassesIntentService : IntentService("SearchPassesIntentService") {
}
Log.i("search " + file.absoluteFile)
if (recursive && file.isDirectory) {
search_in(file, true)
searchIn(file, true)
} else if (file.name.toLowerCase().endsWith(".pkpass") || file.name.toLowerCase().endsWith(".espass")) {
Log.i("found" + file.absolutePath)
@ -149,10 +149,8 @@ class SearchPassesIntentService : IntentService("SearchPassesIntentService") {
}
companion object {
val PROGRESS_NOTIFICATION_ID = 1
val FOUND_NOTIFICATION_ID = 2
val REQUEST_CODE = 1
const val PROGRESS_NOTIFICATION_ID = 1
const val FOUND_NOTIFICATION_ID = 2
const val REQUEST_CODE = 1
}
}

View file

@ -5,7 +5,7 @@ import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.support.v4.app.NotificationCompat
import androidx.core.app.NotificationCompat
import org.ligi.passandroid.R
import org.ligi.passandroid.model.PassBitmapDefinitions
import org.ligi.passandroid.model.PassStore

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.ui
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import android.view.MenuItem
import com.github.salomonbrys.kodein.instance
import com.ortiz.touch.TouchImageView

View file

@ -39,7 +39,7 @@ object UnzipPassController {
tempFile.delete()
} catch (e: Exception) {
App.tracker.trackException("problem processing InputStream", e, false)
spec.failCallback?.fail("problem with temp file" + e)
spec.failCallback?.fail("problem with temp file: $e")
}
}
@ -47,12 +47,12 @@ object UnzipPassController {
private fun processFile(spec: FileUnzipControllerSpec) {
var uuid = UUID.randomUUID().toString()
val path = File(spec.context.cacheDir, "temp/" + uuid)
val path = File(spec.context.cacheDir, "temp/$uuid")
path.mkdirs()
if (!path.exists()) {
spec.failCallback?.fail("Problem creating the temp dir: " + path)
spec.failCallback?.fail("Problem creating the temp dir: $path")
return
}
@ -66,94 +66,89 @@ object UnzipPassController {
}
val manifest_json: JSONObject
val manifestFile = File(path, "manifest.json")
val espassFile = File(path, "main.json")
val manifestJSON: JSONObject
if (manifestFile.exists()) {
try {
when {
manifestFile.exists() -> try {
val readToString = manifestFile.bufferedReader().readText()
manifest_json = readJSONSafely(readToString)!!
uuid = manifest_json.getString("pass.json")
manifestJSON = readJSONSafely(readToString)!!
uuid = manifestJSON.getString("pass.json")
} catch (e: Exception) {
spec.failCallback?.fail("Problem with manifest.json: " + e)
spec.failCallback?.fail("Problem with manifest.json: $e")
return
}
} else if (espassFile.exists()) {
try {
espassFile.exists() -> try {
val readToString = espassFile.bufferedReader().readText()
manifest_json = readJSONSafely(readToString)!!
uuid = manifest_json.getString("id")
manifestJSON = readJSONSafely(readToString)!!
uuid = manifestJSON.getString("id")
} catch (e: Exception) {
spec.failCallback?.fail("Problem with manifest.json: " + e)
spec.failCallback?.fail("Problem with manifest.json: $e")
return
}
else -> {
val bitmap = BitmapFactory.decodeFile(spec.zipFileString)
val resources = spec.context.resources
} else {
if (bitmap != null) {
val imagePass = createPassForImageImport(resources)
val pathForID = spec.passStore.getPathForID(imagePass.id)
pathForID.mkdirs()
File(spec.zipFileString).copyTo(File(pathForID, "strip.png"))
val bitmap = BitmapFactory.decodeFile(spec.zipFileString)
val resources = spec.context.resources
if (bitmap != null) {
val imagePass = createPassForImageImport(resources)
val pathForID = spec.passStore.getPathForID(imagePass.id)
pathForID.mkdirs()
File(spec.zipFileString).copyTo(File(pathForID, "strip.png"))
spec.passStore.save(imagePass)
spec.passStore.classifier.moveToTopic(imagePass, "new")
spec.onSuccessCallback?.call(imagePass.id)
return
}
if (Build.VERSION.SDK_INT >= 21) {
try {
val file = File(spec.zipFileString)
val readUtf8 = Okio.buffer(Okio.source(file)).readUtf8(4)
if (readUtf8 == "%PDF") {
val open = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
val pdfRenderer = PdfRenderer(open)
val page = pdfRenderer.openPage(0)
val ratio = page.height.toFloat() / page.width
val widthPixels = resources.displayMetrics.widthPixels
val createBitmap = Bitmap.createBitmap(widthPixels, (widthPixels * ratio).toInt(), Bitmap.Config.ARGB_8888)
page.render(createBitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
val imagePass = createPassForPDFImport(resources)
val pathForID = spec.passStore.getPathForID(imagePass.id)
pathForID.mkdirs()
createBitmap.compress(Bitmap.CompressFormat.PNG, 100, FileOutputStream(File(pathForID, "strip.png")))
spec.passStore.save(imagePass)
spec.passStore.classifier.moveToTopic(imagePass, "new")
spec.onSuccessCallback?.call(imagePass.id)
return
}
} catch (e: Exception) {
e.printStackTrace()
spec.passStore.save(imagePass)
spec.passStore.classifier.moveToTopic(imagePass, "new")
spec.onSuccessCallback?.call(imagePass.id)
return
}
}
if (Build.VERSION.SDK_INT >= 21) {
try {
val file = File(spec.zipFileString)
val readUtf8 = Okio.buffer(Okio.source(file)).readUtf8(4)
if (readUtf8 == "%PDF") {
val open = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
val pdfRenderer = PdfRenderer(open)
spec.failCallback?.fail("Pass is not espass or pkpass format :-(")
return
val page = pdfRenderer.openPage(0)
val ratio = page.height.toFloat() / page.width
val widthPixels = resources.displayMetrics.widthPixels
val createBitmap = Bitmap.createBitmap(widthPixels, (widthPixels * ratio).toInt(), Bitmap.Config.ARGB_8888)
page.render(createBitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
val imagePass = createPassForPDFImport(resources)
val pathForID = spec.passStore.getPathForID(imagePass.id)
pathForID.mkdirs()
createBitmap.compress(Bitmap.CompressFormat.PNG, 100, FileOutputStream(File(pathForID, "strip.png")))
spec.passStore.save(imagePass)
spec.passStore.classifier.moveToTopic(imagePass, "new")
spec.onSuccessCallback?.call(imagePass.id)
return
}
} catch (e: Exception) {
e.printStackTrace()
}
}
spec.failCallback?.fail("Pass is not espass or pkpass format :-(")
return
}
}
spec.targetPath.mkdirs()
val rename_file = File(spec.targetPath, uuid)
val renamedFile = File(spec.targetPath, uuid)
if (spec.overwrite && rename_file.exists()) {
rename_file.deleteRecursively()
if (spec.overwrite && renamedFile.exists()) {
renamedFile.deleteRecursively()
}
if (!rename_file.exists()) {
path.renameTo(rename_file)
if (!renamedFile.exists()) {
path.renameTo(renamedFile)
} else {
Log.i("Pass with same ID exists")
}

View file

@ -2,7 +2,7 @@ package org.ligi.passandroid.ui
import android.app.Activity
import android.app.ProgressDialog
import android.support.v7.app.AlertDialog
import androidx.appcompat.app.AlertDialog
import org.ligi.passandroid.R
import org.ligi.passandroid.model.InputStreamWithSource
import org.ligi.passandroid.model.PassStore

View file

@ -1,6 +1,6 @@
package org.ligi.passandroid.ui;
import android.support.annotation.IntDef;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import static android.view.View.GONE;

View file

@ -8,8 +8,8 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.appcompat.app.AlertDialog;
import android.util.Log;
import java.util.Arrays;
import java.util.Collection;
@ -90,6 +90,7 @@ import java.util.Map;
* @author Brad Drehmer
* @author gcstang
*/
@SuppressWarnings("WeakerAccess")
public class BarCodeIntentIntegrator {
public static final int REQUEST_CODE = 0x0000c0de; // Only use bottom 16 bits
@ -130,7 +131,7 @@ public class BarCodeIntentIntegrator {
private String buttonYes;
private String buttonNo;
private List<String> targetApplications;
private final Map<String, Object> moreExtras = new HashMap<String, Object>(3);
private final Map<String, Object> moreExtras = new HashMap<>(3);
/**
* @param activity {@link Activity} invoking the integration
@ -313,7 +314,7 @@ public class BarCodeIntentIntegrator {
* @see android.app.Activity#startActivityForResult(Intent, int)
* @see android.app.Fragment#startActivityForResult(Intent, int)
*/
protected void startActivityForResult(Intent intent, int code) {
private void startActivityForResult(Intent intent, @SuppressWarnings("SameParameterValue") int code) {
if (fragment == null) {
activity.startActivityForResult(intent, code);
} else {

View file

@ -1,8 +1,8 @@
package org.ligi.passandroid.ui.edit
import android.content.Intent
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.appcompat.app.AppCompatActivity
import android.view.View
import android.widget.RadioButton
import kotlinx.android.synthetic.main.barcode_edit.view.*
@ -14,14 +14,11 @@ import org.ligi.passandroid.ui.BarcodeUIController
import org.ligi.passandroid.ui.PassViewHelper
import java.util.*
class BarcodeEditController(val rootView: View, internal val context: AppCompatActivity, barCode: BarCode) {
var barcodeFormat: PassBarCodeFormat?
internal val intentFragment: Fragment
class BarcodeEditController(private val rootView: View, internal val context: AppCompatActivity, barCode: BarCode) {
private var barcodeFormat: PassBarCodeFormat?
private val intentFragment: Fragment
class IntentFragment : Fragment() {
var scanCallback: (String) -> Unit = {}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -37,7 +34,7 @@ class BarcodeEditController(val rootView: View, internal val context: AppCompatA
rootView.barcodeRadioGroup.addView(radioButton)
radioButton.text = it.name
radioButton.setOnCheckedChangeListener { buttonView, isChecked ->
radioButton.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
barcodeFormat = it
refresh()
@ -53,7 +50,7 @@ class BarcodeEditController(val rootView: View, internal val context: AppCompatA
intentFragment = IntentFragment()
barcodeFormat = barCode.format
rootView.randomButton.setOnClickListener({
rootView.randomButton.setOnClickListener {
rootView.messageInput.setText(when (barcodeFormat) {
EAN_8 -> getRandomEAN8()
EAN_13 -> getRandomEAN13()
@ -61,9 +58,9 @@ class BarcodeEditController(val rootView: View, internal val context: AppCompatA
else -> UUID.randomUUID().toString().toUpperCase()
})
refresh()
})
}
rootView.scanButton.setOnClickListener({
rootView.scanButton.setOnClickListener {
val barCodeIntentIntegrator = BarCodeIntentIntegrator(intentFragment)
if (barcodeFormat == QR_CODE) {
@ -72,7 +69,7 @@ class BarcodeEditController(val rootView: View, internal val context: AppCompatA
barCodeIntentIntegrator.initiateScan(setOf(barcodeFormat!!.name))
}
})
}
intentFragment.scanCallback = { newMessage ->
rootView.messageInput.setText(newMessage)

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.ui.edit
import android.os.Bundle
import android.support.v4.app.Fragment
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -26,7 +26,7 @@ class FieldsEditFragment : Fragment() {
this.inflater = inflater
val inflate = inflater.inflate(R.layout.edit_fields, container, false)
isEditingHiddenFields = arguments.getBoolean(ARGUMENT_KEY)
arguments?.let { isEditingHiddenFields = it.getBoolean(ARGUMENT_KEY) }
if (isEditingHiddenFields) {
inflate.add_field.setText(R.string.add_back_fields)
@ -74,7 +74,7 @@ class FieldsEditFragment : Fragment() {
companion object {
private val ARGUMENT_KEY = "KEY"
private const val ARGUMENT_KEY = "KEY"
fun create(primary: Boolean): FieldsEditFragment {
val fieldsEditFragment = FieldsEditFragment()

View file

@ -46,12 +46,12 @@ class ImageEditHelper(private val context: Activity, private val passStore: Pass
companion object {
private val REQ_CODE_OFFSET = 5555
val REQ_CODE_PICK_LOGO = 1 + REQ_CODE_OFFSET
val REQ_CODE_PICK_ICON = 2 + REQ_CODE_OFFSET
val REQ_CODE_PICK_STRIP = 3 + REQ_CODE_OFFSET
val REQ_CODE_PICK_THUMBNAIL = 4 + REQ_CODE_OFFSET
val REQ_CODE_PICK_FOOTER = 5 + REQ_CODE_OFFSET
private const val REQ_CODE_OFFSET = 5555
const val REQ_CODE_PICK_LOGO = 1 + REQ_CODE_OFFSET
const val REQ_CODE_PICK_ICON = 2 + REQ_CODE_OFFSET
const val REQ_CODE_PICK_STRIP = 3 + REQ_CODE_OFFSET
const val REQ_CODE_PICK_THUMBNAIL = 4 + REQ_CODE_OFFSET
const val REQ_CODE_PICK_FOOTER = 5 + REQ_CODE_OFFSET
@Pass.PassBitmap
fun getImageStringByRequestCode(requestCode: Int): String? = when (requestCode) {

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.ui.edit.dialogs
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import org.greenrobot.eventbus.EventBus
import org.ligi.kaxt.inflate
import org.ligi.passandroid.R

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.ui.edit.dialogs
import android.content.Context
import android.support.v7.app.AlertDialog
import androidx.appcompat.app.AlertDialog
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.ui.edit.dialogs
import android.content.Context
import android.support.v7.app.AlertDialog
import androidx.appcompat.app.AlertDialog
import android.view.LayoutInflater
import kotlinx.android.synthetic.main.edit_color.view.*
import org.greenrobot.eventbus.EventBus

View file

@ -1,7 +1,7 @@
package org.ligi.passandroid.ui.pass_view_holder
import android.app.Activity
import android.support.v7.widget.CardView
import androidx.cardview.widget.CardView
import android.view.View
import kotlinx.android.synthetic.main.pass_list_item.view.*
import kotlinx.android.synthetic.main.time_and_nav.view.*

View file

@ -3,8 +3,8 @@ package org.ligi.passandroid.ui.pass_view_holder
import android.app.Activity
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.support.v7.app.AlertDialog
import android.support.v7.widget.CardView
import androidx.appcompat.app.AlertDialog
import androidx.cardview.widget.CardView
import android.view.View.VISIBLE
import android.widget.DatePicker
import android.widget.TimePicker
@ -19,9 +19,9 @@ import org.threeten.bp.ZonedDateTime
class EditViewHolder(view: CardView) : VerbosePassViewHolder(view), TimePickerDialog.OnTimeSetListener, DatePickerDialog.OnDateSetListener {
lateinit private var time: ZonedDateTime
lateinit private var pass: PassImpl
lateinit private var passStore: PassStore
private lateinit var time: ZonedDateTime
private lateinit var pass: PassImpl
private lateinit var passStore: PassStore
override fun apply(pass: Pass, passStore: PassStore, activity: Activity) {
super.apply(pass, passStore, activity)
@ -30,7 +30,7 @@ class EditViewHolder(view: CardView) : VerbosePassViewHolder(view), TimePickerDi
this.passStore = passStore
val calendarTimespan = pass.calendarTimespan
time = if (calendarTimespan != null && calendarTimespan.from != null) {
time = if (calendarTimespan?.from != null) {
calendarTimespan.from
} else {
ZonedDateTime.now()

View file

@ -1,8 +1,8 @@
package org.ligi.passandroid.ui.pass_view_holder
import android.app.Activity
import android.support.v7.widget.CardView
import android.support.v7.widget.RecyclerView
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
import android.text.format.DateUtils
import android.view.View.*
import kotlinx.android.synthetic.main.pass_list_item.view.*

Some files were not shown because too many files have changed in this diff Show more