Skip to content

Commit

Permalink
all: on the fly location sharing requests (fixes #1875) (#1987)
Browse files Browse the repository at this point in the history
Co-authored-by: yibo <[email protected]>
Co-authored-by: dogi <[email protected]>
  • Loading branch information
3 people authored May 9, 2024
1 parent 7e41121 commit 635671e
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 61 deletions.
20 changes: 10 additions & 10 deletions .github/workflows/android-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@ jobs:
sha256sum output/remote.aab > output/remote.aab.sha256
ls -alR output
# - name: publish AAB to playstore
# if: github.ref == 'refs/heads/master'
# uses: dogi/[email protected]
# with:
# serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
# packageName: io.treehouses.remote
# releaseFiles: output/remote.aab
# track: internal
# releaseName: "${{ env.VERSION }}"
# status: completed
- name: publish AAB to playstore
if: github.ref == 'refs/heads/master'
uses: dogi/[email protected]
with:
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
packageName: io.treehouses.remote
releaseFiles: output/remote.aab
track: internal
releaseName: "${{ env.VERSION }}"
status: completed

# - name: mobile security framework
# run: |
Expand Down
63 changes: 49 additions & 14 deletions app/src/main/kotlin/io/treehouses/remote/InitialActivity.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.treehouses.remote

import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
Expand All @@ -10,7 +11,10 @@ import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.preference.PreferenceManager
Expand Down Expand Up @@ -136,10 +140,15 @@ class InitialActivity : BaseInitialActivity() {

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == 99) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this@InitialActivity, "Permissions Granted", Toast.LENGTH_SHORT).show()
} //TODO re-request
when (requestCode) {
REQUEST_LOCATION_PERMISSION_FOR_COMMUNITY -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
preferences?.edit()?.putBoolean("send_log", true)?.apply()
goToCommunity()
} else {
Toast.makeText(this, "Permission denied. Cannot proceed to community features.", Toast.LENGTH_SHORT).show()
}
}
}
}

Expand Down Expand Up @@ -167,27 +176,49 @@ class InitialActivity : BaseInitialActivity() {
FeedbackDialogFragment().show(supportFragmentManager.beginTransaction(), "feedbackDialogFragment")
}
R.id.action_community -> {
preferences = PreferenceManager.getDefaultSharedPreferences(this)
val v = layoutInflater.inflate(R.layout.alert_log_map, null)
if (!preferences?.getBoolean("send_log", false)!!) {
val builder = DialogUtils.createAlertDialog(this@InitialActivity, "Sharing is Caring.", "The community map is only available with data sharing. " +
"Please enable data sharing to access this feature.", v).setCancelable(false)
DialogUtils.createAdvancedDialog(builder, Pair("Enable Data Sharing", "Cancel"), {
preferences!!.edit().putBoolean("send_log", true).apply()
goToCommunity()
}, {MainApplication.showLogDialog = false })
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
dataSharing()
} else {
preferences?.edit()?.putBoolean("send_log", true)?.apply()
goToCommunity()
}
else { goToCommunity() }
}
}
return super.onOptionsItemSelected(item)
}

fun dataSharing() {
preferences = PreferenceManager.getDefaultSharedPreferences(this)
val v = layoutInflater.inflate(R.layout.alert_log_map, null)
if (preferences?.getBoolean("send_log", false) == false) {
val builder = DialogUtils.createAlertDialog(this@InitialActivity,
"Sharing is Caring",
"To enable the community map, Treehouses needs to collect some data and your approximate location. Would you like to enable data sharing?", v)
.setCancelable(false)
DialogUtils.createAdvancedDialog(builder, Pair("Enable Data Sharing", "Cancel"), {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), REQUEST_LOCATION_PERMISSION_FOR_COMMUNITY)
}, {MainApplication.showLogDialog = false })
} else {
goToCommunity()
}
}

private fun goToCommunity() {
openCallFragment(CommunityFragment())
title = getString(R.string.action_community)
}

