Hello I have activity with two buttons. First I take a photo and in override onActivityResult I upload the photo in firebase and I get an url which I save to photoUrl . Then in the other btn listener inside oncreate I want to use this variable but I get null as I define it in the begin of the class. How can I get the value of photoUrl which I want?
class AddYourStory : AppCompatActivity() {
val storage = FirebaseStorage.getInstance()
private val REQUEST_IMAGE = 100
private val TAG = "MainActivity"
var destination: File? = null
var imagePath: String? = null
var photoUrl : String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_your_story)
setSupportActionBar(toolbar)
val db: FirebaseFirestore
val intent = intent
val lat = intent.getStringExtra("lng")
val lng = intent.getStringExtra("lng")
db = FirebaseFirestore.getInstance()
val builder = StrictMode.VmPolicy.Builder()
StrictMode.setVmPolicy(builder.build());
val name = dateToString(Date(), "yyyy-MM-dd-hh-mm-ss")
destination = File(Environment.getExternalStorageDirectory(), "$name.jpg")
val takephoto = findViewById<Button>(R.id.button2)
takephoto.setOnClickListener {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(destination));
startActivityForResult(intent, REQUEST_IMAGE);
}
val txtTitle = findViewById<TextInputEditText>(R.id.textInputEditText2)
val txtStory = findViewById<EditText>(R.id.editText)
val btn = findViewById<Button>(R.id.button)
btn.setOnClickListener{
println("????????????????????????>>>>"+photoUrl)
val MyStory: HashMap<String, String> = HashMap<String,String>()
MyStory.put("title",txtTitle.text.toString())
MyStory.put("story",txtStory.text.toString())
MyStory.put("lat",lat)
MyStory.put("lng",lng)
MyStory.put("url",photoUrl.toString())
db.collection("Stories").document().set(MyStory as Map<String, Any>)
val confirm = Intent(this, MapsActivity::class.java)
startActivity(confirm)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_IMAGE && resultCode == Activity.RESULT_OK) {
try {
val `in` = FileInputStream(destination)
val options = BitmapFactory.Options()
options.inSampleSize = 10
imagePath = destination!!.getAbsolutePath()
val storageRef = storage.reference
val stream = FileInputStream(File(imagePath))
val picRef = storageRef.child(dateToString(Date(), "yyyy-MM-dd-hh-mm-ss"))
val uploadTask = picRef.putStream(stream)
uploadTask.addOnFailureListener { exception ->
println("Failed")
}.addOnSuccessListener { taskSnapshot ->
println("OK")
picRef.downloadUrl.addOnCompleteListener () {taskSnapshot ->
photoUrl = taskSnapshot.result.toString()
println ("url =" + photoUrl.toString ())
}
}
val bmp = BitmapFactory.decodeStream(`in`, null, options)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
} else {
println("Cancel")
}
}
fun dateToString(date: Date, format: String): String {
val df = SimpleDateFormat(format)
return df.format(date)
}
}
Related
i am trying to create a video player app using kotlin , First of all I got the videos files by using MediaStore , than store this in ArrayList so far it's been perfect but When I made a folder list of videos, I tried to find out the size of those folders and how many video files there are in those folders, but I failed. like this (Image)
Check this image for more clear
This is my data class code (VideoItem.Kt)
import android.net.Uri
data class VideoItem(
val id: String,
val title: String,
val duration: Long = 0,
val folderName: String,
val size: String,
val path: String,
val dateAdded: String,
val artUri: Uri
)
data class FolderItem(
val id: String,
val folderName: String,
val folderSize: Long
)
This is my MainActivity Code To get Allvideos Using MediaStore
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
companion object {
lateinit var videoList: ArrayList<VideoItem>
lateinit var folderList: ArrayList<FolderItem>
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
folderList = ArrayList()
videoList = getAllVideos()
setFragment(VideoviewFragment())
}
private fun setFragment(fragment: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.FrameLayout, fragment)
transaction.disallowAddToBackStack()
transaction.commit()
}
#SuppressLint("Recycle", "Range")
private fun getAllVideos(): ArrayList<VideoItem> {
val tempList = ArrayList<VideoItem>()
val tempFolderList = ArrayList<String>()
val projection = arrayOf(
MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.SIZE,
MediaStore.Video.Media._ID,
MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
MediaStore.Video.Media.DATA,
MediaStore.Video.Media.DATE_ADDED,
MediaStore.Video.Media.DURATION,
MediaStore.Video.Media.BUCKET_ID
)
val cursor = this.contentResolver.query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
projection,
null,
null,
MediaStore.Video.Media.DATE_ADDED + " DESC"
)
if (cursor != null)
if (cursor.moveToNext())
do {
val titleC =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE))
val idC = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media._ID))
val folderNameC =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_DISPLAY_NAME))
val folderIdC =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID))
val sizeC = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.SIZE))
val pathC = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA))
val dateAddedC =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATE_ADDED))
val durationC =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DURATION))
.toLong()
try {
val file = File(pathC)
val artUriC = Uri.fromFile(file)
val video = VideoItem(
title = titleC,
id = idC,
folderName = folderNameC,
size = sizeC,
path = pathC,
duration = durationC,
dateAdded = dateAddedC,
artUri = artUriC
)
if (file.exists()) tempList.add(video)
//for adding Folders
if (!tempFolderList.contains(folderNameC)) {
tempFolderList.add(folderNameC)
val folderSizeC = getFileLength(pathC)
folderList.add(
FolderItem(
id = folderIdC,
folderName = folderNameC,
folderSize = folderSizeC
)
)
}
} catch (_: Exception) {
}
} while (cursor.moveToNext())
cursor?.close()
return tempList
}
private fun getFileLength(path: String?): Long {
return if (!isExistFile(path)) 0 else File(path.toString()).length()
}
private fun isExistFile(path: String?): Boolean {
val file = File(path.toString())
return file.exists()
}
}
This is my RecyclerviwAdapter Code(FolderAdapter.kt)
class FoldersAdapter(private val context: Context, private var foldersList: ArrayList<FolderItem>) :
RecyclerView.Adapter<FoldersAdapter.MyHolder>() {
class MyHolder(binding: FolderItemBinding) : RecyclerView.ViewHolder(binding.root) {
val folderName = binding.folderName
val noofFiles = binding.nooffiles
val folderSize = binding.foldersize
val root = binding.root
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
return MyHolder(FolderItemBinding.inflate(LayoutInflater.from(context), parent, false))
}
override fun onBindViewHolder(holder: MyHolder, position: Int) {
holder.folderName.text = foldersList[position].folderName
val size: Long = foldersList[position].folderSize
holder.folderSize.text = android.text.format.Formatter.formatFileSize(context, (size))
holder.root.setOnClickListener {
val intent = Intent(context, FolderVideosActivity::class.java)
intent.putExtra("position", position)
ContextCompat.startActivity(context, intent, null)
}
}
override fun getItemCount(): Int {
return foldersList.size
}
}
This is my all codes now please check out all code and suggest the best.
Thank you
Use this function for size
private fun getFolderSize(f: File): Long {
var size: Long = 0
if (f.isDirectory) {
for (file in f.listFiles()!!) {
size += getFolderSize(file)
}
} else {
size = f.length()
}
return size
}
And Count number of files Use this
val length = File("/path/to/folder").listFiles()?.size
i have created an application which uses firebase push notification to get commands and perform that task.
my app doesn't have any visible activity but a service which continuously working in background.
i have implemented a functionality of taking screenshot using Media Projection Api.
when i get command of Screenshot, app launches ScreenProjectionActivity, took screenshot and finish. but when it gets again command of Screenshot ScreenProjectionActivity doesn't launch again. i dont know what i am doing wrong and where i am doing wrong.
Here is how i am launching from service.
context.startActivity(
Intent(this, ScreenProjectionActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
ScreenProjectionActivity.kt
class ScreenProjectionActivity : Activity()
{
lateinit var context: Context
private var mHandler: Handler? = null
#RequiresApi(Build.VERSION_CODES.KITKAT_WATCH)
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
val tv = TextView(this)
tv.text = ""
setContentView(tv)
context = this
log("onCreate")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
val mgr = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
startActivityForResult(mgr.createScreenCaptureIntent(), 7575)
// start capture handling thread
object : Thread() {
override fun run() {
Looper.prepare()
mHandler = Handler()
Looper.loop()
}
}.start()
}
}
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 7575 && resultCode == RESULT_OK)
{
log("if taking screen")
//TakeScreenShot(applicationContext, Handler(Looper.getMainLooper()), resultCode, data).start()
takeScreenShot(resultCode, data)
}
super.onBackPressed()
}
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun takeScreenShot(resultCode: Int, data: Intent?)
{
log("takeScreenshot")
SystemClock.sleep(1000)
var flagScreenShot = true
val metrics = DisplayMetrics()
val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
val mgr = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
windowManager.defaultDisplay.getMetrics(metrics)
val mMediaProjection = mgr.getMediaProjection(resultCode, data!!)
val imgReader: ImageReader = ImageReader.newInstance(
metrics.widthPixels,
metrics.heightPixels,
PixelFormat.RGBA_8888,
1
)
val onImageAvailableListener =
OnImageAvailableListener {
log("onImageAvailableListener")
val image: Image? = it?.acquireLatestImage()
if (image != null && flagScreenShot)
{
flagScreenShot = false
mMediaProjection?.stop()
log("mMediaProjection Stopped!")
imgReader.setOnImageAvailableListener(null, null)
val mWidth = image.width
val mHeight = image.height
val planes = image.planes
val buffer = planes[0].buffer
val pixelStride = planes[0].pixelStride
val rowStride = planes[0].rowStride
val rowPadding = rowStride - pixelStride * mWidth
val bitmap = Bitmap.createBitmap(
mWidth + rowPadding / pixelStride,
mHeight,
Bitmap.Config.ARGB_8888
)
bitmap.copyPixelsFromBuffer(buffer)
saveImage(bitmap)
}
log("image close")
image?.close()
}
mMediaProjection?.createVirtualDisplay(
"ScreenCapture",
metrics.widthPixels,
metrics.heightPixels,
metrics.densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
imgReader.surface,
null,
mHandler
)
imgReader.setOnImageAvailableListener(onImageAvailableListener, mHandler)
}
private fun saveImage(finalBitmap: Bitmap) {
val root: String = Environment.getExternalStorageDirectory().toString()
val myDir = File("$root/saved_images")
myDir.mkdirs()
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(Date())
val fname = "Shutta_$timeStamp.jpg"
val file = File(myDir, fname)
if (file.exists()) file.delete()
try
{
val out = FileOutputStream(file)
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)
out.flush()
out.close()
log("Image Saved.")
finish()
} catch (e: Exception) {
log("Image Saved Exception: $e")
}
}
private fun encodeImage(bm: Bitmap): String {
val baos = ByteArrayOutputStream()
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val b = baos.toByteArray()
return Base64.encodeToString(b, Base64.DEFAULT)
}
override fun onDestroy() {
super.onDestroy()
}
}
Please help me out here. thanks
I solved it my self, what i did is startActivity with these flags
applicationContext.startActivity(
Intent(this, ScreenProjectionActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
and in Manifest:
<activity
android:name=".ScreenProjectionActivity"
android:excludeFromRecents="true"
android:theme="#android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
I have a code to retrieve list of all music from storage but after i renamed a file the recyclerview doesnt update with the change
even after deleting a file it still remains the same
fun Context.musicFiles():MutableList{
val list:MutableList<Music> = mutableListOf()
val uri: Uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
//val uri: Uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI
// IS_MUSIC : Non-zero if the audio file is music
val selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0"
// Sort the musics
val sortOrder = MediaStore.Audio.Media.TITLE + " ASC"
//val sortOrder = MediaStore.Audio.Media.TITLE + " DESC"
// Query the external storage for music files
val cursor: Cursor = this.contentResolver.query(
uri, // Uri
null, // Projection
selection, // Selection
null, // Selection arguments
sortOrder // Sort order
)
// If query result is not empty
if (cursor!= null && cursor.moveToFirst()){
val id:Int = cursor.getColumnIndex(MediaStore.Audio.Media._ID)
val title:Int = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)
val artist:Int= cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)
val musicpathh:Int= cursor.getColumnIndex(MediaStore.Audio.Media.DATA)
val album:Int = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)
// Now loop through the music files
do {
val audioId:Long = cursor.getLong(id)
val audioTitle:String = cursor.getString(title)
val audioArtist:String = cursor.getString(artist)
val audiopath:String = cursor.getString(musicpathh)
val audioalbum:String = cursor.getString(album)
// Add the current music to the list
list.add(Music(audioId,audioTitle,audioArtist,audiopath,audioalbum))
}while (cursor.moveToNext())
}
// Finally, return the music files list
return list
}
data class Music(val id:Long, val title:String, val artist:String, val audiopath:String, val audioalbumm:String)
Function to get musicfiles
val list:MutableList = musicFiles()
val titles = mutableListOf<String>()
val artist = mutableListOf<String>()
val musicpath = mutableListOf<String>()
val album = mutableListOf<String>()
val checkd = mutableListOf<Boolean>()
for (music in list){titles.add(music.title)}
for (music in list){artist.add(music.artist)}
for (music in list){musicpath.add(music.audiopath)}
for (music in list){album.add(music.audioalbumm)}
for (music in list){checkd.add(false)}
val adapter= HobbiesAdapter(this, titles, artist, musicpath, album, checkd)
recyclerView.adapter = adapter
adapter
class HobbiesAdapter(val context: Context, val hobbies: MutableList, val artis: MutableList, val pathh: MutableList, val albumm: MutableList, val checkd: MutableList) : RecyclerView.Adapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return hobbies.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val hobby = hobbies[position]
val artistt = artis[position]
val patth = pathh[position]
val albbum = albumm[position]
holder.setData(hobby, artistt, patth, position, albbum)
}
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var currentHobby: String = ""
var currentArtist: String = ""
var currentPath: String = ""
var currentAlbum: String = ""
var currentPosition: Int = 0
var checkdd:Int=0
var currentCheckedStatus:Boolean=false
init {
itemView.setOnClickListener {
if(itemView.checkstatus.isChecked==true){
itemView.checkstatus.isChecked=false
checkdd=adapterPosition
checkd.set(checkdd,false)
}
else{
itemView.checkstatus.isChecked=true
checkdd=adapterPosition
checkd.set(checkdd,true)
}
}
itemView.checkstatus.setOnClickListener {
if(itemView.checkstatus.isChecked==true){
itemView.checkstatus.isChecked=false
checkdd=adapterPosition
checkd.set(checkdd,false)
}
else{
itemView.checkstatus.isChecked=true
checkdd=adapterPosition
checkd.set(checkdd,true)
}
}
}
fun setData(hobby: String, artiist: String, paath: String, pos: Int, albuum: String) {
itemView.txvTitle.text = hobby
itemView.txvArtist.text=artiist
itemView.txvPath.text=paath
itemView.txvAlbum.text=albuum
itemView.checkstatus.isChecked=checkd.get(pos)
this.currentHobby = hobby
this.currentArtist = artiist
this.currentPath = paath
this.currentAlbum = albuum
this.currentPosition = pos
this.currentCheckedStatus=checkd.get(pos)
}
}
}
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
}
}
I am trying to read contacts from ContactsContract in Kotin. But it's not showing any of the contact in the recyclerview. The noticeable thing is that the java version of this code is working fine.
So, I here is my Kotlin code for reading the contact:
private var adapter: ContactsAdapter? = null
private var myContacts : MutableList<MyContacts> = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// code for recyclerview and adapter and checkPermission
val itemDecoration = DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
recycler_view.layoutManager = LinearLayoutManager(this)
recycler_view.addItemDecoration(itemDecoration)
adapter = ContactsAdapter(myContacts)
recycler_view.hasFixedSize()
recycler_view.adapter = ContactsAdapter(myContacts)
checkPermission()
}
private fun loadContactFromProvider() {
showProgressBar()
val contentResolver = contentResolver
val cursor = contentResolver.query(CONTENT_URI, null, null, null, DISPLAY_NAME)
if (cursor != null && cursor.count > 0) {
while (cursor.moveToNext()) {
val id = cursor.getString(cursor.getColumnIndex(ID))
val name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME))
val hasPhoneNumber = cursor.getInt(cursor.getColumnIndex(HAS_PHONE_NUMBER))
val contacts = MyContacts()
if (hasPhoneNumber > 0) {
contacts.contactName = name
val phoneCursor = contentResolver.query(PHONE_URI, arrayOf(NUMBER), "$PHONE_ID = ?", arrayOf(id), null)
val phoneNumbers = ArrayList<String>()
phoneCursor!!.moveToFirst()
while (!phoneCursor.isAfterLast) {
val phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER)).replace(" ", "")
phoneNumbers.add(phoneNumber)
phoneCursor.moveToNext()
}
contacts.contactNumber = phoneNumbers
phoneCursor.close()
}
val inputStream = ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, ContentUris.withAppendedId(CONTENT_URI, id.toLong()))
if (inputStream != null) {
val bitmap = BitmapFactory.decodeStream(inputStream)
contacts.contactImage = bitmap?.toString()
} else {
contacts.contactImage = vectorDrawableToBitmap(R.drawable.ic_person)?.toString()
}
log(contacts.contactName + " " + contacts.contactNumber.toString() + " " + contacts.contactImage.toString())
myContacts.add(contacts)
}
adapter?.notifyDataSetChanged()
cursor.close()
}
}
The log details are also fine, they are showing the full contact list. But I am unable to see it in the recyclerview. The constant field like ID, DISPLAY_NAME etc. are already defined in the companion object.
Kotlin code for RecyclerViewAdapter is:
class ContactsAdapter(private val contactList: MutableList<MyContacts>): RecyclerView.Adapter<ContactsAdapter.ContactViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, position: Int): ContactViewHolder {
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.contact_item_layout,viewGroup,false)
return ContactViewHolder(view)
}
override fun onBindViewHolder(holder: ContactViewHolder, position: Int) {
val contact = contactList[position]
holder.name!!.text = contact.contactName
holder.mobile!!.text = contact.contactNumber[0]
Glide.with(holder.itemView.context)
.load(contact.contactImage)
.into(holder.image)
}
override fun getItemCount(): Int = contactList.size
class ContactViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var image : ImageView = itemView.find(R.id.contact_image) as ImageView
var name : TextView? = itemView.find(R.id.contact_name) as TextView
var mobile : TextView? = itemView.find(R.id.contact_mobile) as TextView
}
}
Any help would be appreciated.
Thankyou