How do you encompass a try/catch block in these functions? - android

I get a NumberFormatException if an entry field is left blank in the app. Previously, I had a working try/catch block that would handle it but I needed to add a switch on if/else statement to determine which function to run. I've tried everything I can think of to reformat the try/catch so that error is being handled, but everything just breaks the application. What am I doing wrong here, or is it even possible to do?
package com.WordPlay.awcc
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class Setup3 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main
)
editTextNumber2.text.toString().toInt()
editTextNumber3.text.toString().toInt()
editTextNumber4.text.toString().toInt()
editTextNumber5.text.toString().toInt()
editTextNumber6.text.toString().toInt()
editTextNumber15.text.toString().toInt()
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/// Define button for checked
fun essentialexpert() {
val int11 = editTextNumber.text.toString().toInt()
val pay21 = 5
val product11 = int11 * pay21
val int12 = editTextNumber2.text.toString().toInt()
val pay22 = 12.5
val product12 = int12 * pay22
val int13 = editTextNumber3.text.toString().toInt()
val pay23 = 15
val product13 = int13 * pay23
val int16 = editTextNumber6.text.toString().toInt()
val pay24 = 5
val product14 = int16 * pay24
val int15 = editTextNumber5.text.toString().toInt()
val pay25 = 5
val product15 = int15 * pay25
val int14 = editTextNumber4.text.toString().toInt()
val pay26 = 2
val product16 = int14 / pay26
val final =
product11 + product12 + product13 + product14 + product15 + product16
val complete = final.toString()
try {
editTextNumber15?.setText(complete)
} catch (e: NumberFormatException) {
Toast.makeText(
applicationContext,
"Please enter a 0 in the blank field",
Toast.LENGTH_LONG
).show()
}
}
/// Define function for unchecked
fun essential() {
val int1 = editTextNumber.text.toString().toInt()
val pay1 = 5
val product1 = int1 * pay1
val int2 = editTextNumber2.text.toString().toInt()
val pay2 = 7.5
val product2 = int2 * pay2
val int3 = editTextNumber3.text.toString().toInt()
val pay3 = 10
val product3 = int3 * pay3
val int6 = editTextNumber6.text.toString().toInt()
val pay4 = 5
val product4 = int6 * pay4
val int5 = editTextNumber5.text.toString().toInt()
val pay5 = 0
val product5 = int5 * pay5
val int4 = editTextNumber4.text.toString().toInt()
val pay6 = 2
val product6 = int4 / pay6
val final = product1 + product2 + product3 + product4 + product5 + product6
val complete = final.toString()
try {
editTextNumber15?.setText(complete)
} catch (e: NumberFormatException) {
Toast.makeText(
applicationContext,
"Please enter a 0 in the blank field",
Toast.LENGTH_LONG
).show()
}
}
try {
essential()
} catch (e: java.lang.NumberFormatException) {
Toast.makeText(
applicationContext,
"Please enter a 0 in the blank fields",
Toast.LENGTH_LONG
).show()
/// Define buttons to change activity
val button2 = findViewById<Button>(R.id.button2)
button2.setOnClickListener {
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
}
val button3 = findViewById<Button>(R.id.button3)
button3.setOnClickListener {
val intent2 = Intent(this, ThirdActivity::class.java)
startActivity(intent2)
}
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
if (switch1.isChecked) {
essentialexpert()
} else {
essential()
}
}
}
}
}

