My compressed image has no dimensions android - kotlin

I use this function to compress images:
private fun takeScreenshot() {
val now = Date()
DateFormat.format("yyyy-MM-dd_hh:mm:ss", now)
val now2= now.toString().split(" ")
try {
// image naming and path to include sd card appending name you choose for file
val mPath: String =
getExternalFilesDir(null).toString().toString() + "/" + now2 + ".png"
Log.d("path",mPath)
// create bitmap screen capture
val v1 = window.decorView.rootView
v1.isDrawingCacheEnabled = true
val bitmap = Bitmap.createBitmap(v1.drawingCache)
v1.isDrawingCacheEnabled = false
val imageFile = File(mPath)
val outputStream = FileOutputStream(imageFile)
val quality = 100
bitmap.compress(Bitmap.CompressFormat.PNG, quality, outputStream)
outputStream.flush()
outputStream.close()
} catch (e: Throwable) {
// Several error may come out with file handling or DOM
e.printStackTrace()
}
}
And after do it,the result is a png file with no dimensions,i can't open it and view on laptop but can view on phone:
How to add dimensions?

Related

Google Places OpeningHours.getWeekdayText() is NULL for some locations

I'm using google places to retrieve information for a place such as the business name, address, OpenHours and LatLng.
This works 95% of the time, but for some places I receive the error...
"Attempt to invoke virtual method 'java.util.List com.google.android.libraries.places.api.model.OpeningHours.getWeekdayText()' on a null object reference"
Looking on Google maps, I do see these places have open hours information.
//Add a marker when a POI on map is clicked.
map.setOnPoiClickListener { poi ->
map.clear()
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
poiMarker?.showInfoWindow()
placeId = poi.placeId
Timber.i("Place ID: $placeId")
//https://developers.google.com/maps/documentation/places/android-sdk/reference/com/google/android/libraries/places/api/net/PlacesClient#fetchPlace(com.google.android.libraries.places.api.net.FetchPlaceRequest)
val placeFields = listOf(Place.Field.ID, Place.Field.NAME, Place.Field.ADDRESS, Place.Field.OPENING_HOURS, Place.Field.LAT_LNG)
val request = FetchPlaceRequest.newInstance(placeId, placeFields)
if (!Places.isInitialized()) {
Places.initialize(requireContext(), apiKey, Locale.US);
}
val placesClient = Places.createClient(requireContext())
placesClient.fetchPlace(request)
.addOnSuccessListener { response: FetchPlaceResponse ->
val place = response.place
setLiveDataPlace(place)
}.addOnFailureListener { exception: Exception ->
if (exception is ApiException) {
Timber.i( "Place not found: ${exception.message}")
}
}
binding.buttonSave.visibility = View.VISIBLE
}
}
fun setLiveDataPlace(place: Place){
placeId = place.id as String
placeName = place.name as String
placeAddress = place.address as String
try {
placeOpenMonday = place.openingHours.weekdayText[0]
placeOpenTuesday = place.openingHours.weekdayText[1]
placeOpenWednesday = place.openingHours.weekdayText[2]
placeOpenThursday = place.openingHours.weekdayText[3]
placeOpenFriday = place.openingHours.weekdayText[4]
placeOpenSaturday = place.openingHours.weekdayText[5]
placeOpenSunday = place.openingHours.weekdayText[6]
} catch(e : Exception) {
Timber.i("Open hours exception: ${e.message}")
}
placeLat = place.latLng.latitude.toString()
placeLng = place.latLng.longitude.toString()
Timber.i("Place: $place")
}

How to get filepath for Documents from Uri in android 10 and android 11

