make a file shareable using drive api in android studio - android

In my mobile application I am using Drive API to upload an file to the google drive. It works well. But it uploads all the files as not shareable. I want to make this shareable.
Here is my code in kotlin
// upload a file in to google drive
fun uploadFile(localFile: java.io.File, mimeType: String?, folderId: String?): Task<Any>? {
return Tasks.call(mExecutor, Callable<Any> { // Retrieve the metadata as a File object.
val root: List<String> = folderId?.let { listOf(it) } ?: listOf("root")
val metadata = File()
.setParents(root)
.setMimeType(mimeType)
.setName(localFile.name)
val fileContent = FileContent(mimeType, localFile)
val fileMeta = mDriveService.files().create(
metadata,
fileContent
).execute()
val googleDriveFileHolder = GoogleDriveFileHolder()
googleDriveFileHolder.setId(fileMeta.id)
googleDriveFileHolder.setName(fileMeta.name)
googleDriveFileHolder
})
}
There is a answer in js here but I dont understand how to do it inside my function. Please help.

Related

How to prevent Ktor Client from encoding url parameters?

I am trying to create an android app with kotlin, this app need to have a mini download manager as I will need to download files from 100MB to 8GB and user can pause and resume download later when the server supports the pause, searching I found the Ktor library and reading the documentation plus some videos on youtube, I managed to write a base code where I could download the files and make the process of stopping the download and keep going all right when one of mine tests gave error there are files whose url pattern is: http://server.com/files?file=/10/55/file.zip
The problem is that I put this link, but Ktor converts to http://server.com/files?file=%2F10%2F55%2Ffile.zip this generate an error response on the server, as I don't have access to the server to change this rule I need to send the right url without encoding. Does anyone know how to do this? Prevent Ktor from doing a URL_encode in the url parameters, I couldn't find anything in the documentation
My code is this:
ktor-client version 1.6.7
fun startDownload(url: String, auth: String = "", userAgentS: String = "", fileName: String = ""){
val client = HttpClient(CIO)
val path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val file = File.createTempFile("File", "index", path)
runBlocking {
client.get<HttpStatement>(url){
headers {
append(HttpHeaders.Authorization, auth)
append(HttpHeaders.UserAgent, userAgentS)
append(HttpHeaders.Range, "bytes=${file.length()}-")
}
}
.execute { httpResponse ->
val channel: ByteReadChannel = httpResponse.receive()
while (!channel.isClosedForRead) {
val packet = channel.readRemaining(DEFAULT_BUFFER_SIZE.toLong())
while (!packet.isEmpty) {
val bytes = packet.readBytes()
file.appendBytes(bytes)
println("Received ${(file.length())} bytes from ${httpResponse.contentLength()}")
}
}
val pathF = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS + "/${fileName}")
file.renameTo(pathF)
println("A file saved to ${file.path}")
}
}
}
Can anyone help me solve this problem with ktor, if there is no solution, can someone tell me another way to achieve the same goal? Need to be with Kotlin.
update 2022-02-17
Thanks to Aleksei Tirman's help I managed to solve the problem, thank you very much. And the base code looks like this:
fun startDownload(url: String, auth: String = "", userAgentS: String = "", fileName: String = ""){
val client = HttpClient(CIO)
val path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val file = File.createTempFile("File", "index", path)
runBlocking {
client.get<HttpStatement>(url){
url {
parameters.urlEncodingOption = UrlEncodingOption.NO_ENCODING
}
headers {
append(HttpHeaders.Authorization, auth)
append(HttpHeaders.UserAgent, userAgentS)
append(HttpHeaders.Range, "bytes=${file.length()}-")
}
}
.execute { httpResponse ->
val channel: ByteReadChannel = httpResponse.receive()
while (!channel.isClosedForRead) {
val packet = channel.readRemaining(DEFAULT_BUFFER_SIZE.toLong())
while (!packet.isEmpty) {
val bytes = packet.readBytes()
file.appendBytes(bytes)
println("Received ${(file.length())} bytes from ${httpResponse.contentLength()}")
}
}
val pathF = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS + "/${fileName}")
file.renameTo(pathF)
println("A file saved to ${file.path}")
}
}
}
You can disable query parameters encoding by assigning the UrlEncodingOption.NO_ENCODING value to the urlEncodingOption property of the ParametersBuilder. Here is an example:
val requestBuilder = HttpRequestBuilder()
requestBuilder.url {
protocol = URLProtocol.HTTP
host = "httpbin.org"
path("get")
parameters.urlEncodingOption = UrlEncodingOption.NO_ENCODING
parameters.append("file", "/10/55/file.zip")
}
val response = client.get<String>(requestBuilder)

Upload Image to Server using Multipart and Request Body in Android in Kotlin

I am stuck in between a strange issue of uploading image file to server. Although I did upload file several times before, but this time I don't understand what is the issue.
I get the file path of respective file but RequestBody returns null. Below I mentioned what library I'm using.
I am using kotlin, MultiPart and RequestBody for file upload.
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'
Below is my code which I wrote for file upload. In which you can see GalleryCameraUtility.getImageRequestBody(imageFile) returns null for file.
File path from mobile device /storage/emulated/0/DCIM/Screenshots/test_image.jpg
fun addNewCompany(companyName: String, email: String,imageFile: File, ownerName: String, address: String, companyDetails: String){
val companyNameBody: RequestBody = companyName.toRequestBody("text/plain".toMediaType())
val emailBody: RequestBody = email.toRequestBody("text/plain".toMediaType())
val fileData: RequestBody? = GalleryCameraUtility.getImageRequestBody(imageFile)
val ownerNameBody: RequestBody = ownerName.toRequestBody("text/plain".toMediaType())
val addressBody: RequestBody = address.toRequestBody("text/plain".toMediaType())
val userIdBody: RequestBody = PreferenceHelper.readUserIdPref(Constants.USER_ID).toString()
.toRequestBody("text/plain".toMediaType())
addCompanyRepo.addNewCompanyApi(companyNameBody, emailBody, fileData, ownerNameBody, addressBody, userIdBody)
}
class GalleryCameraUtility {
companion object{
fun getImageRequestBody(sourceFile: File) : RequestBody? {
var requestBody: RequestBody? = null
Thread {
val mimeType = getMimeType(sourceFile);
if (mimeType == null) {
Log.e("file error", "Not able to get mime type")
return#Thread
}
try {
requestBody = sourceFile.path.toRequestBody("multipart/form-data".toMediaTypeOrNull())
/*MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart(serverImageKey, uploadedFileName,sourceFile.asRequestBody(mimeType.toMediaTypeOrNull()))
.build()*/
} catch (ex: Exception) {
ex.printStackTrace()
Log.e("File upload", "failed")
}
}.start()
return requestBody;
}
// url = file path or whatever suitable URL you want.
private fun getMimeType(file: File): String? {
var type: String? = null
val extension = MimeTypeMap.getFileExtensionFromUrl(file.path)
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
}
return type
}
}
}
I spent so many hours on this but not able to find solution. Please help me out on this.

Store File To External Storage Not Working For Android 10 and above - Android Studio/Kotlin