You shouldn't catch errors when writing to an EditText, but when reading. Something like that:
fun essentialexpert() {
val int11 = try {
editTextNumber.text.toString().toInt()
} catch (e: NumberFormatException) {
Toast.makeText(
applicationContext,
"Please enter a 0 in the blank field",
Toast.LENGTH_LONG ).show()
return
}
val pay21 = 5
val product11 = int11 * pay21
// ...
// If you reach here, all fields are ok
val final = product11 + /* ... */ + product16
val complete = final.toString()
editTextNumber15?.setText(complete)
}
With Kotlin, you can simplify this try/catch using the toIntOrNull method.
var areAllFieldsValid = false
fun essentialexpert() {
val int11 = editTextNumber.text.toString().toIntOrNull() ?: return
val pay21 = 5
val product11 = int11 * pay21
// ...
// If you reach here, all fields are ok
areAllFieldsValid = true
val final = product11 + /* ... */ + product16
val complete = final.toString()
editTextNumber15?.setText(complete)
}
override fun onCreate(savedInstanceState: Bundle?) {
// ...
btnFinish.setOnClickListener {
essentialexpert()
if (!areAllFieldsValid) {
Toast.makeText(
applicationContext,
"Please enter a 0 in the blank fields",
Toast.LENGTH_LONG).show()
} else {
// Do something when all fields are valid
}
}
}
Some tips for you:
Replace final.toString() with "$final"
Replace Toast.makeText(applicationContext, ... with Toast.makeText(this, .... An Activity is a Context.
I'm not sure what Setup3 is, but if it only exists for getting the EditText values, it won't work. You can do it in MainActivity.
The expression 5/2 may not return what you think it returns.

Related

On Button Click code under Switch Button is not Working

On Button Click, I want to get data on second activity from edit text only if the Switch button is ON but unable to do this anyone can help me to resolve this issue. Thanks
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val nextButton = findViewById<Button>(R.id.nextButton)
nextButton.setOnClickListener {
nextPage()
}
}
private fun nextPage(){
val etName = findViewById<EditText>(R.id.name)
val etEmail = findViewById<EditText>(R.id.email)
val etPhone = findViewById<EditText>(R.id.phone)
val etPassPort = findViewById<CheckBox>(R.id.checkbox)
var passport = ""
if (etPassPort.isChecked) { passport = etPassPort.text.toString() }
val mName = etName.text.toString()
val mEmail = etEmail.text.toString()
val mPhone = etPhone.text.toString()
val intent = Intent(this#MainActivity, ViewActivity::class.java)
intent.putExtra("Name", mName)
intent.putExtra("Email", mEmail)
intent.putExtra("Phone", mPhone)
intent.putExtra("CHECKBOX", passport)
val mySwitch = findViewById<SwitchCompat>(R.id.mySwitch)
mySwitch.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
val et = findViewById<EditText>(R.id.sponsorName)
val mEt = et.text.toString()
intent.putExtra("SPONSOR", mEt)
}
}
startActivity(intent)
}
}
SecondActivity.kt
class ViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view)
val intent = intent
val mName = intent.getStringExtra("Name")
val mEmail = intent.getStringExtra("Email")
val mPhone = intent.getStringExtra("Phone")
val checkbox = intent.getStringExtra("CHECKBOX")
val mEt = intent.getStringExtra("SPONSOR")
//textview
val resultTv = findViewById<View>(R.id.resultTV) as TextView
//setText
resultTv.text = mName+"\n"+mEmail+"\n"+mPhone+"\n"+checkbox+"\n"+mEt
}
}
Switch button code is working fine when i release it from the Button Click. Under the Button Click only null value is showing in Output.
I resolved the issue of Switch Button by declaring it globally here is my working code.
MainActivity.kt
class MainActivity : AppCompatActivity() {
var sponsor : Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mySwitch = findViewById<SwitchCompat>(R.id.mySwitch)
mySwitch.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
sponsor = true
}
}
val nextButton = findViewById<Button>(R.id.nextButton)
nextButton.setOnClickListener {
nextPage()
}
}
private fun nextPage(){
val etName = findViewById<EditText>(R.id.name)
val etEmail = findViewById<EditText>(R.id.email)
val etPhone = findViewById<EditText>(R.id.phone)
val etPassPort = findViewById<CheckBox>(R.id.checkbox)
var passport = ""
if (etPassPort.isChecked) { passport = etPassPort.text.toString() }
val mName = etName.text.toString()
val mEmail = etEmail.text.toString()
val mPhone = etPhone.text.toString()
val intent = Intent(this#MainActivity, ViewActivity::class.java)
val et = findViewById<EditText>(R.id.sponsorName)
val mEt = et.text.toString()
intent.putExtra("SPONSOR", mEt)
intent.putExtra("Name", mName)
intent.putExtra("Email", mEmail)
intent.putExtra("Phone", mPhone)
intent.putExtra("CHECKBOX", passport)
intent.putExtra("Switch",sponsor.toString())
startActivity(intent)}}
SecondActivity.kt
class ViewActivity : AppCompatActivity() {
private lateinit var pdfButton: Button
private var permissionCode = 101
private val STORAGE_CODE: Int = 100
val resultTv = findViewById<View>(R.id.resultTV) as TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view)
val intent = intent
val mName = intent.getStringExtra("Name")
val mEmail = intent.getStringExtra("Email")
val mPhone = intent.getStringExtra("Phone")
val checkbox = intent.getStringExtra("CHECKBOX")
val mEt = intent.getStringExtra("SPONSOR")
val sponsor1 = intent.getStringExtra("Switch")
//textview
//setText
resultTv.text =
mName + "\n" + mEmail + "\n" + mPhone + "\n" + checkbox + "\n" + mEt + "\n" + sponsor1
if (sponsor1 == "true") {
resultTv.text = mName + "\n" + mEmail + "\n" + mPhone + "\n" + checkbox + "\n" + mEt
} else {
resultTv.text = mName + "\n" + mEmail + "\n" + mPhone + "\n" + checkbox
}
I know where is the problem, first of all you call the buttonCLick, and inside it you call the method nextPage(), if we look closely, this block of code
val mySwitch = findViewById<SwitchCompat>(R.id.mySwitch)
mySwitch.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
val et = findViewById<EditText>(R.id.sponsorName)
val mEt = et.text.toString()
intent.putExtra("SPONSOR", mEt)
}
}
is inside your click button, and by default your switch is not checked, so you pass all data, but intent.putExtra("SPONSOR", mEt) is not executed, so when the second activity receive the data is show a null error because val mEt = intent.getStringExtra("SPONSOR") is null.
You have two solution, either you write the block of the switch code outside the click button, or in the second activity you check with a conditionif all your data are not null.