I am creating an app where users will upload pdf or doc files.
I have used default file chooser which returns Uri , now i need to upload those selected files to server
Its working fine upto android 9 ,i am facing issues in android 10 and 11 (i have used android:requestLegacyExternalStorage="true" for android 10 )
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
.apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "*/*"
putExtra(Intent.EXTRA_MIME_TYPES, supportedDocumentTypes.keys.toTypedArray())
}
resultLauncher.launch(intent)
In Activity Result
if (data != null) {
var path = ""
val id = data.data?.lastPathSegment!!
val selection = "_id=?"
if (id.startsWith("msf:") && Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
path = FileHelper(requireContext()).getRealPathFromUri(data.data!!.toString()
.replace("msf:","").toUri())!!
}else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q){
path = FileHelper(requireContext()).getRealPathFromUri(data.data!!)!!
}else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
path = getDataColumn(context, MediaStore.Downloads.EXTERNAL_CONTENT_URI,
selection, arrayOf(getPath(data.data!!)))
} else {
data.data?.also { uri ->
path = FileHelper(requireContext()).getRealPathFromUri(uri)!!
}
}
Log.e("Doc Path ::",path)
AppUtils.CustomToast(requireActivity(),path)
uploadDocs(path)
}
For getting Document_ID
private fun getPath(uri : Uri) : String {
val contentResolver = requireActivity().applicationContext.contentResolver
val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
// Check for the freshest data.
contentResolver.takePersistableUriPermission(uri, takeFlags)
val cursor: Cursor? = contentResolver.query(
uri, null, null, null, null, null)
var id = ""
cursor?.use { cursor1 ->
if (cursor1.moveToFirst()) {
val displayName: String = cursor1.getString(cursor1.getColumnIndex(OpenableColumns.DISPLAY_NAME))
Log.i(TAG, "Display Name: $displayName")
val names = cursor1.columnNames.joinToString(",") { it }
Log.e("names ^^^^^",names)
val sizeIndex: Int = cursor1.getColumnIndex(OpenableColumns.SIZE)
val size: String = if (!cursor1.isNull(sizeIndex)) {
cursor1.getString(sizeIndex)
} else { "Unknown" }
Log.i(TAG, "Size: $size")
id = cursor1.getString(cursor1.getColumnIndex(cursor1.columnNames[0]))
Log.e("DocId",id)
}
}
return id
}
Uploading file to server using Retrofit
val builder = MultipartBody.Builder()
builder.setType(MultipartBody.FORM)
val file = File(docPaths)
builder.addFormDataPart("documents", file.name,
RequestBody.create("multipart/form-data".toMediaTypeOrNull(), file))
val requestBody: MultipartBody = builder.build()
I am expecting some code for getting file to upload to server
Thanks In Advance

Converting Hashmap to CSV in Kotlin Android

Hi I am trying to convert a hashmap where hashmap =
private var Sdata:MutableMap<String, MutableList> = mutableMapOf<String, MutableList>()
Sdata currently looks like the picture below:
https://i.stack.imgur.com/UNLCR.png[enter link description here]1
My code to convert my hashmap to csv looks like this: #Credit to Михаил Нафталь
binding.btnSave.setOnClickListener() {
Sdata = viewModel.savehash
val csv = File(this.filesDir, "test.csv")
val valuesSeparator = ","
val lineTerminator = "\r\n"
val rowTerminator = "["
//write header, overwrite file if it has existed
csv.writeText(
Sdata.keys.joinToString(
separator = valuesSeparator,
postfix = lineTerminator
)
)
//write rows
val nRows = Sdata.values.maxOf { it.size } // if size of all lists are not equal
//val nRows = Sdata.values.first().size // if size of all lists are equal
for (i in 0 until nRows) {
val row = Sdata.values
//.map { it[i] } // if it's guaranteed that size of all lists is the same
.map { it.getOrElse(i) { "" } } // otherwise
.joinToString(separator = valuesSeparator, postfix = lineTerminator)
csv.appendText(row)
}
Log.d(TAG, "CSV VIEW: $Sdata")
Toast.makeText(this, "Data Saved to Documents", Toast.LENGTH_SHORT).show()
}
I was able to get my csv file successfully but the data format is off:
CSV File 2:
https://i.stack.imgur.com/xSb0U.png
How should I fix This? Any help would be greatly appreciated.

How to change encoding to a downloaded file Kotlin