private fun showLocationPermissionDisclosureForCommunity() {
AlertDialog.Builder(this)
.setTitle("Location & GPS Usage")
.setMessage("This app collects location data to create a community map and understand user distribution. " +
"This helps us improve our services. To continue, please enable GPS.")
.setPositiveButton("Ok") { _, _ ->
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), REQUEST_LOCATION_PERMISSION_FOR_COMMUNITY)
}
.setNegativeButton("No", null).show()
}

fun changeAppBar() {
mActionBarDrawerToggle = ActionBarDrawerToggle(this, bind.drawerLayout, findViewById(R.id.toolbar), 0, 0)
mActionBarDrawerToggle.toolbarNavigationClickListener = View.OnClickListener {
Expand All @@ -208,4 +239,8 @@ class InitialActivity : BaseInitialActivity() {
mActionBarDrawerToggle.isDrawerIndicatorEnabled = true
bind.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
}

companion object {
private const val REQUEST_LOCATION_PERMISSION_FOR_COMMUNITY = 2
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ abstract class PermissionActivity : AppCompatActivity() {
}

fun requestPermission() {
proceedWithoutLocationPermission()
}

private fun proceedWithLocationPermission() {
val permissionsToRequest = mutableListOf(
Manifest.permission.CHANGE_WIFI_STATE, Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.BLUETOOTH,
Expand All @@ -56,11 +60,29 @@ abstract class PermissionActivity : AppCompatActivity() {
}
}

private fun proceedWithoutLocationPermission() {
val permissionsToRequest = mutableListOf(
Manifest.permission.CHANGE_WIFI_STATE, Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.BLUETOOTH_SCAN
)

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU && !checkPermission(Manifest.permission.POST_NOTIFICATIONS)) {
permissionsToRequest.add(Manifest.permission.POST_NOTIFICATIONS)
}

if (permissionsToRequest.any { !checkPermission(it) }) {
ActivityCompat.requestPermissions(this, permissionsToRequest.toTypedArray(), PERMISSION_REQUEST_WIFI)
}
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQUEST_WIFI) {
if (grantResults.isNotEmpty() && grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
statusCheck()
if (checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
statusCheck()
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
package io.treehouses.remote.fragments

import android.Manifest
import android.content.Context
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import io.treehouses.remote.fragments.preferencefragments.GeneralPreferenceFragment
import io.treehouses.remote.fragments.preferencefragments.UserCustomizationPreferenceFragment
import androidx.preference.PreferenceManager
import androidx.preference.SwitchPreferenceCompat
import io.treehouses.remote.MainApplication
import io.treehouses.remote.R
import io.treehouses.remote.callback.HomeInteractListener
import io.treehouses.remote.fragments.preferencefragments.GeneralPreferenceFragment
import io.treehouses.remote.fragments.preferencefragments.UserCustomizationPreferenceFragment
import io.treehouses.remote.utils.DialogUtils
import io.treehouses.remote.utils.SettingsUtils

class SettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceClickListener {
class SettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
private var preferenceChangeListener: OnSharedPreferenceChangeListener? = null
private lateinit var listener : HomeInteractListener
private lateinit var preferences: SharedPreferences

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.app_preferences, rootKey)
val general = findPreference<Preference>("general")
Expand All @@ -25,12 +36,16 @@ class SettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceClic
SettingsUtils.setClickListener(this, showBluetoothFile)
SettingsUtils.setClickListener(this, general)
SettingsUtils.setClickListener(this, usercustomization)

val sendLogPreference = findPreference<SwitchPreferenceCompat>("send_log")
sendLogPreference?.onPreferenceChangeListener = this
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.windowBackground))
setDivider(null)
preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
}

override fun onResume() {
Expand Down Expand Up @@ -68,4 +83,58 @@ class SettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceClic
listener = if (context is HomeInteractListener) context
else throw Exception("Context does not implement HomeInteractListener")
}
}

override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
if (preference.key == "send_log") {
val value = newValue as? Boolean ?: false
if (value) {
dataSharing()
} else {
preferences.edit()?.putBoolean("send_log", false)?.apply()
}
(preference as? SwitchPreferenceCompat)?.isChecked = preferences.getBoolean("send_log", false)
}
return true
}


fun dataSharing() {
val v = layoutInflater.inflate(R.layout.alert_log, null)
val emoji = String(Character.toChars(0x1F60A))
val builder = DialogUtils.createAlertDialog(activity,
"Sharing is Caring $emoji",
"To make Treehouses better, we'd like to collect some data and your approximate location. Would you like to enable data sharing?", v)
.setCancelable(false)
DialogUtils.createAdvancedDialog(builder, Pair("Enable Data Sharing", "Cancel"), {
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION),
REQUEST_LOCATION_PERMISSION_FOR_ACTIVITY_COLLECTION
)
} else {
preferences.edit()?.putBoolean("send_log", true)?.apply()
}
}, {
val sendLogPreference = findPreference<SwitchPreferenceCompat>("send_log")
sendLogPreference?.isChecked = false
preferences.edit()?.putBoolean("send_log", false)?.apply()
MainApplication.showLogDialog = false
})
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
REQUEST_LOCATION_PERMISSION_FOR_ACTIVITY_COLLECTION -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
preferences.edit()?.putBoolean("send_log", true)?.apply()
} else {
Toast.makeText(context, "Permission denied. We won't collect your activities", Toast.LENGTH_SHORT).show()
}
}
}
}