Am I stuck in Kotlin While-Loop?

I was making Count-up Timer.
It works well when I press pause button or stop button, but the app freezes when I press start button.
I suspected that I was stuck in while loop but algorithm doesn't reach the codes before while loop.
What is wrong in my codes?
class MainActivity( var second : Int = 0 , var minute : Int = 0 , var hour : Int = 0 , var ongoing : Boolean = false ) : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initLayout()
}
private fun initLayout(): Unit {
val startButton: Button = findViewById(R.id.startButton)
val pauseButton: Button = findViewById(R.id.pauseButton)
val stopButton: Button = findViewById(R.id.stopButton)
var realTime : TextView = findViewById(R.id.Realtime)
startButton.setOnClickListener {
realTime.text = "0"//doesn't reach here
buttonOn()
countTime(realTime)
}
pauseButton.setOnClickListener {
buttonOff()
countTime(realTime)
}
stopButton.setOnClickListener {
buttonOff()
countTime(realTime)
}
}
private fun buttonOn(): Unit {
this.ongoing = true
}
private fun buttonOff(): Unit {
this.ongoing = false
}
private fun showTime(second: Int, minute: Int, hour: Int): String {
var secondShow: String = if (second < 10) "0$second" else second.toString()
var minuteShow: String = if (minute < 10) "0$minute" else minute.toString()
var hourShow: String = if (hour < 10) "0$hour" else hour.toString()
return "$hourShow:$minuteShow:$secondShow"
}
private fun countTime(textView: TextView): Unit {
var text = 0
textView.text = text.toString()
textView.text = showTime(this.second, this.minute, this.hour)
while (this.ongoing) {
Thread.sleep(1_000)
this.second++
if (this.second == 60) {
this.second = 0
this.minute++
if (this.minute == 60) {
this.minute = 0
this.hour++
}
}
textView.text = showTime(this.second, this.minute, this.hour)
//buttonOff reach here
}
}
}

How do you use a val returned inside a function in a class?

