How can an App write and read file in Documents folder? - android-studio

I wrote an App, in Kotlin with Android Studio that write some strings to a file.
All work, I can write and read inside the App, but I can't see the file looking in Documents folder.
How can I use the folder Documents as a storage space?
Thank you
These are the function I use:
fun saveTextFile(view: View, nomeFile: String, testo: String, contesto: Context){
var fileStream: FileOutputStream
try {
fileStream = contesto.openFileOutput(nomeFile, MODE_APPEND) // OK esegue append
fileStream.write(testo.toByteArray())
fileStream.close()
}catch (e: Exception){
e.printStackTrace()
}
}
fun readTextFile(view: View, nomeFile: String, contesto: Context): String{
var fileInputStream: FileInputStream? = null
fileInputStream = contesto.openFileInput(nomeFile)
var inputStreamReader: InputStreamReader = InputStreamReader(fileInputStream)
val bufferedReader: BufferedReader = BufferedReader(inputStreamReader)
val stringBuilder: StringBuilder = StringBuilder()
var text: String? = null
while ({ text = bufferedReader.readLine(); text }() != null) {
stringBuilder.append(text)
}
inputStreamReader.close();
return(stringBuilder.toString())
}
Thank you, Livio

For writing in Documents folder of your device , you just need to make use of MediaStore for the same. You can take input for this function anything that you want like String , bitmap , PdfDocument and other's too .
For Your UseCase you can do the following ,
Global Variable :
private var imageUri: Uri? = null
override suspend fun saveDocument(context : Context, text : String) {
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val date = System.currentTimeMillis()
val fileName = "$date.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}")
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
}
val imageUri = context.contentResolver.insert(collection, contentValues)
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "w").use { out -> out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
For Updating the already existing file , do the following . After creating file for the first time I have saved the imageUri in a global variable (If you want to store it permanently / or for a while you can use Jetpack Datastore / Shared Preference to save the same ):
suspend fun updateData(context: Context,text : String){
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val fileName = "test.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(
MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}"
)
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "wa").use { out ->
out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
For Reading the File , Do the following :
suspend fun read(context: Context, source: Uri): String = withContext(Dispatchers.IO) {
val resolver: ContentResolver = context.contentResolver
resolver.openInputStream(source)?.use { stream -> stream.readText() }
?: throw IllegalStateException("could not open $source")
}
private fun InputStream.readText(charset: Charset = Charsets.UTF_8): String =
readBytes().toString(charset)
This is how the final code looks like :
class MainActivity : AppCompatActivity() {
private lateinit var btn: Button
private var imageUri: Uri? = null
private lateinit var btn2: Button
private lateinit var btn3 : Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn = findViewById(R.id.btnAdd)
btn2 = findViewById(R.id.getText)
btn3 = findViewById(R.id.updateText)
btn.setOnClickListener {
lifecycleScope.launch {
saveDocument(applicationContext, "Original ")
}
}
btn3.setOnClickListener {
lifecycleScope.launch {
updateData(applicationContext,"Appended")
}
}
btn2.setOnClickListener {
lifecycleScope.launch {
imageUri?.let { it1 ->
val data = read(applicationContext, it1)
Toast.makeText(applicationContext, "The data is $data ", Toast.LENGTH_LONG)
.show()
}
}
}
}
suspend fun saveDocument(context: Context, text: String) {
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val date = System.currentTimeMillis()
val fileName = "test.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(
MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}"
)
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
imageUri = context.contentResolver.insert(collection, contentValues)
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "w").use { out ->
out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
suspend fun updateData(context: Context, text: String) {
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val fileName = "test.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(
MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}"
)
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "wa").use { out ->
out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
suspend fun read(context: Context, source: Uri): String = withContext(Dispatchers.IO) {
val resolver: ContentResolver = context.contentResolver
resolver.openInputStream(source)?.use { stream -> stream.readText() }
?: throw IllegalStateException("could not open $source")
}
private fun InputStream.readText(charset: Charset = Charsets.UTF_8): String =
readBytes().toString(charset)
I have three buttons . With the first I create a file , then the uri gets stored in the global variable . Then onClick of second button I add to the already existing file and then read the file using the third button using the same imageUri stored in the global variable
This is the demo for the same . Check when the buttons are being pressed and the output in the form of Toast at the bottom .

Related

Load image from firestore collection into LazyColumn in jetpack compose

My app has a navigation bar and in one navBarItem I have two tabs, I want to read images and their caption I have stored in my firebase firestore collection into a LazyColumn in one of the tabs.
Here is how my DataException and GalleryRepo class looks like
data class DataOrException<T, E : Exception> (
var data: T? = null,
var e: E? = null
)
#Singleton
class GalleryRepo #Inject constructor(
private val queryImageData: Query
) {
fun getImagesFromFirestore(): DataOrException<List<PQImageGallery>, Exception> {
val dataOrException = DataOrException<List<PQImageGallery>, Exception>()
try {
dataOrException.data = queryImageData.get()
.result.map { document -> document.toObject(PQImageGallery::class.java) }
} catch (e: FirebaseFirestoreException) {
dataOrException.e = e
}
return dataOrException
}
}
My data class
data class PQImageGallery (
var imageUrl: String? =null,
var caption: String? = null
)
ViewModels...
#HiltViewModel
class PQViewModel #Inject constructor(
private val repository: GalleryRepo
): ViewModel() {
var loading = mutableStateOf(false)
val data: MutableState<DataOrException<List<PQImageGallery>, Exception>> = mutableStateOf(
DataOrException(
listOf(),
Exception("")
)
)
init {
getGalleryCollection()
}
private fun getGalleryCollection() {
viewModelScope.launch {
loading.value = true
data.value = repository.getImagesFromFirestore()
loading.value = false
}
}
}
#Module
#InstallIn(SingletonComponent::class)
object RemoteImageModel {
#Provides
#Singleton
fun loadImagesInCollection() = FirebaseFirestore.getInstance()
.collection(IMAGE_COLLECTION)
}
My GalleryCollection composable file
#Composable
fun GalleryCollection(dataOrException: DataOrException<List<PQImageGallery>, Exception>) {
val images = dataOrException.data
images?.let {
LazyColumn {
items(items = images) { product ->
GalleryCard(pqImageGallery = product)
}
}
}
val e = dataOrException.e
e?.let {
Text(
text = e.message!!,
modifier = Modifier.padding(16.dp)
)
}
}
#Composable
fun GalleryCard(
pqImageGallery: PQImageGallery,
) {
Card(...) {
Box(modifier = Modifier
.fillMaxSize()
) {
pqImageGallery.imageUrl?.let { imageUrl ->
CoilImage(
data = imageUrl,
....
)
}
pqImageGallery.caption?.let { caption ->
Text(
text = caption,
...
)
}
}
}
}
My navBarItem that contains the two tabs called Home
class Home : ComponentActivity() {
private val viewModel: PQViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HomeScreen(viewModel)
}
}
}
#Composable
fun HomeScreen(
viewModel: PQViewModel
) {
val dataOrException = viewModel.data.value
val navController = rememberNavController()
val currentBackStack by navController.currentBackStackEntryAsState()
val currentDestination = currentBackStack?.destination
val currentScreen =
HomeTabRowScreens.find { it.route == currentDestination?.route } ?: GalleryView
Scaffold(
topBar = {
HomeScreenTabRow(
allScreens = HomeTabRowScreens,
onTabSelected = { newScreen ->
navController
.navigateSingleTopTo(newScreen.route)
},
currentScreen = currentScreen,
)
}
) { innerPadding ->
NavHost(
navController = navController,
startDestination = GalleryView.route,
modifier = Modifier.padding(innerPadding)
) {
composable(route = GalleryView.route) {
// GalleryTabScreen()
GalleryCollection(dataOrException = dataOrException)
}
composable(route = VirtualTourView.route) {
VirtualTourScreen()
}
}
}
}
fun NavHostController.navigateSingleTopTo(route: String) =
this.navigate(route) {
popUpTo(
this#navigateSingleTopTo.graph.findStartDestination().id
) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
Finally calling the Home class in my main screen(MainActivity)
NavHost(
..
) {
composable(NAV_HOME) {
Home()
}
composable(..) { ...}
}
The issue is when I run the app the tabs in the Home navBar doesn't show at all talk of loading the images from the firestore collection.
Also, is there another way to instantiate a viewModel without having to create a class that extends ComponentActiviy?
If there's another way to achieve this kindly share.

How to get original image size after capture

How do I get original size image after capture in Kotlin so that I can send the original size photo to a server? Here is my code:
DeliveryPresenter:
import com.stevenmorris.delivery.util.ImageStorageUtils
override fun capturePhoto() {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
activity.startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
}
override fun onCapturePhotoResults(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
val imageBitmap = data?.extras?.get("data") as Bitmap
view.onPhotoCaptured(imageBitmap);
}
}
DeliveryActivity:
private lateinit var imgPhoto: AppCompatImageView
private var photo: Bitmap? = null;
override fun onPhotoCaptured(photo: Bitmap) {
this.photo = photo
imgPhoto.setImageBitmap(photo)
}
ImageStorageUtils.kt
object ImageStorageUtils {
val TAG = javaClass.simpleName
fun savePhoto(activity: Activity,photo: Bitmap, fileName: String): Boolean {
val root = activity.filesDir.absolutePath;
val myDir = File("$root/photos")
myDir.mkdirs()
val file = File(myDir, fileName)
if (file.exists()) file.delete()
try {
val out = FileOutputStream(file)
photo.compress(Bitmap.CompressFormat.JPEG, 100, out)
out.flush()
out.close()
return true
} catch (e: Exception) {
AppLogger.e(TAG, e.message, e)
return false
}
}
}
Initial thoughts were can I save the photo without compressing it? or is there a way to save the photo in its original size directly?