My app has an extract button that takes the data from text view and paste it in a text file "Ledger.txt". It creates a folder in Mobile internal Storage Root Directory "WaterLedger" and place a Ledger.txt file in it and if the text file is already present it appends the text in the file. The code is only working till android 9 not above.
In Android 10 on pressing Extract button it asks "grant permission to write file in storage" but even if you press Yes it still wont create folder (WaterLerger) and paste/update data in Text File (Ledger.txt)
Here is the code
class WriteFile: AsyncTask<String, Int, String>() {
private val mFolder = "/WaterLedger"
lateinit var folder: File
internal var writeThis = "string to cacheApp.txt"
internal var cacheApptxt = "Ledger.txt"
override fun doInBackground(vararg writethis: String): String? {
val received = writethis[0]
if(received.isNotEmpty()){
writeThis = received
}
folder = File(Environment.getExternalStorageDirectory(),"$mFolder/")
if(!folder.exists() || folder.exists()){
folder.mkdir()
val readME = File(folder, cacheApptxt)
val file = File(readME.path)
val out: BufferedWriter
try {
out = BufferedWriter(FileWriter(file, true), 1024)
out.write("****Ledger Updated On Dated:$currentDate*****\n")
out.newLine()
out.write(writeThis)
out.newLine()
out.close()
Log.d("Output_Success", folder.path)
} catch (e: Exception) {
Log.d("Output_Exception", "$e")
}
}
return folder.path
}
// Driver Code
extract.setOnClickListener {
var pathToFileCreated = ""
val anRW = ReadandWrite().readAndwriteStorage(this, this)
if (anRW) {
pathToFileCreated = WriteFile().execute("$StringBuilder").get()
Log.d("pathToFileCreated", pathToFileCreated)
Toast.makeText(this,"File Saved",android.widget.Toast.LENGTH_LONG).show()
}
This will give you External Pictures directory URI (You can create your desirable directory into it):
private fun createTextURI(): Uri? {
val imageCollection = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
else
MediaStore.Video.Media.EXTERNAL_CONTENT_URI
val fileName = System.currentTimeMillis()
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "$fileName.txt")
put(MediaStore.MediaColumns.MIME_TYPE, "text/plain")
}
val finalURI = contentResolver.insert(imageCollection, contentValues)
resultUri = finalURI
return finalURI
}
Use this URI for file creation like this:
new File(finalURI.getPath());
And write into this file which you created above. ✌
Make sure you have WRITE_EXTERNAL_STORAGE permission.
Ref. Demo App

How to get callback in andorid after uploading of file is complete using Azure blob storage?

I'm uploading user's profile pic to azure server using Azure blob storage.
This is my code
fun uploadImage(path: String, fileInputStream: FileInputStream) =
viewModelScope.launch(Dispatchers.IO) {
try {
val storageAccount = CloudStorageAccount.parse(connectionString)
val bobClient = storageAccount.createCloudBlobClient()
val container = bobClient.getContainerReference(storageContainer)
val blob = container.getBlockBlobReference("$storageContainer.jpg")
val file = File(path)
blob.upload(fileInputStream, file.length() )
} catch (e: Exception) {
e.printStackTrace()
}
}
The code is working fine and the image is uploading, when I checked using the URL, but how can I get a callback on success or error of uploading, so that I can perform action on the basis of that.
How can I know when upload finishes or if any error occurred?

Downloading file and saving it to download folder using kotlin in Android

I am trying to download an apk file from the web server and store it in the download folder. I am using fuel library
Fuel.download("https://mypath/app.apk").destination {
response, url -> val dir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString()) File(dir, "abcd.apk")
}.progress {
readBytes, totalBytes -> val progress = readBytes.toFloat() / totalBytes.toFloat()
Log.d("log",progress.toString())
}.response {
req, res, result -> Log.d("log","download completed ")
Log.d("log",Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/abcd.apk")
}
I am getting bytesArray in response but the file is not saving to download folder. I have write_external_storage on my Manifest file. Please let me know what am I missing?
As you mentioned in comment that you are using targetSdkVersion as 23. Beginning with Android 6.0 (API level 23), if you set targetSdkVersion as 23 in your app you have to implement rumtime permission in your app.
To implement it please refer official documentation here Requesting Permissions at Run Time
fun storeImage(link: String) : String {
val policy: StrictMode.ThreadPolicy = StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy)
val cw = ContextWrapper(applicationContext)
val directory: File = cw.getDir("imageDir", Context.MODE_PRIVATE)
val pictureFile = File(directory, "backgroundImage.gif")
URL(link).openStream().use { input ->
FileOutputStream(pictureFile).use { output ->
input.copyTo(output)
Log.e("DD GIF", "storeImage: FILE SAVED" )
return "SAVED"
}
}
}
it is working for me.

Categories

Resources