I'm trying to take user input, run it through if statements so the correct math is multiplied, and then output it for a user to see their total. When I end the return statement in my function, it won't let me use the variable the number should be stored in. If I don't end the statement, my code is unreachable.
Any guidance appreciated.
package com.example.awcc
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class Setup: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle ? ) {
super.onCreate(savedInstanceState)
editTextNumber.text.toString().toInt()
}
}
class ThirdActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle ? ) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main3)
val button2 = findViewById < Button > (R.id.button2)
button2.setOnClickListener {
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
}
val button3 = findViewById < Button > (R.id.button3)
button3.setOnClickListener {
val intent2 = Intent(this, MainActivity::class.java)
startActivity(intent2)
val button7 = findViewById < Button > (R.id.button)
button7.setOnClickListener {
fun accessory(): Int {
var value1 = editTextNumber.text.toString().toInt()
if (value1 > 10) {
return value1 * 0
} else if (value1 in 10. .20) {
return value1 * 1
} else if (value1 in 21. .40) {
return value1 * 2
} else if (value1 in 40. .50) {
return value1 * 3
} else if (value1 in 51. .75) {
return value1 * 4
} else if (value1 < 75) {
return value1 * 5
}
return value1
}
val final2 = value1.toString().toInt()
val complete = final2.toString()
try {
editTextNumber7 ? .setText(complete)
} catch (e: NumberFormatException) {
Toast.makeText(
applicationContext,
"Please enter a 0 in the blank field",
Toast.LENGTH_LONG
).show()
accessory()
}
}
}
}
}
You can use when to simplify your code and take the value1 to function outside.
var value1 = editTextNumber.text.toString().toInt()
fun accessory(): Int {
return when {
value1 > 10 -> value1 * 0
value1 in 10..20 -> value1 * 1
value1 in 21..40 -> value1 * 2
value1 in 40..50 -> value1 * 3
value1 in 51..75 -> value1 * 4
value1 < 75 -> value1 * 5
else -> value1
}
}
This won't work. Because you are trying to use the "value1" variable outside the method in which you have declared. You can't use the local variable outside of its scope.
//Existing
val final2 = value1.toString().toInt()
val complete = final2.toString()
try {
editTextNumber7?.setText(complete)
} catch (e: NumberFormatException) {
Toast.makeText(
applicationContext,
"Please enter a 0 in the blank field",
Toast.LENGTH_LONG
).show()
accessory()
}
//Replace with this code
val complete = accessory().toString()
try {
editTextNumber7?.setText(complete)
} catch (e: NumberFormatException) {
Toast.makeText(
applicationContext,
"Please enter a 0 in the blank field",
Toast.LENGTH_LONG
).show()
}

Why "C" != "C"?

Now i am writing my small molar mass calculator and i can't fix one bug. In MainActivity.kt i fill array from my .xml file, after that i use Regex to parse user input. BUT if i type, for example "C" (carbon) in my program it doesn't recognize it. WHY?
MainActivity.kt:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val adapter = MoleculeAdapter(this)
moleculeView.layoutManager = LinearLayoutManager(this)
moleculeView.setHasFixedSize(true)
moleculeView.adapter = adapter
val parser = resources.getXml(R.xml.elements)
val elements = Array(127) { Element() }
thread {
var i = 0
while (parser.eventType != END_DOCUMENT) {
if (parser.eventType == START_TAG && parser.name == "element") {
elements[i].number = parser.getAttributeIntValue(null, "number", 0)
elements[i].letter = parser.getAttributeValue(null, "letter")
elements[i].name = parser.getAttributeValue(null, "name")
val weight = parser.getAttributeValue(null, "weight")
elements[i].weight = if (weight.isNotEmpty()) weight.toFloat() else 0F
i++
}
parser.next()
}
parser.close()
}.join()
Log.i("elements:", elements.joinToString { it.toString() + "\n" })
val lowerCaseLetters = "abcdefghiklmnopqrstuy"
val elementsRegex = Regex("""[ABCDEFGHIKLMNOPRSTUVWXYZ]([$lowerCaseLetters]{2}|[$lowerCaseLetters]?)\d*""")
val digitsRegex = Regex("""\d+""")
formulaInput.doOnTextChanged { text, _, _, _ ->
lateinit var foundedElements: List<Element>
thread {
foundedElements = elementsRegex
.findAll(text ?: "")
.map {
elements.find { element ->
Log.i("value", it.value + " " + it.value)
if (it.value.filter { it.isLetter() } == element.letter) {
val number = digitsRegex.find(it.value)
if (number != null) {
try {
element.moleculeCount = number.value.toInt()
element.weight = element.weight * number.value.toInt()
} catch (e: NumberFormatException) { }
}
element.percentage = adapter.getTotalWeight(element.weight) * 100
true
} else false
}
}.filterNotNull().toList()
}.join()
adapter.insertElements(foundedElements)
}
}
}
Element.kt:
data class Element(var number: Int = -1,
var letter: String = "",
var name: String = "",
var weight: Float = 0F,
var percentage: Float = 100F,
var moleculeCount: Int = 1)
xml file item example:
<element
number="6"
letter="С"
name="Углерод"
weight="12.011" />
I can't believe it, in my xml file letter "С" was a cyrillic letter "C" (\u0421)! And because of this equals check "С" == "C" was failing.
Huge Thanks to Wiktor Stribiżew for his comment.