How to append data in a file in Android?

I have a function that can write a file in Android file system, but I want to append data.
My function create a new file every time I call it.
How can I modify to have the data appended to the file?
Thank you
fun saveDocument(context : Context, fileName: String, text : String): Boolean {
try {
val collection = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(Environment.DIRECTORY_DOCUMENTS, context.getString(R.string.app_name)) // subfolder with name of the App
//val date = System.currentTimeMillis() // current datetime
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
//put(MediaStore.MediaColumns.MIME_TYPE, "application/txt")
//put(MediaStore.MediaColumns.DATE_ADDED, date)
//put(MediaStore.MediaColumns.DATE_MODIFIED, date)
put(MediaStore.MediaColumns.RELATIVE_PATH, "$dirDest${File.separator}")
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
val imageUri = context.contentResolver.insert(collection, contentValues)
imageUri?.let { uri ->
//context.contentResolver.openOutputStream(uri, "w").use { out -> out?.write(text.toByteArray()) } // write
context.contentResolver.openOutputStream(uri, "wa").use { out -> out?.write(text.toByteArray()) } // append
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
return(true)
}
catch (e: FileNotFoundException) {
return(false)
}
}

Kotlin string replace function not working for me?

Hello everyone please help me i am try to modify link but it's not working. it's working on java but recently i convert java to kotlin and getting this error.
am trying to change my link http://www.offertoro.com/click_track/api?offer_id=419393&pub_id=14&pub_app_id=5&USER_ID=[USER_ID]&GAID=[your_GAID] in [USER_ID] with current login user email but getting error.
Check Screenshot
Screenshot
Error
None of the following functions can be called with the arguments supplied.
CharSequence.replace(Regex, String) defined in kotlin.text
String.replace(String, String, Boolean = ...) defined in kotlin.text
My code
fun modifyOfferLink() {
val id = mAuth!!.currentUser!!.email
// Modifying Offer Link Acording to Offer Partner
when (partner) {
"ogads" -> Finallink = link + "&aff_sub5=" + mAuth!!.currentUser!!.email
"offertoro" -> Finallink = link.replace("[USER_ID]", mAuth!!.currentUser!!.email)
"none" -> {
Finallink = link!!.replace("[USER_ID]", mAuth!!.currentUser!!.email)
}
else -> Finallink = link.replace("[USER_ID]", mAuth!!.currentUser!!.email)
}
}
OfferActivity.kt
package com.sgamer.creditsk.Activity
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.Window
import android.view.WindowManager
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.google.firebase.auth.FirebaseAuth
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.loopj.android.http.AsyncHttpClient
import com.loopj.android.http.AsyncHttpResponseHandler
import com.loopj.android.http.RequestParams
import com.sgamer.creditsk.Activity.AndyConstants.ServiceType
import com.sgamer.creditsk.Activity.OfferDetailsActivity
import com.sgamer.creditsk.R
import com.sgamer.creditsk.Utils.*
import cz.msebera.android.httpclient.Header
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
class OfferDetailsActivity constructor() : AppCompatActivity() {
var Finallink: String? = null
var package_id: String? = null
var uniq_id: String? = null
var offerid: String? = null
var app_name: String? = null
var description: String? = null
var icon_url: String? = null
var bg_image_url: String? = null
var amount: String? = null
var OriginalAmount: String? = null
var link: String? = null
var partner: String? = null
var insTitle: String? = null
var first_text: String? = null
var second_text: String? = null
var third_text: String? = null
var fourth_text: String? = null
var webview: Boolean? = null
var ClickId: String? = null
var ctx: OfferDetailsActivity? = null
var later: TextView? = null
var status_image: ImageView? = null
var mAuth: FirebaseAuth? = null
private val bannerAdManager: BannerAdManager_SK? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_offer_details)
val toolbar: Toolbar = findViewById<View>(R.id.toolbar) as Toolbar
val adContainer: LinearLayout = findViewById<View>(R.id.adView) as LinearLayout
setSupportActionBar(toolbar)
val bannerAdManager_SK: BannerAdManager_SK = BannerAdManager_SK(this#OfferDetailsActivity, adContainer)
bannerAdManager_SK.BannerAds()
ctx = this
mAuth = FirebaseAuth.getInstance()
getSupportActionBar()!!.setTitle(R.string.offer_details)
getSupportActionBar()!!.setDisplayHomeAsUpEnabled(true)
getSupportActionBar()!!.setBackgroundDrawable(ColorDrawable(getResources().getColor(android.R.color.transparent)))
getSupportActionBar()!!.setElevation(0f)
if (Build.VERSION.SDK_INT >= 21) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
}
changeStatusBarColor()
initViews()
modifyOfferLink()
}
private fun changeStatusBarColor() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val window: Window = getWindow()
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.setStatusBarColor(Color.TRANSPARENT)
}
}
fun initViews() {
val title: TextView = findViewById(R.id.title)
val desc: TextView = findViewById(R.id.description)
val instructionsTitle: TextView = findViewById(R.id.instructions)
val first: TextView = findViewById(R.id.first)
val second: TextView = findViewById(R.id.second)
val third: TextView = findViewById(R.id.third)
val fourth: TextView = findViewById(R.id.fourth)
val des: TextView = findViewById(R.id.des)
val complete_button: TextView = findViewById(R.id.complete_button)
val button: TextView = findViewById(R.id.button)
later = findViewById(R.id.later)
val comSpace: LinearLayout = findViewById(R.id.comSpace)
val offer_icon: ImageView = findViewById(R.id.offer_icon)
val bg_image: ImageView = findViewById(R.id.bg_image)
status_image = findViewById(R.id.status_image)
uniq_id = getIntent().getStringExtra("uniq_id")
offerid = getIntent().getStringExtra("offerid")
app_name = getIntent().getStringExtra("app_name")
package_id = getIntent().getStringExtra("package_id")
description = getIntent().getStringExtra("description")
icon_url = getIntent().getStringExtra("icon_url")
bg_image_url = getIntent().getStringExtra("bg_image_url")
amount = getIntent().getStringExtra("amount")
OriginalAmount = getIntent().getStringExtra("OriginalAmount")
link = getIntent().getStringExtra("link")
partner = getIntent().getStringExtra("partner")
first_text = getIntent().getStringExtra("first_text")
insTitle = getIntent().getStringExtra("instructionsTitle")
second_text = getIntent().getStringExtra("second_text")
third_text = getIntent().getStringExtra("third_text")
fourth_text = getIntent().getStringExtra("fourth_text")
webview = getIntent().getBooleanExtra("webview", false)
if (getIntent().hasExtra("description")) {
des.setText(getIntent().getStringExtra("description"))
} else {
des.setText(getIntent().getStringExtra("description"))
}
title.setText(app_name)
desc.setText(getString(R.string.earn) + " " + amount + " " + getString(R.string.app_currency) + " " + getString(R.string.on_this_offer))
Glide.with(this).load(icon_url)
.apply(RequestOptions().placeholder(R.drawable.placeholder_image).error(R.drawable.placeholder_image))
.into(offer_icon)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
comSpace.setElevation(20f)
}
instructionsTitle.setText(insTitle)
first.setText(first_text)
second.setText(second_text)
third.setText(third_text)
fourth.setText(fourth_text)
complete_button.setText(getResources().getString(R.string.complete_offer))
if (!bg_image_url!!.isEmpty()) {
Glide.with(this).load(bg_image_url).into(bg_image)
} else {
}
// On click Listners
later!!.setOnClickListener(object : View.OnClickListener {
public override fun onClick(view: View) {
finish()
}
})
complete_button.setOnClickListener(object : View.OnClickListener {
public override fun onClick(view: View) {
if (!App.isVPNConnected()) {
addoffer(amount, app_name + " Offer Credit", offerid)
}
AppUtils.parse(this#OfferDetailsActivity, Finallink)
}
})
button.setOnClickListener(object : View.OnClickListener {
public override fun onClick(view: View) {
val launchIntent: Intent? = getPackageManager().getLaunchIntentForPackage((package_id)!!)
startActivity(launchIntent)
}
})
isAppExist
if (isAppExist) {
complete_button.setVisibility(View.GONE)
button.setVisibility(View.VISIBLE)
} else {
button.setVisibility(View.GONE)
complete_button.setVisibility(View.VISIBLE)
}
}
fun addoffer(points: String?, Activity: String?, offerid: String?) {
val client: AsyncHttpClient = AsyncHttpClient()
val params: RequestParams = RequestParams()
val jsObj: JsonObject = Gson().toJsonTree(API()) as JsonObject
jsObj.addProperty("method_name", "user_offeradd")
jsObj.addProperty("offer_id", offerid)
jsObj.addProperty("email", mAuth!!.getCurrentUser()!!.getEmail())
jsObj.addProperty("points", points)
jsObj.addProperty("firebase_id", mAuth!!.getCurrentUser()!!.getUid())
jsObj.addProperty("Activity", Activity)
params.put("data", API.toBase64(jsObj.toString()))
client.post(Javaaescipher.decrypt(), params, object : AsyncHttpResponseHandler() {
public override fun onSuccess(statusCode: Int, headers: Array<Header>, responseBody: ByteArray) {
Log.d("Response", String(responseBody))
val res: String = String(responseBody)
try {
val jsonObject: JSONObject = JSONObject(res)
val jsonArray: JSONArray = jsonObject.getJSONArray("ANDROID_REWARDS_APP")
for (i in 0 until jsonArray.length()) {
val `object`: JSONObject = jsonArray.getJSONObject(i)
val success: String = `object`.getString("success")
val msg: String = `object`.getString("msg")
if ((success == "1")) {
// Toast.makeText(OfferDetailsActivity.this, msg, Toast.LENGTH_LONG).show();
} else {
// Toast.makeText(OfferDetailsActivity.this, msg, Toast.LENGTH_LONG).show();
}
}
} catch (e: JSONException) {
e.printStackTrace()
}
}
public override fun onFailure(statusCode: Int, headers: Array<Header>, responseBody: ByteArray, error: Throwable) {
Log.d("error", error.toString())
}
})
}
private val isAppExist: Boolean
private get() {
val pm: PackageManager = getPackageManager()
try {
val info: PackageInfo = pm.getPackageInfo((package_id)!!, PackageManager.GET_META_DATA)
} catch (e: PackageManager.NameNotFoundException) {
return false
}
return true
}
fun modifyOfferLink() {
val id = mAuth!!.currentUser!!.email
// Modifying Offer Link Acording to Offer Partner
when (partner) {
"ogads" -> Finallink = link + "&aff_sub5=" + mAuth!!.currentUser!!.email
"offertoro" -> Finallink = link!!.replace("[USER_ID]", mAuth!!.currentUser!!.email)
"none" -> {
Finallink = link!!.replace("[USER_ID]", mAuth!!.currentUser!!.email)
}
else -> Finallink = link!!.replace("[USER_ID]", mAuth!!.currentUser!!.email)
}
}
}
It is likely there is no sub-string that is exactly [USER_ID]. Are you sure is it not ["USER_ID"] ?
Can you print the value of link before you call the replace. This may let us and you see the problem.

