In fragment A, I trying to get image object from server and store them into totalListImage. This steps works fine.
var totalListImage: MutableList<Image> = mutableListOf()
fun getWorkRequestImage() {
GlobalScope.launch(Dispatchers.Main) {
val request = WebApi.getImages(activity, obj?.id!!)
request?.images?.let {
for (i in it!!.iterator()) {
totalListImage?.add(i)
}
}
mImageListAdapter.notifyDataSetChanged()
}
}
In same fragment, I allow user to take image and store the captured image into totalListImage.
Here onActivityResult
var path = data?.getExtras()?.getString("bitmap")
if (path != null) {
Log.d(TAG,path)
val images = Image()
images.image?.url = path
totalListImage.add(images)
display()
}
Finally in display method, I want to display all the url. But I get null pointer on the last captured image.
fun display() {
for (i in totalListImage) {
Log.d(TAG, i.image?.url)
}
}
If I remove the captured image, I get this
D/AFragment: https://xxx/image/633/1562424667277.png
D/AFragment: https://xxx/image/637/1562426838223.png
The path of the captured image confirm not null, as I display it I saw this
D/AFragment: /data/user/0/xxxk/cache/images/1562437144046.png
Why I can't save the last image's path into images.image?.url ?
Images
class Images : Serializable {
#PrimaryKey
var id = ""
#Ignore
var image : Image?=null
}
Image
#Parcelize
class Image(
#ColumnInfo(name = "image")
var url: String ? =null
) : Serializable,Parcelable
Referring to this code:
val images = Image()
images.image?.url = path
totalListImage.add(images)
and assuming that you meant val images = Images() (otherwise this snippet won't even compile),
then the issue is that images.image is null.
That's because of the definition of the Images class, where you have var image : Image?=null.
To solve you either:
change the class definition to have a not-null default value, like:
var image : Image? = Image()
or manually initialize it in the snippet above, like:
val images = Images()
images.image = Image()
images.image?.url = path
totalListImage.add(images)
Related
I have a lot of pictures on a path , and i move picture to this path , loading pictures and displaying them on recyclerView take a lot of time , and i am using a fragment , when i change fragment and back to the one that display pictures , it take again a lot of time to load pictures .
any suggestion to load pictures fast ?
suspend fun getImages() = try {
val path = Environment.getExternalStorageDirectory()
.toString() + "Here folder path "
val directory = File(path)
val files = directory.listFiles()
if (files.isEmpty()) {
//
} else {
}
for (i in files.indices) {
println( files[i].name)
val myBitmap = BitmapFactory.decodeFile(files[i].getAbsolutePath())
var path = files[i].getAbsolutePath()
var fileName = files[i].name
var picture = Picture(myBitmap, path, fileName)
if (picture != null) {
listPictures.add(picture)
}
}
withContext(Dispatchers.Main){
myAdapter.notifyDataSetChanged()
}
} catch (e: Exception) {
}
```
My User object has a List<Post>, each Post has a List<Tag>.
Now I would like to add a Tag item to the List<Tag>.
User:
data class User(
val id: String,
val name: String,
val posts: List<Post> = listOf()
)
Post:
data class Post(
val id: Int,
val name: String
val tags: List<Tags> = listOf()
)
Now I would like to update my MutableStateFlow containing the User object:
private val _userStateFlow: MutableStateFlow<User?> = MutableStateFlow(User())
val userStateFlow: StateFlow<User?> = _userStateFlow
To find the correct Post (containing the List<Tag> I want to update) I have the id of it (passedPostId)
val postsList = userStateFlow.value?.posts!!.toMutableList()
val tagsList = postsList.find { it.id == passedPostId }?.tags?.toMutableList()
tagsList.add(Tag("test"))
Now I got an updated tagsList but I need an updated postsList to pass it to my MutableStateFlow.
I am not sure how to do it.
This is how I update my MutableStateFlow:
_userStateFlow.update { it?.copy(posts = newPosts)
If I have the index of the post I want to update everything works fine, but In my Case I only can call .find because all i have is the id of the post.
val posts = userStateFlow.value?.posts!!.toMutableList()
posts[index] = posts[index].copy(tags = posts[index].tags.plus(Tag("test")
userStateFlow.value = userStateFlow.value?.copy(posts = posts)
You can create a function to add a tag to your immutable Post object - may as well stick it inside the class:
data class Post(
val id: Int,
val name: String
val tags: List<Tag> = listOf()
) {
// copy this object, replacing the tag list with a copy that has the new one appended
fun addTag(newTag: Tag) = copy(tags = tags + newTag)
}
Then you can do:
// alternative to putting it in the User class - whatever feels better
fun User.addTag(postId: Int, tag: Tag) =
// copy this User, including copying its list of Posts
// but any with a matching ID get the tag added
copy(posts = posts.map { post ->
if (post.id == postId) post.addTag(tag) else post
})
and update with
userStateFlow.value = userStateFlow.value!!.addTag(passedPostId, Tag("test"))
Try it here if you like
I fixed it by simply getting the index of the Post so I could use the code that worked before:
val postPosition = postsList.indexOfFirst {
it.id == passedPostId
}
postsList[postPosition] = postsList[postPosition].copy(tags = tagsList)
_userStateFlow.update { it?.copy(posts = postsList)
I feel pretty stupid to not have thought of that in the first place.
I have this function in my MainActivity.kt file which I want to produce a screenshot of the google map being rendered, then display it in an image view and save it. This is related to what I am trying to do but I don't have enough experience with Kotlin, Java and android studio to understand what isn't working.
My main issue is that I can't figure out how to get / access a variable containing the Bitmap
This is being added to the code from This Google Tutorial
private fun takePicture(googleMap: GoogleMap) {
var bitmapfrommap: Bitmap? = null
val snapshotReadyCallback : GoogleMap.SnapshotReadyCallback = GoogleMap.SnapshotReadyCallback {
fun onSnapshotReady(snapshot: Bitmap) {
bitmapfrommap = snapshot
imageView.setImageBitmap(bitmapfrommap)
var filename = "export.png"
var path = getExternalFilesDir(null)
var fileOut = File(path, filename)
if (bitmapfrommap != null) {
fileOut.writeBitmap(bitmapfrommap!!, Bitmap.CompressFormat.PNG, 85)
}
}
}
val onMapLoadedCallback : GoogleMap.OnMapLoadedCallback = GoogleMap.OnMapLoadedCallback {
googleMap.snapshot(snapshotReadyCallback, bitmapfrommap)
}
googleMap.setOnMapLoadedCallback(onMapLoadedCallback)
}
binding.takeMapScreenshot.setOnClickListener {
myMap?.snapshot { bitmap -> //here you do whatever you want with the resulting bitmap }
}
I am using below code to save image data into local directory from Uris obtained through pick intent.
private fun sendImages(uriString: String, messageBody: String, uriList: ArrayList<Uri>) {
val pathList = mutableListOf<String>()
val fileNameList = mutableListOf<String>()
var fieSize = 0
var multiSize = 0
if(uriList.isEmpty() && uriString.isNotEmpty())
uriList.add(Uri.parse(uriString))
val localId: String = "localId"
for(i in 0 until uriList.size) {
val uri = uriList[i]
val path = FileUtils.getPath(application, uri)!!
val fullName = path.substring(path.lastIndexOf("/") + 1)
val name = "some function call that returns unique name for file"
val file = File(requireActivity().applicationContext.filesDir, localId + name)
file.createNewFile()
var bitmapdata: ByteArray? = null
var inputStream: InputStream? = null
try {
val ei = ExifInterface(path)
val orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)
var bitmap: Bitmap? = null
bitmap = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
ImageDecoder.decodeBitmap(ImageDecoder.createSource(requireActivity().applicationContext.contentResolver, uri))
}
else MediaStore.Images.Media.getBitmap(requireActivity().applicationContext.contentResolver, uri)
val newBitmap = FunctionUtil.rotateImage(bitmap, orientation)
bitmapdata = FileUtils.getCompressedBitmapForUpload(newBitmap!!)
FunctionUtil.recycleBitmap(newBitmap)
} catch (e: Exception) {
return
}
}
requireActivity().applicationContext.openFileOutput(file.name, Context.MODE_PRIVATE).use {
it.write(bitmapdata)
}
val localPath = FunctionUtil.getMediaStorePath(requireActivity().application)
val completePath = requireActivity().application.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)!!
var outFile =File(localPath+"/"+file.name)
org.apache.commons.io.FileUtils.copyFile(file,outFile)
Logger.log("PATH ${ outFile.absolutePath} ${ outFile.path}")
pathList.add(outFile.absolutePath)
fileNameList.add(file.name)
//... Do something with this data
}
}
In the same code, if single file is copied to local directory, it is getting saved & i am able to send it . But whenever i try to save multiple files, the files are becoming empty when i try to send them.
I am not able to find what issue is there. Please help
Some Android phones will encounter such a problem :
the file does exist, but the 'fd' returned by the 'c++ open()' method is -1, and the 'strerror' showing 'No such file or directory".
The phones I have come across are as follows:
vivo
V2055A V2073A V2241A
huawei
GIA-AN00 JLH-AN00 CMA-AN00 HPB-AN00 NTN-AN20 CMA-AN40
oppo
LE2110
In the source code of the Android System, a similar phenomenon can also be found :
The above is a comment added in 2017, and only the common 'bmp' and 'ico' formats are written.
In face, this problem also occurs with pictures in 'heif/heic' format.
Finally,
Using 'FileInputStream' will be ok.
I try to add accident in firebase-realtime with some information and some images, only the information are saved, the images paths are saved in firebase-storage but not in firebase-realtime.when I get the path of images from firebase-storage. I put this result path in arrayList of String. I want to put this arrayList in accident .I don't know why only the information are saved and the arrayList not saved, can some one help me please ?
class Accident (
var date:String?,
var id:String?,
var description:String?,
// var video:Array<String>?=null,
// var gravite:Int?=null,
val geolocalisation:Localisation?,
var photos: ArrayList<String>?,
val adress:String?
//var nbVictime:Int?=null
): Serializable
class Localisation( var altitude:Double=0.0,
var longitude:Double = 0.0)
: Serializable {
}
fun loadDatabase(firebaseData: DatabaseReference) {
uploadFile()
var loc = Localisation(currentLatLng!!.latitude, currentLatLng!!.longitude)
var uri=tabpath as ArrayList<String>
val availableAccident: List<Accident> = mutableListOf(
Accident(SimpleDateFormat("yyyy/MM/dd_HH:mm:ss").format(Date()), "", "il est tres grave", loc, uri, "Monastir")
)
var t=""
availableAccident.forEach {
val key = firebaseData.child("accidents").push().key
it.id = key!!
it.photos=uri
if (key != null) {
firebaseData.child("accidents").child(key).setValue(it)
}
}
}