Implement freedom build flavors
This is a necessary step in separating the proprietary code (like Google Play Billing) from the FLOSS code so that I can eventually get around to publishing the app on fdroid Signed-off-by: William Brawner <me@wbrawner.com>
This commit is contained in:
parent
c3821fbfc9
commit
9a0685a165
4 changed files with 139 additions and 66 deletions
|
@ -68,6 +68,14 @@ android {
|
|||
buildConfigField "boolean", "ENABLE_CUSTOM_CSS", "false"
|
||||
}
|
||||
}
|
||||
flavorDimensions "freedom"
|
||||
productFlavors {
|
||||
play {}
|
||||
free {
|
||||
applicationIdSuffix ".free"
|
||||
versionNameSuffix "-free"
|
||||
}
|
||||
}
|
||||
dexOptions {
|
||||
jumboMode true
|
||||
}
|
||||
|
@ -100,8 +108,8 @@ dependencies {
|
|||
implementation 'com.google.android.material:material:1.1.0'
|
||||
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
|
||||
implementation 'com.commonsware.cwac:anddown:0.3.0'
|
||||
implementation 'com.android.billingclient:billing:3.0.0'
|
||||
implementation 'com.google.firebase:firebase-core:17.4.3'
|
||||
playImplementation 'com.android.billingclient:billing:3.0.0'
|
||||
playImplementation 'com.google.firebase:firebase-core:17.4.3'
|
||||
implementation "androidx.core:core-ktx:1.3.0"
|
||||
implementation 'androidx.browser:browser:1.2.0'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
@ -116,7 +124,13 @@ dependencies {
|
|||
implementation 'eu.crydee:syllable-counter:4.0.2'
|
||||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
android.productFlavors.each { flavor ->
|
||||
if (getGradle().getStartParameter().getTaskRequests().toString().toLowerCase().contains(flavor.name)
|
||||
&& flavor.name == 'play') {
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package com.wbrawner.simplemarkdown.utility
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.google.android.material.button.MaterialButton
|
||||
|
||||
class SupportLinkProvider(@Suppress("unused") private val activity: Activity) {
|
||||
val supportLinks = MutableLiveData<List<MaterialButton>>()
|
||||
}
|
|
@ -6,18 +6,15 @@ import android.net.Uri
|
|||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import com.android.billingclient.api.*
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import androidx.lifecycle.Observer
|
||||
import com.wbrawner.simplemarkdown.R
|
||||
import com.wbrawner.simplemarkdown.utility.SupportLinkProvider
|
||||
import kotlinx.android.synthetic.main.activity_support.*
|
||||
|
||||
|
||||
class SupportActivity : AppCompatActivity(), BillingClientStateListener, PurchasesUpdatedListener {
|
||||
private lateinit var billingClient: BillingClient
|
||||
|
||||
class SupportActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_support)
|
||||
|
@ -31,11 +28,6 @@ class SupportActivity : AppCompatActivity(), BillingClientStateListener, Purchas
|
|||
}
|
||||
setTitle(R.string.support_title)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
billingClient = BillingClient.newBuilder(applicationContext)
|
||||
.setListener(this)
|
||||
.enablePendingPurchases()
|
||||
.build()
|
||||
billingClient.startConnection(this)
|
||||
githubButton.setOnClickListener {
|
||||
CustomTabsIntent.Builder()
|
||||
.addDefaultShareMenuItem()
|
||||
|
@ -57,6 +49,11 @@ class SupportActivity : AppCompatActivity(), BillingClientStateListener, Purchas
|
|||
startActivity(playStoreIntent)
|
||||
}
|
||||
}
|
||||
SupportLinkProvider(this).supportLinks.observe(this, Observer { links ->
|
||||
links.forEach {
|
||||
supportButtons.addView(it)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
@ -66,56 +63,4 @@ class SupportActivity : AppCompatActivity(), BillingClientStateListener, Purchas
|
|||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onBillingSetupFinished(result: BillingResult) {
|
||||
if (result.responseCode != BillingClient.BillingResponseCode.OK) {
|
||||
return
|
||||
}
|
||||
|
||||
val skuDetails = SkuDetailsParams.newBuilder()
|
||||
.setSkusList(listOf("support_the_developer", "tip_coffee", "tip_beer"))
|
||||
.setType(BillingClient.SkuType.INAPP)
|
||||
.build()
|
||||
billingClient.querySkuDetailsAsync(skuDetails) { skuDetailsResponse, skuDetailsList ->
|
||||
// Process the result.
|
||||
if (skuDetailsResponse.responseCode != BillingClient.BillingResponseCode.OK || skuDetailsList.isNullOrEmpty()) {
|
||||
return@querySkuDetailsAsync
|
||||
}
|
||||
|
||||
skuDetailsList.sortedBy { it.priceAmountMicros }.forEach { skuDetails ->
|
||||
val supportButton = MaterialButton(this@SupportActivity)
|
||||
supportButton.text = getString(
|
||||
R.string.support_button_purchase,
|
||||
skuDetails.title,
|
||||
skuDetails.price
|
||||
)
|
||||
supportButton.setOnClickListener {
|
||||
val flowParams = BillingFlowParams.newBuilder()
|
||||
.setSkuDetails(skuDetails)
|
||||
.build()
|
||||
billingClient.launchBillingFlow(this, flowParams)
|
||||
}
|
||||
supportButtons.addView(supportButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBillingServiceDisconnected() {
|
||||
billingClient.startConnection(this)
|
||||
}
|
||||
|
||||
override fun onPurchasesUpdated(result: BillingResult, purchases: MutableList<Purchase>?) {
|
||||
purchases?.forEach { purchase ->
|
||||
val consumeParams = ConsumeParams.newBuilder()
|
||||
.setPurchaseToken(purchase.purchaseToken)
|
||||
.build()
|
||||
billingClient.consumeAsync(consumeParams) { _, _ ->
|
||||
Toast.makeText(
|
||||
this@SupportActivity,
|
||||
getString(R.string.support_thank_you),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
package com.wbrawner.simplemarkdown.utility
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.android.billingclient.api.*
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.wbrawner.simplemarkdown.R
|
||||
|
||||
class SupportLinkProvider(private val activity: Activity) : BillingClientStateListener,
|
||||
PurchasesUpdatedListener {
|
||||
val supportLinks = MutableLiveData<List<MaterialButton>>()
|
||||
|
||||
private val billingClient: BillingClient = BillingClient.newBuilder(activity.applicationContext)
|
||||
.setListener(this)
|
||||
.enablePendingPurchases()
|
||||
.build()
|
||||
|
||||
init {
|
||||
billingClient.startConnection(this)
|
||||
activity.application.registerActivityLifecycleCallbacks(
|
||||
object : Application.ActivityLifecycleCallbacks {
|
||||
override fun onActivityPaused(activity: Activity) {
|
||||
}
|
||||
|
||||
override fun onActivityStarted(activity: Activity) {
|
||||
}
|
||||
|
||||
override fun onActivityDestroyed(activity: Activity) {
|
||||
billingClient.endConnection()
|
||||
}
|
||||
|
||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
|
||||
}
|
||||
|
||||
override fun onActivityStopped(activity: Activity) {
|
||||
}
|
||||
|
||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
||||
}
|
||||
|
||||
override fun onActivityResumed(activity: Activity) {
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onBillingSetupFinished(result: BillingResult) {
|
||||
if (result.responseCode != BillingClient.BillingResponseCode.OK) {
|
||||
return
|
||||
}
|
||||
|
||||
val skuDetails = SkuDetailsParams.newBuilder()
|
||||
.setSkusList(listOf("support_the_developer", "tip_coffee", "tip_beer"))
|
||||
.setType(BillingClient.SkuType.INAPP)
|
||||
.build()
|
||||
billingClient.querySkuDetailsAsync(skuDetails) { skuDetailsResponse, skuDetailsList ->
|
||||
// Process the result.
|
||||
if (skuDetailsResponse.responseCode != BillingClient.BillingResponseCode.OK || skuDetailsList.isNullOrEmpty()) {
|
||||
return@querySkuDetailsAsync
|
||||
}
|
||||
|
||||
skuDetailsList.sortedBy { it.priceAmountMicros }
|
||||
.map { skuDetails ->
|
||||
val supportButton = MaterialButton(activity)
|
||||
supportButton.text = activity.getString(
|
||||
R.string.support_button_purchase,
|
||||
skuDetails.title,
|
||||
skuDetails.price
|
||||
)
|
||||
supportButton.setOnClickListener {
|
||||
val flowParams = BillingFlowParams.newBuilder()
|
||||
.setSkuDetails(skuDetails)
|
||||
.build()
|
||||
billingClient.launchBillingFlow(activity, flowParams)
|
||||
}
|
||||
supportButton
|
||||
}
|
||||
.let {
|
||||
supportLinks.postValue(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBillingServiceDisconnected() {
|
||||
billingClient.startConnection(this)
|
||||
}
|
||||
|
||||
override fun onPurchasesUpdated(result: BillingResult, purchases: MutableList<Purchase>?) {
|
||||
purchases?.forEach { purchase ->
|
||||
val consumeParams = ConsumeParams.newBuilder()
|
||||
.setPurchaseToken(purchase.purchaseToken)
|
||||
.build()
|
||||
billingClient.consumeAsync(consumeParams) { _, _ ->
|
||||
Toast.makeText(
|
||||
activity,
|
||||
activity.getString(R.string.support_thank_you),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue