diff --git a/app/build.gradle b/app/build.gradle
index e633f19c..ab1a65b2 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -72,7 +72,7 @@ dependencies {
// Android
implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.core:core-ktx:1.1.0-alpha05'
+ implementation 'androidx.core:core-ktx:1.2.0-alpha01'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
@@ -88,13 +88,15 @@ dependencies {
implementation 'com.google.android.libraries.places:places:1.1.0'
// Billing / Subscriptions
+ // WARNING FOR 2.0: https://developer.android.com/google/play/billing/billing_library_releases_notes
+ // Purchases MUST BE ACKNOWLEDGED
implementation 'com.android.billingclient:billing:1.2.2'
// Firebase
- implementation 'com.google.firebase:firebase-core:16.0.8'
+ implementation 'com.google.firebase:firebase-core:16.0.9'
// Crashlytics
- implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
+ implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
// Logs
implementation 'com.jakewharton.timber:timber:4.7.1'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b068e33e..de2ea637 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -22,6 +22,7 @@
@@ -30,11 +31,6 @@
-
-
-
@@ -49,6 +45,13 @@
+
+
+
+
().equalTo("name", name).findFirst()
- return if (bankroll != null) {
- bankroll
+ val br = realm.where().equalTo("name", name).findFirst()
+ return if (br != null) {
+ br
} else {
val bankroll = Bankroll()
bankroll.name = name
+ bankroll.live = live
val currency = Currency()
currency.code = currencyCode
currency.rate = currencyRate
diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt
index 95fea7f9..76cce72c 100644
--- a/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt
+++ b/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt
@@ -7,9 +7,7 @@ import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.SessionSet
import kotlin.math.max
-class CorruptSessionSetException(message: String) : Exception(message) {
-
-}
+class CorruptSessionSetException(message: String) : Exception(message)
/**
* The manager is in charge of updating the abstract concept of timeline,
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt
index 6bfbf3a5..d58ad551 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt
@@ -3,6 +3,7 @@ package net.pokeranalytics.android.ui.activity
import android.app.KeyguardManager
import android.content.Context
import android.content.Intent
+import android.net.Uri
import android.os.Build
import android.os.Bundle
import com.google.android.material.bottomnavigation.BottomNavigationView
@@ -13,7 +14,9 @@ import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Currency
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.adapter.HomePagerAdapter
+import net.pokeranalytics.android.ui.extensions.showAlertDialog
import net.pokeranalytics.android.util.billing.AppGuard
+import timber.log.Timber
class HomeActivity : PokerAnalyticsActivity() {
@@ -75,6 +78,30 @@ class HomeActivity : PokerAnalyticsActivity() {
}
+ override fun onNewIntent(intent: Intent?) {
+ super.onNewIntent(intent)
+
+ intent?.let {
+
+ when (intent.action) {
+ "android.intent.action.VIEW" -> { // import
+ val data = it.data
+ if (data != null) {
+ this.requestImportConfirmation(data)
+ } else {
+ throw IllegalStateException("URI null on import")
+ }
+ }
+ else -> {
+ Timber.d("Intent ${intent.action} unmanaged")
+ }
+ }
+
+ }
+
+
+ }
+
private fun observeRealmObjects() {
val realm = getRealm()
@@ -125,4 +152,14 @@ class HomeActivity : PokerAnalyticsActivity() {
viewPager.setCurrentItem(index, false)
}
+ // Import
+
+ fun requestImportConfirmation(uri: Uri) {
+
+ showAlertDialog(this, R.string.import_confirmation, showCancelButton = true, positiveAction = {
+ ImportActivity.newInstance(this, uri)
+ })
+
+ }
+
}
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt
index fc86d727..55b8f7f9 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/ImportActivity.kt
@@ -1,12 +1,9 @@
package net.pokeranalytics.android.ui.activity
-import android.Manifest
import android.content.Context
import android.content.Intent
-import android.content.pm.PackageManager
+import android.net.Uri
import android.os.Bundle
-import android.os.PersistableBundle
-import androidx.core.app.ActivityCompat
import io.realm.Realm
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
@@ -15,8 +12,10 @@ import timber.log.Timber
class ImportActivity : PokerAnalyticsActivity() {
+ private lateinit var fileURI: Uri
+
enum class IntentKey(val keyName: String) {
- FILE_PATH("filepath")
+ URI("uri")
}
companion object {
@@ -24,25 +23,24 @@ class ImportActivity : PokerAnalyticsActivity() {
/**
* Create a new instance for result
*/
- fun newInstance(context: Context, filePath: String) {
- context.startActivity(getIntent(context, filePath))
+ fun newInstance(context: Context, uri: Uri) {
+ context.startActivity(getIntent(context, uri))
}
- private fun getIntent(context: Context, filePath: String) : Intent {
+ private fun getIntent(context: Context, uri: Uri) : Intent {
val intent = Intent(context, ImportActivity::class.java)
- intent.putExtra(ImportActivity.IntentKey.FILE_PATH.keyName, filePath)
+ intent.putExtra(ImportActivity.IntentKey.URI.keyName, uri)
return intent
}
}
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
- override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
- super.onCreate(savedInstanceState, persistentState)
+ this.fileURI = intent.getParcelableExtra(ImportActivity.IntentKey.URI.keyName)
setContentView(R.layout.activity_import)
-
initUI()
-
}
override fun onStop() {
@@ -59,32 +57,27 @@ class ImportActivity : PokerAnalyticsActivity() {
val fragmentTransaction = supportFragmentManager.beginTransaction()
val fragment = ImportFragment()
- val filePath = intent.getStringExtra(ImportActivity.IntentKey.FILE_PATH.keyName)
- fragment.setData(filePath)
+ val fis = contentResolver.openInputStream(fileURI)
+ Timber.d("Load fragment data with: $fis")
+ fis?.let {
+ fragment.setData(it)
+ }
fragmentTransaction.add(R.id.container, fragment)
fragmentTransaction.commit()
- }
- private fun requestPermission() {
- if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
- ActivityCompat.requestPermissions(
- this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), PERMISSION_REQUEST_ACCESS_FINE_LOCATION
- )
- }
}
- override fun onNewIntent(intent: Intent?) {
- super.onNewIntent(intent)
-
- val f = intent?.data
- val uri = f.toString()
- Timber.d("!!!Intent!!! uri = $uri")
-
- }
-
- override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults)
- }
+// private fun requestPermission() {
+// if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
+// ActivityCompat.requestPermissions(
+// this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), PERMISSION_REQUEST_ACCESS_FINE_LOCATION
+// )
+// }
+// }
+//
+// override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+// super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+// }
}
\ No newline at end of file
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt
index fc084b97..177cd9e9 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt
@@ -12,6 +12,7 @@ import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.util.csv.CSVImporter
import timber.log.Timber
+import java.io.InputStream
import java.util.*
import kotlin.coroutines.CoroutineContext
@@ -21,11 +22,17 @@ class ImportFragment : RealmFragment() {
get() = Dispatchers.Main
private lateinit var filePath: String
+ private lateinit var inputStream: InputStream
fun setData(path: String) {
this.filePath = path
}
+ fun setData(inputStream: InputStream) {
+ Timber.d("> setData with IS...")
+ this.inputStream = inputStream
+ }
+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_import, container, false)
@@ -33,6 +40,8 @@ class ImportFragment : RealmFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+
+ Timber.d("> onViewCreated...")
this.startImport()
}
@@ -42,9 +51,9 @@ class ImportFragment : RealmFragment() {
val test = GlobalScope.async {
val s = Date()
- Timber.d(">>> start...")
+ Timber.d(">>> Start Import...")
- val csv = CSVImporter(filePath)
+ val csv = CSVImporter(inputStream)
csv.start()
val e = Date()
diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt
index 686671d8..aeb41345 100644
--- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt
+++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/data/DataManagerFragment.kt
@@ -95,7 +95,7 @@ open class DataManagerFragment : RealmFragment() {
this.getRealm().executeTransaction {
val managedItem = it.copyToRealmOrUpdate(this.item)
if (managedItem is Savable) {
- val uniqueIdentifier = (managedItem as Savable).id
+ val uniqueIdentifier = managedItem.id
finishActivityWithResult(uniqueIdentifier)
}
}
diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt
index ef18a235..b988a824 100644
--- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt
+++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt
@@ -5,8 +5,24 @@ import org.apache.commons.csv.CSVFormat
import org.apache.commons.csv.CSVRecord
import timber.log.Timber
import java.io.FileReader
+import java.io.InputStream
+import java.io.InputStreamReader
+import java.io.Reader
-open class CSVImporter(var path: String) {
+open class CSVImporter {
+
+ private val COMMIT_FREQUENCY = 100
+
+ var path: String? = null
+ var inputStream: InputStream? = null
+
+ constructor(istream: InputStream) {
+ inputStream = istream
+ }
+
+ constructor(filePath: String) {
+ path = filePath
+ }
private var usedDescriptors: MutableList = mutableListOf()
private var currentDescriptor: CSVDescriptor? = null
@@ -15,40 +31,52 @@ open class CSVImporter(var path: String) {
val realm = Realm.getDefaultInstance()
- val reader = FileReader(this.path)
+ var reader: Reader? = null
+ if (this.path != null) {
+ reader = FileReader(this.path)
+ }
+ if (this.inputStream != null) {
+ reader = InputStreamReader(this.inputStream)
+ }
val parser = CSVFormat.DEFAULT.withAllowMissingColumnNames().parse(reader)
Timber.d("Starting import...")
- realm.executeTransaction {
+ realm.beginTransaction()
- parser.forEachIndexed { index, record ->
+ parser.forEachIndexed { index, record ->
- Timber.d("line $index")
+ Timber.d("line $index")
- if (currentDescriptor == null) { // find descriptor
- this.findDescriptor(record)
- } else {
+ if (currentDescriptor == null) { // find descriptor
+ this.findDescriptor(record)
+ } else {
- currentDescriptor?.let {
- if (record.size() == 0) {
- this.usedDescriptors.add(it)
- this.currentDescriptor = null // reset descriptor when encountering an empty line (multiple descriptors can be found in a single file)
- } else {
- it.parse(realm, record)
- }
- } ?: run {
- throw IllegalStateException("CSVDescriptor should never be null here")
- }
+ if ((index + 1) % COMMIT_FREQUENCY == 0) {
+ Timber.d("****** committing at ${index} sessions...")
+ realm.commitTransaction()
+ realm.beginTransaction()
+ }
+ currentDescriptor?.let {
+ if (record.size() == 0) {
+ this.usedDescriptors.add(it)
+ this.currentDescriptor =
+ null // reset descriptor when encountering an empty line (multiple descriptors can be found in a single file)
+ } else {
+ it.parse(realm, record)
+ }
+ } ?: run {
+ throw IllegalStateException("CSVDescriptor should never be null here")
}
+
}
}
- Timber.d("Ending import...")
+ realm.commitTransaction()
-// this.save(realm)
+ Timber.d("Ending import...")
realm.close()
}
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 372267b6..e6436138 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -379,7 +379,7 @@
Vérifiez que la transaction possède un type et un montant
Il faut choisir un nom!
Types de transactions
- Transaction
+ Transactions
Autres
Choisissez un code PIN pour\n protéger l\'accès à l\'application.\nUn code PIN ne peut pas être retrouvé.\nSoyez attentif lors de l\'activation\n de cette fonction.
Code PIN
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2daa133f..8e860c65 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -31,6 +31,7 @@
Launch Report
Progress
Save Report
+ Do you want to proceed with the file import?
Update %s
Comparison chart
The filter cannot be deleted because it is currently selected.