I'm making an app which will download a .zip file, unzip it and finally take the .srt file (which was zipped) and put it as subtitle file in exoplayer movie.
My problem
The file has greek letters inside and when I put it as a subtitle file I only see corrupted letters
What have I tried
Below is the code to unzip the file
fun writeZipAndUnZip(subtitlesLinks: ArrayList<String>, context: Context, body: ResponseBody?) {
if (body == null) { return }
val file = File(getSubsDirectory(), subtitlesLinks.first())
var inputStream: InputStream? = null
var outputStream: OutputStream? = null
try {
val fileReader = ByteArray(4096)
inputStream = body.byteStream()
outputStream = FileOutputStream(file)
while (true) {
var read = inputStream.read(fileReader)
if (read == -1) {
break
}
outputStream.write(fileReader, 0, read)
}
outputStream.flush()
unzip(context)
} catch (e: IOException) {
return
} finally {
inputStream?.close()
outputStream?.close()
}}
fun unzip(context: Context) {
val unzipPath = getSubsDirectory()
var count: Int
val buffer = ByteArray(4096)
val subFile = File(getSubsDirectory()).listFiles()?.first() ?: return
try {
val stream = FileInputStream(subFile.absolutePath)
ZipInputStream(stream).use { zis ->
var ze = ZipEntry("")
while (zis.nextEntry?.also { ze = it } != null) {
var fileName = ze.name
fileName = fileName.substring(fileName.indexOf("/") + 1)
val file = File(unzipPath, fileName)
val dir = if (ze.isDirectory) file else file.parentFile
if (!dir.isDirectory && !dir.mkdirs())
throw FileNotFoundException("Invalid path: " + dir.absolutePath)
if (ze.isDirectory) continue
val fileOutput = FileOutputStream(file)
try {
while (zis.read(buffer).also { count = it } != -1)
fileOutput.write(buffer, 0, count)
} catch (e: IOException) {
Timber.tag("ErrorZip").d(e.localizedMessage)
} finally {
val fileOutput = context.openFileOutput(fileName, Context.MODE_PRIVATE)
fileOutput.close()
}
}
}
} catch (e: IOException) {
Timber.tag("ErrorZip").d(e.localizedMessage)
}}
Here is the code I put subtitle in exoplayer
val subtitleFormat = Format.createTextSampleFormat(null, MimeTypes.APPLICATION_SUBRIP, Format.NO_VALUE, "el")
val subtitleSource = SingleSampleMediaSource(File(Utils.getSubsDirectory()).listFiles()!![1].toUri(), dataSourceFactory, subtitleFormat, C.TIME_UNSET)
mediaSource = MergingMediaSource(buildMediaSource(videoUrl), subtitleSource)
I also tried to resave the subtitle with Utf-8 encoding but I get some characters in greek and the most missing or incorrect using this code
fun encode() {
val charset = "UTF8"
val subFile = File(getSubsDirectory()).listFiles()!![1] ?: return
val inputStream: InputStream = subFile.absoluteFile.inputStream()
val inputString = inputStream.bufferedReader().use { it.readText() }
val writer = OutputStreamWriter(FileOutputStream(File(getSubsDirectory(), "subs.srt")), charset)
writer.write(inputString)
writer.close()
}
Probably the file you are trying to read is in a different encoding than the System default (Android uses utf-8). You need to read the file at the 'correct' encoding format (for Greek usually is Windows-1253) and then save it to utf-8.

Kotlin not receiving a full packet from an HC-06 Bluetooth module

In Kotlin I am having an issue with data not fully loading into the buffer in Android in one packet. I am sending <7:16> data packet from a HC-06 bluetooth module.
When i receive it's coming in as 2 packets. The micro is sending a CR and LF and the end of the transmission.
I/UI_Msg: <
I/UI_Msg: 7:16>
I/UI_Msg: <
I/UI_Msg: 7:16>
etc
If I add a sleep command for a second, then query the buffer it comes in completed in one packet. The problem is I want to send more than one packet in a second..
How can i fix this issue to or can i just build a string until '>' is received from the buffer.
private fun beginListenForData() {
val handler = Handler()
stopThread = false
buffer = ByteArray(10)
val thread = Thread(Runnable {
while (!Thread.currentThread().isInterrupted && !stopThread) {
try {
val byteCount = inputStream!!.available()
if (byteCount > 0) {
//Thread.sleep(1000) // wait for buffer finish filling
val rawBytes = ByteArray(byteCount)
inputStream!!.read(rawBytes)
val string = String(rawBytes, StandardCharsets.UTF_8)
//handler.post {txt_message.text=""}
Log.i(TAG,""+ string)
//handler.post {txt_message.append(string)}
// processInput(string)
}
} catch (ex: IOException) {
stopThread = true
}
}
})
thread.start()
}
Figgured it out. Read the buffer one byte at a time and build the string character at a time. Check for the < and the > character for a valid transmission
private fun beginListenForData() {
stopThread = false
val thread = Thread(Runnable {
while (!Thread.currentThread().isInterrupted && !stopThread) {
try {
val byteCount = inputStream!!.available()
if (byteCount > 0) {
val rawBytes = ByteArray(1)
inputStream!!.read(rawBytes,0,1)
val string = String(rawBytes, StandardCharsets.UTF_8)
if (string== "<") {
m_Headder=true
}
if (m_Headder==true){
stringBuilder = stringBuilder.plus(string)
if (string ==">") {
m_Received=stringBuilder
Log.i(TAG, "string:" + stringBuilder)
stringBuilder = ""
m_Headder = false
ProcessMessage(m_Received)
}
}
}
} catch (ex: IOException) {
stopThread = true
}
}
})
thread.start()
}