In kotlin, how to recieve data class in bundle with parcelable? - kotlin

Send bundle from itemClickListener of Recyclerview in Activity like this
val bundle = Bundle()
bundle.putParcelableArrayList("myPlace", ArrayList<MyPlace>(myPlace))
ScheduleListFragment().arguments = bundle
Log.d("번들",bundle.toString())
finish()
and receive bundle in fragment like this
val bundle = arguments?.getParcelableArrayList<MyPlace>("myPlace")
if(bundle != null){
val yourPlace = requireArguments().getParcelableArrayList<MyPlace>("myPlace")
Log.d("마이", yourPlace.toString())
}
It says bundle is null...

Related

Pass synched Realm to other Activity

When I try to access the synched Realm from e.g. Main Activity I always get the error lateinit var not initialised.
I can successful open a database on the device and also the synched Database. But because the open of the synched Database must be in "run blocking" I don't know how to access "synchedRealm" then. Can't pass it to Main Activity.
I am sure its kind of fundamental knowledge I don't get out of the Kotlin/Realm documentation because English is not my primary language.
Thank you for your help!!!
In another Activity: MyApp:
....
runBlocking {
// Neuen User Registrieren
// app.emailPasswordAuth.registerUser(email, pw)
// once registered, you can log in with the user credentials
val appid: String = "MYAppId"
val apikey: String = "MyApiKey"
val app: App = App.create(
AppConfiguration.Builder(appid)
.log(LogLevel.ALL)
.build()
)
val user_api = app.login(io.realm.kotlin.mongodb.Credentials.apiKey(apikey))
val config = SyncConfiguration.Builder(
user_api,
setOf(MyClass::class)
)
.initialSubscriptions { realm ->
add(
realm.query<PersonCollection>(
"MyField == $0",
"Mustermann"
),
"subscription name"
)
}
.build()
val realmSynced = Realm.open(config)
}
I tried also the above code in an object{} or the runblocking{} in an init{} block and dozend other things
In Mainactivity:
lateinit var realm:Realm
lateinit var realmSynched:Realm
...
realm=MyApp.Databaseobject.realm //Works for Database on device
realmSynched= ???? //How to initialise this ???

How do I use ViewHolder to get a reference to items in the RecyclerView?

I am working with the LeDeviceListAdapter class in Android Studio. Specifically, I don't know how to call the ViewHolder for my RecyclerView in the getView function of this class.
override fun getView(i: Int, view: View?, viewGroup: ViewGroup?): View? {
var view: View? = view
val viewHolder: ViewHolder
// General ListView optimization code.
if (view == null) {
view = mInflator.inflate(R.layout.listitem_device, null)
viewHolder = ItemAdapter.ItemViewHolder(view)
viewHolder.device_name = view.findViewById(R.id.device_address) as TextView
viewHolder.device_address = view.findViewById(R.id.device_name) as TextView
view.setTag(viewHolder)
} else {
viewHolder = view.tag as ViewHolder
}
val device = mLeDevices[i]
val deviceName = device.name
if (deviceName != null && deviceName.length > 0) viewHolder.deviceName.setText(deviceName) else viewHolder.deviceName.setText(
R.string.unknown_device
)
viewHolder.deviceAddress.setText(device.address)
return view
}
I am getting an error where it says...
viewHolder = ViewHolder( )
The error says I can't instantiate an abstract class. I have tried to extend the ViewHolder class, and I have tried to access the ViewHolder through the RecyclerView.
How can I access the ViewHolder from this class?
Let me know if you need to see more of my project or hear more specifics.
UPDATE: I moved these two lines...
view = mInflator.inflate(R.layout.listitem_device, null)
viewHolder = ItemAdapter.ItemViewHolder(view)
...to the top of the function, and it resolved my problem with the ViewHolder.
For some reason, though, the line that says...
if (deviceName != null && deviceName.length > 0)
viewHolder.deviceName.setText(deviceName)
...cannot access the deviceName property of the ViewHolder the same way that I could above.

Why are these log statements not printing?