android viewmodel observer inside RecyclerView.Adapter.onBindViewHolder() update every item

I need to download images from AWS S3 and update ImageViews inside a recycler view. I am using ViewModel for downloading files from S3. A file object is observing inside onBindViewHolder() method and once receive the file my intention was to update the image belongs with that particular holder.
But the problem is if there were two rows, then two images need to download. So each view holder will attach with the observer. After downloading the first file, both the image views inside the recycler view become updated with the first image and after downloading the second image, both images updated with the second image. I am a little bit confuse about working. Please help me with this.
I cannot use Glide for this. Because S3 have authentication. So, I need to use S3 library for downloading files.
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
val postUrl = listData[position].postUrl
val createdAt = listData[position].createdAt
val postImage = listData[position].postImage
val postVideo = listData[position].postVideo
val postVideoThumbnail = listData[position].postVideoThumbnail
val groupId = listData[position].groupId
val postStatus = listData[position].postStatus
val postId = listData[position].postId
val userId = listData[position].userId
val postHeading = listData[position].postHeading
val postDescription = listData[position].postDescription
val updatedAt = listData[position].updatedAt
val profileName = listData[position].userName
val profileImage = listData[position].profileImage
val likeCount = listData[position].likeCount
val commentCount = listData[position].commentCount
var key = ""
if(!profileImage.isNullOrEmpty()){
Glide.with(activity).load(profileImage) to holder.imgProfile
}
holder.textName.text = profileName.substring(0, 1).toUpperCase() + profileName.substring(1).toLowerCase()
holder.textPostedDateTime.text = SimpleDateFormat(POST_LIST_DATE_FORMAT).format(Date(createdAt))
holder.textPostHeading.text = postHeading
if(postDescription.isNullOrEmpty() || postDescription == "null"){
holder.textPostDescription.visibility = View.GONE
} else{
holder.textPostDescription.visibility = View.VISIBLE
holder.textPostDescription.text = postDescription
}
if(postUrl.isNullOrEmpty() || postUrl == "null"){
holder.textPostLink.visibility = View.GONE
} else{
holder.textPostLink.visibility = View.VISIBLE
holder.textPostLink.text = postUrl
}
if(postVideoThumbnail.isNullOrEmpty() || postVideoThumbnail == "null"){
holder.imgPostVideoPreview.visibility = View.GONE
} else{
holder.imgPostVideoPreview.visibility = View.VISIBLE
loadImageToFile(holder.imgPostVideoPreview, postVideoThumbnail, position)
key = postVideoThumbnail
}
if(postImage.isNullOrEmpty() || postImage == "null"){
holder.imgPostImagePreview.visibility = View.GONE
} else{
holder.imgPostImagePreview.visibility = View.VISIBLE
loadImageToFile(holder.imgPostImagePreview, postImage, position)
key = postImage
}
holder.textLikeCount.text = likeCount.toString()
holder.textCommentCount.text = commentCount.toString()
if(!isSelfPosts){
holder.layoutCommentLikeShare.visibility = View.VISIBLE
holder.imgAddComment.setOnClickListener { }
holder.imgAddLike.setOnClickListener { }
holder.imgShare.setOnClickListener { }
}
holder.itemView.setOnClickListener {
moveTOPostDetails(postId, listData[position], Environment.getExternalStorageDirectory().path + "/" + EXTERNAL_STORAGE_FOLDER_NAME + "/" + key.substring(key.lastIndexOf("/")+1))
}
}
class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val imgProfile: ImageView = itemView.imgProfile
val textName: TextView = itemView.textName
val textPostedDateTime: TextView = itemView.textPostedDateTime
val textPostHeading: TextView = itemView.textPostHeading
val textPostDescription: TextView = itemView.textPostDescription
val textPostLink: TextView = itemView.textPostLink
val imgPostVideoPreview: ImageView = itemView.imgPostVideoPreview
val imgPostImagePreview: ImageView = itemView.imgPostImagePreview
val textCommentCount: TextView = itemView.textCommentCount
val textLikeCount: TextView = itemView.textLikeCount
val layoutCommentLikeShare: LinearLayout = itemView.layoutCommentLikeShare
val imgAddComment: ImageView = itemView.imgAddComment
val imgAddLike: ImageView = itemView.imgAddLike
val imgShare: ImageView = itemView.imgShare
}
private fun moveTOPostDetails(postId: String, fetchPostsResponseModel: FetchPostsResponseModel, imageFileName: String){
val intent = Intent(activity, PostDetails::class.java)
intent.putExtra("POST_DETAILS", fetchPostsResponseModel)
intent.putExtra("IS_SELF_POST", isSelfPosts)
intent.putExtra("IMAGE_FILE_NAME", imageFileName)
activity.startActivity(intent)
}
private fun loadImageToFile(imageView: ImageView, key: String, position: Int){
var postListAdapterViewModel: PostListAdapterViewModel = ViewModelProviders.of(fragment).get(PostListAdapterViewModel::class.java)
postListAdapterViewModel.init(activity)
postListAdapterViewModel.getMediaFile()?.observe(fragment, Observer<File>{ file ->
var a=position
imageView.setImageURI(Uri.fromFile(file))
} )
postListAdapterViewModel.performDownload(key)
}
This is my viewmodel
class PostListAdapterViewModel(application: Application):AndroidViewModel(application){
private val file = MutableLiveData<File>()
private lateinit var context: Context
fun init(context: Context) {
this.context = context
AWSMobileClient.getInstance().initialize(context).execute()
}
fun performDownload(key : String){
val credentials = BasicAWSCredentials(AMAZON_S3_ACCESS_KEY, AMAZON_S3_SECRET_KEY)
val s3Client = AmazonS3Client(credentials)
val transferUtility = TransferUtility.builder()
.context(context)
.awsConfiguration(AWSMobileClient.getInstance().configuration)
.s3Client(s3Client)
.build()
val downloadObserver = transferUtility.download (
key,
File(Environment.getExternalStorageDirectory().path + "/" + EXTERNAL_STORAGE_FOLDER_NAME + "/" + key.substring(key.lastIndexOf("/")+1)))
// Attach a listener to get state updates
downloadObserver.setTransferListener(object : TransferListener {
override fun onStateChanged(id: Int, state: TransferState) {
if (state == TransferState.COMPLETED) {
// Handle a completed upload.
file.value = File(Environment.getExternalStorageDirectory().path + "/" + EXTERNAL_STORAGE_FOLDER_NAME + "/" + key.substring(key.lastIndexOf("/")+1))
}
}
override fun onProgressChanged(id: Int, current: Long, total: Long) {
try {
val done = (((current.toDouble() / total) * 100.0).toInt()) //as Int
Log.d("PostListAdapterVM", "DOWNLOAD - - ID: $id, percent done = $done")
}
catch (e: Exception) {
Log.e("PostListAdapterVM", "Trouble calculating progress percent", e)
}
}
override fun onError(id: Int, ex: Exception) {
Log.d("PostListAdapterVM", "DOWNLOAD ERROR - - ID: $id - - EX: ${ex.message.toString()}")
}
})
// If you prefer to poll for the data, instead of attaching a
// listener, check for the state and progress in the observer.
if (downloadObserver.state == TransferState.COMPLETED) {
// Handle a completed upload.
}
Log.d("PostListAdapterVM", "Bytes Transferrred: ${downloadObserver.bytesTransferred}")
}
fun getMediaFile(): MutableLiveData<File> {
return file
}
}

Categories

Resources