how to fix conversion error when converting from java to kotlin

I am a student, new to kotlin, so I am converting java codes to kotlin to learn and see how it works, but I didnt understand what the error says.
private val _songs = ArrayList<SongInfo>()
internal lateinit var recyclerView: RecyclerView
internal lateinit var seekBar: SeekBar
internal lateinit var songAdapter: SongAdapter
internal var mediaPlayer: MediaPlayer? = null
private val myHandler = Handler()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView = findViewById(R.id.recyclerView) as RecyclerView
seekBar = findViewById(R.id.seekBar) as SeekBar
songAdapter = SongAdapter(this, _songs)
recyclerView.adapter = songAdapter
val linearLayoutManager = LinearLayoutManager(this)
val dividerItemDecoration = DividerItemDecoration(recyclerView.context,
linearLayoutManager.orientation)
recyclerView.layoutManager = linearLayoutManager
recyclerView.addItemDecoration(dividerItemDecoration)
songAdapter.setOnItemClickListener { b, view, obj, position ->
if (b.text == "Stop") {
mediaPlayer!!.stop()
mediaPlayer!!.reset()
mediaPlayer!!.release()
mediaPlayer = null
b.text = "Play"
} else {
val runnable = Runnable {
try {
mediaPlayer = MediaPlayer()
mediaPlayer!!.setDataSource(obj.songUrl)
mediaPlayer!!.prepareAsync()
mediaPlayer!!.setOnPreparedListener { mp ->
mp.start()
seekBar.progress = 0
seekBar.max = mediaPlayer!!.duration
Log.d("Prog", "run: " + mediaPlayer!!.duration)
}
b.text = "Stop"
} catch (e: Exception) {
}
}
myHandler.postDelayed(runnable, 100)
}
}
checkUserPermission()
val t = runThread()
t.start()
}
inner class runThread : Thread() {
override fun run() {
while (true) {
try {
Thread.sleep(1000)
} catch (e: InterruptedException) {
e.printStackTrace()
}
Log.d("Runwa", "run: " + 1)
if (mediaPlayer != null) {
seekBar.post { seekBar.progress = mediaPlayer!!.currentPosition }
Log.d("Runwa", "run: " + mediaPlayer!!.currentPosition)
}
}
}
}
private fun checkUserPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 123)
return
}
}
loadSongs()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
123 -> if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
loadSongs()
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show()
checkUserPermission()
}
else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
}
private fun loadSongs() {
val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
val selection = MediaStore.Audio.Media.IS_MUSIC + "!=0"
val cursor = contentResolver.query(uri, null, selection, null, null)
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
val name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME))
val artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST))
val url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))
val s = SongInfo(name, artist, url)
_songs.add(s)
} while (cursor.moveToNext())
}
cursor.close()
songAdapter = SongAdapter(this#MainActivity, _songs)
}
}
}
This is the error:
"Error:(46, 44) Type mismatch: inferred type is (???, ???, ???, ???)
-> Any but SongAdapter.OnItemClickListener was expected Error:(46, 46) Cannot infer a type for this parameter. Please specify it explicitly."
Batch conversion to Kotlin is not the best way to learn the language. I suggest you to re-implement your Android component in Kotlin manually, to get the feeling of language.
The error you see says: "I can not understand how this lambda with 4 parameters can be an instance of SongAdapter.OnItemClickListener, please help". You can try anonymous class in this place.

Resources