I'm building an object detection application (in Kotlin, for Android). The application uses CameraX to build a camera preview and Google ML to provide machine learning expertise. Just for reference; I used this CameraX documentation and this this Google ML Kit documentation.
I'm currently attempting to print Log.d("TAG", "onSuccess" + it.size) to my IDE console in order to determine if .addonSuccessListener is actually running. If it does, it should print something along the lines of onSuccess1. However, this isn't the case. Infact, it isn't even printing the Log statement from the .addOnFailureListener either, which really confuses me as I'm not even entirely sure the objectDetector code is even running. What really puzzles me is that I have relatively completed the same project in Java and have not faced this issue.
I did have someone point out that within my YourImageAnalyzer.kt class, if mediaImage is null, then I won't see anything logging. However, upon my own debugging (this is actually my very first time debugging), I was unable to find out if my first sentence of this paragraph is true or not. I suppose this issue may provide a lead into how I'll resolve this issue, and also learn how to properly debug.
Here is my YourImageAnalyzer.kt class, and I will also add the code for my MainActivity.kt class below as well.
YourImageAnalyzer.kt
private class YourImageAnalyzer : ImageAnalysis.Analyzer {
override fun analyze(imageProxy: ImageProxy) {
val mediaImage = imageProxy.image
if (mediaImage != null) {
val image =
InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
val localModel = LocalModel.Builder()
.setAssetFilePath("mobilenet_v1_0.75_192_quantized_1_metadata_1.tflite")
.build()
val customObjectDetectorOptions =
CustomObjectDetectorOptions.Builder(localModel)
.setDetectorMode(CustomObjectDetectorOptions.STREAM_MODE)
.enableClassification()
.setClassificationConfidenceThreshold(0.5f)
.setMaxPerObjectLabelCount(3)
.build()
val objectDetector =
ObjectDetection.getClient(customObjectDetectorOptions)
objectDetector //Here is where the issue stems, with the following listeners
.process(image)
.addOnSuccessListener {
Log.i("TAG", "onSuccess" + it.size)
for (detectedObjects in it)
{
val boundingBox = detectedObjects.boundingBox
val trackingId = detectedObjects.trackingId
for (label in detectedObjects.labels) {
val text = label.text
val index = label.index
val confidence = label.confidence
}
}
}
.addOnFailureListener { e -> Log.e("TAG", e.getLocalizedMessage()) }
.addOnCompleteListener { it -> imageProxy.close() }
}
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
override fun onCreate(savedInstanceState: Bundle?) {
cameraProviderFuture = ProcessCameraProvider.getInstance(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
cameraProviderFuture.addListener(Runnable {
val cameraProvider = cameraProviderFuture.get()
bindPreview(cameraProvider)
}, ContextCompat.getMainExecutor(this))
}
fun bindPreview(cameraProvider: ProcessCameraProvider) {
val previewView = findViewById<PreviewView>(R.id.previewView)
var preview : Preview = Preview.Builder()
.build()
var cameraSelector : CameraSelector = CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build()
preview.setSurfaceProvider(previewView.surfaceProvider)
var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview)
}
}
You are not binding your ImageAnalysis use case. Something in the line of:
val imageAnalysis = ImageAnalysis.Builder()
.setTargetResolution(Size(1280, 720))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
.build()
and then;
imageAnalysis.setAnalyzer(executor, YourImageAnalyzer())
cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageAnalysis, preview)
Also a suggestion as a bonus:
You should get your LocalModel.Builder() out of analyze as this is called each time an image arrives. You do not need to execute this code piece each time as it will make your analysis slower.
So move this code:
val localModel = LocalModel.Builder()
.setAssetFilePath("mobilenet_v1_0.75_192_quantized_1_metadata_1.tflite")
.build()
to just below of the class private class YourImageAnalyzer : ImageAnalysis.Analyzer {.

How to get KtClass from PsiElement or VirtualFile?

I want to make an plugin that generate some template code for some specific kotlin files. Now I need to get KtClass from PsiElement or VirtualFile. I tried some code as below, but it's not working.
val psiFile = e.getData(CommonDataKeys.PSI_FILE)
psiFile ?: return
val editor = e.getData(CommonDataKeys.EDITOR)
editor ?: return
println(psiFile.name)
val pe = psiFile.findElementAt(editor.caretModel.offset)
if (pe != null) {
println(pe.text)
} else {
println("PE is null")
}
val kt = PsiTreeUtil.getParentOfType(pe, KtClass::class.java)
kt?.run {
println(this.text)
}
PS: I found that there are 2 PsiTreeUtils, one from org.jetbrains.kotlin.com.intellij.psi.util package, and another from com.intellij.psi.util, I don't know which one should I use
A PsiFile might contain zero or more KtClasss. You can get them all by doing this:
val classes = psiFile.getChildrenOfType<KtClass>().asList()

How to pass the values from activity to another activity

As I'm learning Kotlin for Android development, I'm now trying the basic programs like hello world and how to navigate from one activity to another activity, there is no issue with this.
When I move from one activity to another, it works fine, but I do not know how to pass the values between the activities.
I tried to set the values in one activity and retrieved them in another activity it does not work.
Please see the code snippet below
This is my main activity where I take the username and password from edit text and setting to the intent:
class MainActivity : AppCompatActivity() {
val userName = null
val password = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
val intent = Intent(this#MainActivity,SecondActivity::class.java);
var userName = username.textø
var password = password_field.text
intent.putExtra("Username", userName)
intent.putExtra("Password", password)
startActivity(intent);
}
}
}
This is my second activity where I have to receive values from the main activity
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
var strUser: String = intent.getStringExtra("Username")
var strPassword: String = intent.getStringExtra("Password")
user_name.setText("Seelan")
passwor_print.setText("Seelan")
}
}
Please guide me on how to do this, whether I have some other way to do this in Kotlin if not by intent.
Send value from HomeActivity
val intent = Intent(this#HomeActivity,ProfileActivity::class.java)
intent.putExtra("Username","John Doe")
startActivity(intent)
Get values in ProfileActivity
val profileName=intent.getStringExtra("Username")
I'm on mobile, you must test by yourself.
Try to make a CharSequence to a String in MainActivity , you have put a CharSequence rather than a String, for example:
var userName = username.text.toString()
var password = password_field.text.toString()
In Kotlin, you can pass the data simply by using the Intents. You can directly put your data in intent or you can write those data in bundle and send that bundle to another activity using the intent.
val intent = Intent(this#HomeActivity,ProfileActivity::class.java);
intent.putExtra("profileName", "John Doe")
var b = Bundle()
b.putBoolean("isActive", true)
intent.putExtras(b)
startActivity(intent);
You can simply use the intents and bundle to send data from one activity to another activity.
val intent = Intent(this#OneActivity,TwoActivity::class.java);
intent.putExtra("username", userName)
startActivity(intent);
//On Click on Button
var but = findViewById<Button>(R.id.buttionActivity_two) as Button
but.setOnClickListener {
//Define intent
var intent = Intent(applicationContext,MainActivity::class.java)
// Here "first" is key and 123 is value
intent.putExtra("first",123)
startActivity(intent)
}
}
// If Get In Into Other Activity
var Intent1: Intent
Intent1= getIntent()
//Here first is key and 0 is default value
var obj :Int = Intent1.getIntExtra("first",0);
Log.d("mytag","VAlue is==>"+obj)
first you should do this,
var userName = username.text.toString()
var password = password_field.text.toString()
Add Anko dependency.
implementation "org.jetbrains.anko:anko:0.10.4"
information passing inside MainActivity() is like
startActivity<SecondActivity>("Username" to userName,"Password" to password )
get information from SecondActivity() is,
val profileName=intent.getStringExtra("Username")
You can just access the value without using extras or intent. Simply use companion object in MainActivity:
companion object{
val userName: String = String()
val password: String = String()
}
In SecondActivity:
var strUser: String = MainActivity.username
var strPassword: String = MainActivity.password
And you can access the values from multiple activities easily.
Send data
val Name=findViewById<EditText>(R.id.editTextTextPersonName)
val Name2=findViewById<EditText>(R.id.editTextTextPersonName2)
val name=Name.text.toString()
val age=Name2.text.toString()
val intent1=Intent(this,Second::class.java).also {
it.putExtra("Username",name)
it.putExtra("Age",age)
startActivity(it);
}
Receive data
val name=intent.getStringExtra ("Username")
val age = intent.getStringExtra("Age")
val textView5=findViewById<TextView>(R.id.textView).apply {
text= "Name = $name"
}
val textView6=findViewById<TextView>(R.id.textView2).apply {
text= "Age = $age"
}