Request write permission when downloading circulars

This commit is contained in:
2019-09-21 18:47:08 +02:00
committed by Matte23
parent a45eea1fde
commit d00ce9b51f
6 changed files with 110 additions and 14 deletions

View File

@@ -18,9 +18,13 @@
package net.underdesk.circolapp package net.underdesk.circolapp
import android.app.DownloadManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
@@ -30,9 +34,19 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_main.*
import net.underdesk.circolapp.adapters.CircularLetterAdapter
import net.underdesk.circolapp.data.Circular
import net.underdesk.circolapp.works.PollWork import net.underdesk.circolapp.works.PollWork
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity(), CircularLetterAdapter.AdapterCallback {
companion object {
internal const val PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 10
}
override var circularToDownload: Circular? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -80,6 +94,44 @@ class MainActivity : AppCompatActivity() {
} }
} }
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>, grantResults: IntArray
) {
when (requestCode) {
PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE -> {
// If request is cancelled, the result arrays are empty.
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
downloadCircular()
} else {
Snackbar.make(
container,
resources.getString(R.string.snackbar_write_permission_not_granted),
Snackbar.LENGTH_LONG
).show()
}
return
}
}
}
override fun downloadCircular() {
val request = DownloadManager.Request(Uri.parse(circularToDownload!!.url))
request.setTitle(circularToDownload!!.name)
request.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
"Circolapp/" + circularToDownload!!.id + ".pdf"
)
(getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager).enqueue(request)
Snackbar.make(
container,
resources.getString(R.string.snackbar_circular_downloaded),
Snackbar.LENGTH_LONG
).show()
}
private fun showInfoDialog() { private fun showInfoDialog() {
val builder = AlertDialog.Builder(this) val builder = AlertDialog.Builder(this)
builder.apply { builder.apply {

View File

@@ -18,29 +18,37 @@
package net.underdesk.circolapp.adapters package net.underdesk.circolapp.adapters
import android.app.DownloadManager import android.Manifest
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.Environment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_circular.view.* import kotlinx.android.synthetic.main.item_circular.view.*
import net.underdesk.circolapp.AlarmBroadcastReceiver import net.underdesk.circolapp.AlarmBroadcastReceiver
import net.underdesk.circolapp.MainActivity
import net.underdesk.circolapp.R import net.underdesk.circolapp.R
import net.underdesk.circolapp.data.AppDatabase import net.underdesk.circolapp.data.AppDatabase
import net.underdesk.circolapp.data.Circular import net.underdesk.circolapp.data.Circular
import net.underdesk.circolapp.fragments.NewReminderFragment import net.underdesk.circolapp.fragments.NewReminderFragment
class CircularLetterAdapter(private val circulars: List<Circular>) : class CircularLetterAdapter(
private val circulars: List<Circular>,
private val adapterCallback: AdapterCallback
) :
RecyclerView.Adapter<CircularLetterAdapter.CircularLetterViewHolder>() { RecyclerView.Adapter<CircularLetterAdapter.CircularLetterViewHolder>() {
private lateinit var context: Context private lateinit var context: Context
private var collapsedItems = -1 private var collapsedItems = -1
@@ -108,14 +116,36 @@ class CircularLetterAdapter(private val circulars: List<Circular>) :
} }
holder.downloadButton.setOnClickListener { holder.downloadButton.setOnClickListener {
val request = DownloadManager.Request(Uri.parse(circulars[position].url)) adapterCallback.circularToDownload = circulars[position]
request.setTitle(circulars[position].name)
request.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
"Circolapp/" + circulars[position].id + ".pdf"
)
(context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager).enqueue(request) if (ContextCompat.checkSelfPermission(
context,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
!= PackageManager.PERMISSION_GRANTED
) {
val builder: AlertDialog.Builder? = AlertDialog.Builder(context)
builder?.apply {
setMessage(context.getString(R.string.dialog_message_permission_write))
setTitle(context.getString(R.string.dialog_title_permission_required))
setPositiveButton(
context.getString(R.string.dialog_next)
) { _, _ ->
ActivityCompat.requestPermissions(
adapterCallback as AppCompatActivity,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
MainActivity.PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE
)
}
}
builder?.create()?.show()
} else {
adapterCallback.downloadCircular()
}
} }
holder.favouriteButton.setOnClickListener { holder.favouriteButton.setOnClickListener {
@@ -163,4 +193,9 @@ class CircularLetterAdapter(private val circulars: List<Circular>) :
} }
override fun getItemCount() = circulars.size override fun getItemCount() = circulars.size
interface AdapterCallback {
var circularToDownload: Circular?
fun downloadCircular()
}
} }

View File

@@ -29,6 +29,7 @@ import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.fragment_circular_letters.view.* import kotlinx.android.synthetic.main.fragment_circular_letters.view.*
import net.underdesk.circolapp.MainActivity
import net.underdesk.circolapp.R import net.underdesk.circolapp.R
import net.underdesk.circolapp.adapters.CircularLetterAdapter import net.underdesk.circolapp.adapters.CircularLetterAdapter
import net.underdesk.circolapp.viewmodels.CircularLetterViewModel import net.underdesk.circolapp.viewmodels.CircularLetterViewModel
@@ -49,7 +50,7 @@ class CircularLetterFragment : Fragment() {
circularLetterViewModel = circularLetterViewModel =
ViewModelProviders.of(this).get(CircularLetterViewModel::class.java) ViewModelProviders.of(this).get(CircularLetterViewModel::class.java)
circularLetterViewModel.circulars.observe(this, Observer { circularLetterViewModel.circulars.observe(this, Observer {
root.circulars_list.adapter = CircularLetterAdapter(it) root.circulars_list.adapter = CircularLetterAdapter(it, activity as MainActivity)
}) })
circularLetterViewModel.showMessage.observe(this, Observer { circularLetterViewModel.showMessage.observe(this, Observer {
if (it) activity?.findViewById<ConstraintLayout>(R.id.container)?.let { view -> if (it) activity?.findViewById<ConstraintLayout>(R.id.container)?.let { view ->

View File

@@ -27,6 +27,7 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_circular_letters.view.* import kotlinx.android.synthetic.main.fragment_circular_letters.view.*
import net.underdesk.circolapp.MainActivity
import net.underdesk.circolapp.R import net.underdesk.circolapp.R
import net.underdesk.circolapp.adapters.CircularLetterAdapter import net.underdesk.circolapp.adapters.CircularLetterAdapter
import net.underdesk.circolapp.viewmodels.FavouritesViewModel import net.underdesk.circolapp.viewmodels.FavouritesViewModel
@@ -47,7 +48,7 @@ class FavouritesFragment : Fragment() {
favouritesViewModel = favouritesViewModel =
ViewModelProviders.of(this).get(FavouritesViewModel::class.java) ViewModelProviders.of(this).get(FavouritesViewModel::class.java)
favouritesViewModel.circulars.observe(this, Observer { favouritesViewModel.circulars.observe(this, Observer {
root.circulars_list.adapter = CircularLetterAdapter(it) root.circulars_list.adapter = CircularLetterAdapter(it, activity as MainActivity)
}) })
return root return root
} }

View File

@@ -27,6 +27,7 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_circular_letters.view.* import kotlinx.android.synthetic.main.fragment_circular_letters.view.*
import net.underdesk.circolapp.MainActivity
import net.underdesk.circolapp.R import net.underdesk.circolapp.R
import net.underdesk.circolapp.adapters.CircularLetterAdapter import net.underdesk.circolapp.adapters.CircularLetterAdapter
import net.underdesk.circolapp.viewmodels.RemindersViewModel import net.underdesk.circolapp.viewmodels.RemindersViewModel
@@ -47,7 +48,7 @@ class RemindersFragment : Fragment() {
remindersViewModel = remindersViewModel =
ViewModelProviders.of(this).get(RemindersViewModel::class.java) ViewModelProviders.of(this).get(RemindersViewModel::class.java)
remindersViewModel.circulars.observe(this, Observer { remindersViewModel.circulars.observe(this, Observer {
root.circulars_list.adapter = CircularLetterAdapter(it) root.circulars_list.adapter = CircularLetterAdapter(it, activity as MainActivity)
}) })
return root return root
} }

View File

@@ -32,5 +32,11 @@
© 2019 Matteo Schiff\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it © 2019 Matteo Schiff\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it
under certain conditions.</string> under certain conditions.</string>
<string name="dialog_title_permission_required">Permission required</string>
<string name="dialog_message_permission_write">We need your permission to save this circular letter to local storage</string>
<string name="snackbar_write_permission_not_granted">Unable to save this circular letter to local storage. Permission not granted</string>
<string name="snackbar_circular_downloaded">The circular letter will be saved into the download folder</string>
<string name="snackbar_connection_not_available">Network not available. Results may be outdated</string> <string name="snackbar_connection_not_available">Network not available. Results may be outdated</string>
</resources> </resources>