companion object {
private const val REQUEST_LOCATION_PERMISSION_FOR_ACTIVITY_COLLECTION = 2
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package io.treehouses.remote.ui.home

import android.Manifest
import android.app.AlertDialog
import android.content.ActivityNotFoundException
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.graphics.drawable.AnimationDrawable
import android.net.Uri
import android.view.View
import android.widget.ImageView
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import androidx.preference.PreferenceManager
import io.treehouses.remote.InitialActivity
import io.treehouses.remote.IntroActivity
import io.treehouses.remote.MainApplication
import io.treehouses.remote.R
Expand Down Expand Up @@ -81,9 +86,32 @@ open class BaseHomeFragment : BaseFragment() {
if (lastDialogShown < date.timeInMillis && !preferences.getBoolean("send_log", false)) {
if (connectionCount >= 3) {
preferences.edit().putLong("last_dialog_shown", Calendar.getInstance().timeInMillis).apply()
val builder = DialogUtils.createAlertDialog(activity, "Sharing is Caring $emoji", "Treehouses wants to collect your activities. " +
"Do you like to share it? It will help us to improve.", v).setCancelable(false)
DialogUtils.createAdvancedDialog(builder, Pair("Continue", "Cancel"), { preferences.edit().putBoolean("send_log", true).apply() }, { MainApplication.showLogDialog = false })
val builder = DialogUtils.createAlertDialog(activity,
"Sharing is Caring $emoji",
"Treehouses wants to collect your activities. Do you like to share it? It will help us to improve.", v)
.setCancelable(false)
DialogUtils.createAdvancedDialog(builder, Pair("Continue", "Cancel"), {
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION),
REQUEST_LOCATION_PERMISSION_FOR_ACTIVITY_COLLECTION
)
} else {
preferences.edit()?.putBoolean("send_log", true)?.apply()
}
}, { MainApplication.showLogDialog = false })
}
}
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
REQUEST_LOCATION_PERMISSION_FOR_ACTIVITY_COLLECTION -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
preferences?.edit()?.putBoolean("send_log", true)?.apply()
} else {
Toast.makeText(context, "Permission denied. We won't collect your activities", Toast.LENGTH_SHORT).show()
}
}
}
}
Expand Down Expand Up @@ -271,4 +299,8 @@ open class BaseHomeFragment : BaseFragment() {
alertDialog.window!!.setBackgroundDrawableResource(android.R.color.transparent)
alertDialog.show()
}

companion object {
private const val REQUEST_LOCATION_PERMISSION_FOR_ACTIVITY_COLLECTION = 2
}
}
Loading

0 comments on commit 635671e

Please sign in to comment.