Multiple results from activity to fragment - android

I've got a question about results/callback from activities to fragments.
Until now I have a fragment which calls a camera activity to scan QR Codes. So I start the activity from the fragment with startActivityForResult. If a QR Code is successfully scanned I get a callback Intent which is handled in onActivityResult.
This works perfectly.
Now I want to handle multiple scanns. In detail that means, that every successfully scan should call the onActivityResult function without closing the activity. The problem which I got at this point is, that onActivityResult is only called if I call finish() in the camera activity.
So my question is, how can I call onActivityResult multiple times with or without calling finish() but without closing the activity? Or is there another way to handle callbacks from activities to fragments?
This is my fragment code:
class ScanFragment : Fragment() {
private val CHECKIN_CODE = 0
private val CHECKOUT_CODE = 1
companion object {
fun newInstance(): LeadScanFragment = LeadScanFragment()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_lead_scan, container, false)
view.checkin.setOnClickListener {view ->
val intent = Intent(activity, CodeScannerActivity::class.java)
startActivityForResult(intent, CHECKIN_CODE)
}
view.checkout.setOnClickListener {view ->
val intent = Intent(activity, CodeScannerActivity::class.java)
startActivityForResult(intent, CHECKOUT_CODE)
}
return view
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == CHECKIN_CODE) {
if (resultCode == Activity.RESULT_OK) {
val returnString = data!!.getStringExtra("hash")
Log.d("scaned in", returnString)
}
}
if (requestCode == CHECKOUT_CODE) {
if (resultCode == Activity.RESULT_OK) {
val returnString = data!!.getStringExtra("hash")
Log.d("scaned out", returnString)
}
}
}
}
And this is the camera activity code:
class CodeScannerActivity : AppCompatActivity() {
private val requestCodeCameraPermission = 1001
private lateinit var cameraSource: CameraSource
private lateinit var detector: BarcodeDetector
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_code_scanner)
if (ContextCompat.checkSelfPermission(this#CodeScannerActivity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
askForCameraPermission()
} else {
setup()
}
}
private fun setup() {
detector = BarcodeDetector.Builder(this#CodeScannerActivity).build()
cameraSource = CameraSource.Builder(this#CodeScannerActivity, detector).setAutoFocusEnabled(true).build()
cameraSurfaceView.holder.addCallback(surfaceCallback)
detector.setProcessor(processor)
}
private fun askForCameraPermission() {
ActivityCompat.requestPermissions(this#CodeScannerActivity, arrayOf(Manifest.permission.CAMERA), requestCodeCameraPermission)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode == requestCodeCameraPermission && grantResults.isNotEmpty()) {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setup()
} else {
Toast.makeText(applicationContext, "Permission denied!", Toast.LENGTH_SHORT).show()
}
}
}
private val surfaceCallback = object : SurfaceHolder.Callback {
override fun surfaceCreated(surfaceHolder: SurfaceHolder?) {
try {
cameraSource.start(surfaceHolder)
} catch (exception: Exception) {
Toast.makeText(applicationContext, "Something went wrong", Toast.LENGTH_SHORT).show()
}
}
override fun surfaceChanged(p0: SurfaceHolder?, p1: Int, p2: Int, p3: Int) {
}
override fun surfaceDestroyed(p0: SurfaceHolder?) {
cameraSource.stop()
}
}
private val processor = object : Detector.Processor<Barcode> {
override fun release() {
}
override fun receiveDetections(detections: Detector.Detections<Barcode>?) {
val intent = Intent()
if(detections != null && detections.detectedItems.isNotEmpty()) {
val qrCodes: SparseArray<Barcode> = detections.detectedItems
val code = qrCodes.valueAt(0)
intent.putExtra("hash", code.displayValue)
setResult(Activity.RESULT_OK, intent)
finish()
} else {
setResult(Activity.RESULT_CANCELED, intent)
finish()
}
}
}
}
receiveDetections inside the processor in the lower area of the camera activity code is where the callback Intent is send back to onActivityResult.

You could have the scanner Activity send a local broadcast Intent to forward "results" to the calling Fragment. The Fragment (or its hosting Activity) should set a listener to listen for the broadcast "results". In this way you could perform multiple scans and send each result back to the underlying Activity.

Related

Kotlin cast one AppCompatActivity into another one in Android

world! I am new to Android development. I am creating an app and I have a question, how can I cast one AppCompatActvity class into another?
This is my sample code:
class UploadActivity : AppCompatActivity() {
var sm = FirebaseStorageManager()
private var filePath: Uri? = null
private val btnSelectImage: AppCompatButton by lazy {
findViewById(R.id.select)
}
private val btnUploadImage: AppCompatButton by lazy {
findViewById(R.id.upload)
}
private val imgPost: AppCompatImageView by lazy {
findViewById(R.id.imageView)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_upload)
init()
}
private fun init() {
btnSelectImage.setOnClickListener {
imagePicker()
}
btnUploadImage.setOnClickListener {
filePath?.let {
it1 -> sm.uploadImage(this, it1)
thread {
Thread.sleep(1000)
//ParseUploadActivity().uploader(this, it1)
//(this#UploadActivity as ParseUploadActivity).uploader(this, it1)
(this as ParseUploadActivity).uploader(this, it1)
}
}
}
}
private fun imagePicker() {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == 1 && resultCode == Activity.RESULT_OK) {
if(data == null || data.data == null) {
return
}
filePath = data.data
try {
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, filePath)
imgPost?.setImageBitmap(bitmap)
} catch(e: IOException) {
e.printStackTrace()
}
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
var inflater: MenuInflater = menuInflater
inflater.inflate(R.menu.filemenu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when(item.itemId) {
R.id.upload_menu -> {
true
}
R.id.show_menu -> {
true
}
else -> super.onOptionsItemSelected(item)
}
}
}
The problem is in this line of code (this as ParseUploadActivity).uploader(this, it1). I tried different ways but still have an error and can't fix it.
P.S.
ParseUploadActivity is also inherited from AppCompatActivity.
I mean
class ParseUploadActivity : AppCompatActivity() {...}

Android Studio: onActivityResult not being executed after closing gallery

I am new to android development and trying to teach myself. Currently I am trying to add a functionality in my app where I click a button and the gallery opens up for a user to select an image to be used later and then a dialog box is supposed to show up after the gallery closes. However, after closing the gallery nothing happens and it seems that the onActivityResult() code does not run for some reason. I get no error in logcat and Log.d statments do not show up. Code below. Thanks!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d("TEST1", "FUN EXECUTED")
val fab = view.findViewById<FloatingActionButton>(R.id.fababc)
fab.setOnClickListener {
showCreateTodoList()
Log.d("TEST2", "RECIEVING INPUT")
}
}
private fun showCreateTodoList() {
openGallery()
}
private fun openGallery() {
val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
requireActivity().startActivityForResult(gallery, p)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(resultCode == AppCompatActivity.RESULT_OK && requestCode == p){
Log.d("TESTING", "THIS CODE RUNS")
imageURI = data!!.data
activity?.let {
val dialogTitle = getString(R.string.newScp)
val positiveButtonTitle = getString(R.string.create)
val myDialog = AlertDialog.Builder(it)
val todoTitleEditText = EditText(it)
todoTitleEditText.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_WORDS
myDialog.setTitle(dialogTitle)
myDialog.setView(todoTitleEditText)
myDialog.setPositiveButton(positiveButtonTitle) { dialog, _ ->
uri = imageURI.toString()
val list = viewData(todoTitleEditText.text.toString(),uri,R.drawable.image,"SCP Name: ", "SCP Class", "Date Discovered: ", "Kill Count:" )
addToList(list)
dialog.dismiss()
ListItemCLickedu(list)
}
myDialog.create().show()
}
}
else{ Log.d("TESTING2", "THIS CODE DOES NOT RUN!")
}
}
Based on your code,i try this and works fine:
private lateinit var imageURI: Uri
companion object {
const val REQUEST_MEDIA = 101
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("TEST1", "FUN EXECUTED")
button.setOnClickListener {
showCreateTodoList()
Log.d("TEST2", "RECIEVING INPUT")
}
}
private fun showCreateTodoList() {
openGallery()
}
private fun openGallery() {
val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
startActivityForResult(gallery, REQUEST_MEDIA)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == REQUEST_MEDIA) {
Log.d("TESTING", "THIS CODE RUNS")
imageURI = data?.data!!
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(this)
builder.setMessage("Dummy Dialog Title")
.setPositiveButton("Ok",
DialogInterface.OnClickListener { dialog, id ->
// what you want to do on positive click
dialog.dismiss()
})
.setNegativeButton("Cancel",
DialogInterface.OnClickListener { dialog, id ->
// User cancelled the dialog
dialog.dismiss()
})
// Create the AlertDialog object and return it
builder.create().show()
}
}
Please check if you add permissions in your manifest file and also if you are in fragment check if activity in activity?.let is null. If so, try something getBaseActivity()?.let or applicationContext?.let and in there display your dialog.

Object does not exist at location android studio Kotlin

I wanna store an image in firebase storage but i got an warning message when running "Object does not exist at location", I don't know where is my mistake, already trying search old answer but all of them in java not kotlin.
class Activity2 : AppCompatActivity() {
private var curFile: Uri? = null
private val imageRef = Firebase.storage.reference
private val REQUEST_CODE_IMAGE_PICK = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity2)
//an image view to select and image inside phone storage
ivfoto.setOnClickListener {
Intent(Intent.ACTION_GET_CONTENT).also {
it.type = "image/*"
startActivityForResult(it, REQUEST_CODE_IMAGE_PICK)
}
}
//btn for upload image to storage
btnupload.setOnClickListener {
uploadImageToStorage("Myimages")
}
}
//function to upload an image to firebase
private fun uploadImageToStorage(filename: String) = CoroutineScope(Dispatchers.IO).launch {
try {
curFile?.let {
imageRef.child("images/$filename").putFile(it).await()
withContext(Dispatchers.Main) {
Toast.makeText(
this#Activity2, "Foto anda telah dipilih",Toast.LENGTH_LONG).show()
}
}
} catch (e: Exception) {
withContext(Dispatchers.Main) {
Toast.makeText(this#Activity2, e.message, Toast.LENGTH_LONG).show()
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_IMAGE_PICK) {
data?.data?.let {
curFile = it
ivfoto.setImageURI(it)
}
}
}
}
Here is the error message,its on the device,already run in physical device and emulator but the error is the same

change the toolbar menu in android when the recycle view items are longClicked

I have implemented a recycle view and add images to the view by the camera. It is working fine. Now what i am going to do is, when the user long clicks on a recycle view item change the toolbar menu. I am getting the following error.
Process: com.example.fyp_patient, PID: 8797
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:164)
at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:157)
at android.content.Context.obtainStyledAttributes(Context.java:677)
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:692)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:659)
at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:479)
at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:214)
at com.example.fyp_patient.MainActivity._$_findCachedViewById(Unknown Source:25)
at com.example.fyp_patient.MainActivity.onLongClick(ImageRecycleViewActivity.kt:237)
at android.view.View.performLongClickInternal(View.java:7444)
at android.view.View.performLongClick(View.java:7392)
at android.view.View.performLongClick(View.java:7410)
at android.view.View$CheckForLongPress.run(View.java:27811)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7188)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
My code is as follow.
ImageRecycleViewActivity.kt
var isInActionMode = false
private val uriArrayList = ArrayList<Uri>()
private val arrayList = ArrayList<Model>()
private var driveServiceHelper: DriveServiceHelper? = null
private var RC_AUTHORIZE_DRIVE = 101
private val REQUEST_IMAGE_CAPTURE: Int = 100
private var image_uri: Uri? = null
private val IMAGE_CAPTURE_CODE: Int = 101
private var ACCESS_DRIVE_SCOPE = Scope(Scopes.DRIVE_FILE)
private var SCOPE_EMAIL = Scope(Scopes.EMAIL)
lateinit var googleDriveService: Drive
var mDriveServiceHelper: DriveServiceHelper? = null
var adapter = Adapter(arrayList,this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_imagerecycleview)
setSupportActionBar(toolbar as Toolbar?)
updateView()
counter_text.visibility = View.GONE
btn.setOnClickListener {
checkForGooglePermissions()
createFolderInDrive()
}
fab.setOnClickListener {
getPermission()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater: MenuInflater = menuInflater
inflater.inflate(R.menu.main, menu)
return true
}
/***********get the permission from the device to access the camera***********/
private fun getPermission() {
//if the system is marshmallow or above get the run time permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED ||
checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED
) {
//permission was not enabled
val permission = arrayOf(
android.Manifest.permission.CAMERA,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
)
//show popup to request permission
requestPermissions(permission, REQUEST_IMAGE_CAPTURE)
} else {
//permission already granted
openCamera()
}
} else {
//system os < marshmallow
openCamera()
}
}
/************open the device camera*************/
private fun openCamera() {
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE, "New Picture")
values.put(MediaStore.Images.Media.DESCRIPTION, "this is an images")
image_uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
//camera Intent
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri)
startActivityForResult(cameraIntent, IMAGE_CAPTURE_CODE)
}
/*************call when user clicks on the permission request dialog********************/
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
//called when user allow or deny from permission request
when (requestCode) {
REQUEST_IMAGE_CAPTURE -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//permission from pop up was granted
openCamera()
} else {
//permission from pop up was denied
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show()
}
}
}
}
/************called when an image is captured*************/
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
//called when image is captured from camera intent
if (resultCode == Activity.RESULT_OK) {
//set the image to the image view
image_uri?.let { uriArrayList.add(it) }
arrayList.add((image_uri?.let { Model("My title", "My description", it) }!!))
Log.i("check123", image_uri.toString())
updateView()
}
}
private fun updateView() {
val adapter = Adapter(arrayList, this)
recycleView.layoutManager = LinearLayoutManager(this)
recycleView.adapter = adapter
}
override fun onLongClick(view: View?): Boolean {
Log.i("clicktest","clicked")
toolbar.menu.clear()
toolbar.inflateMenu(R.menu.menu_action_mode)
counter_text.visibility=View.VISIBLE
isInActionMode=true
adapter.notifyDataSetChanged()
ActionBar.DISPLAY_HOME_AS_UP
return true
}
}
Adapter.kt
class Adapter(val arrayList: ArrayList<Model>,val context:Context) :
RecyclerView.Adapter<Adapter.ViewHolder>() {
class ViewHolder (itemView : View) : RecyclerView.ViewHolder(itemView){
fun bindItems (model: Model){
itemView.title.text = model.title
itemView.description.text = model.des
itemView.imageIv.setImageURI(model.uri)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.image_list_item, parent, false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return arrayList.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(arrayList[position])
if (!MainActivity().isInActionMode){
holder.itemView.checkbox.visibility=View.GONE
}else {
holder.itemView.checkbox.visibility=View.VISIBLE
}
holder.itemView.setOnLongClickListener(MainActivity())
}
}
Error occurs from this line
toolbar.menu.clear()
Please help me

App crashes when I pass an object that extends parcelable interface

I am trying to build a simple app that passes objects between activities so I could use the Class properties in the recyclerview later on. I have created the "Member data class" and extended it so that it uses the parelable interface.
data class Member(val name : String, val image : ByteArray) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.createByteArray()
) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(name)
parcel.writeByteArray(image)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Member> {
override fun createFromParcel(parcel: Parcel): Member {
return Member(parcel)
}
override fun newArray(size: Int): Array<Member?> {
return arrayOfNulls(size)
}
}
}
After that i have created a memberCreation activity to input some data in the class and pass the class back to the main activity using intent.
class MemberCreation : AppCompatActivity() {
private lateinit var profilePic : ImageView
private lateinit var nameEditText: EditText
private lateinit var saveButton: Button
private lateinit var profilePictureByteArray: ByteArray
private lateinit var member: Member
companion object{
const val REQUES_CODE_GALLERY = 999
const val EXTRA_REPLY = "robybp.coolkids.reply.extra"
}
#RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_member_creation)
profilePic = findViewById(R.id.profile_picture)
nameEditText = findViewById(R.id.name_edit_text)
saveButton = findViewById(R.id.button_save)
profilePic.setOnClickListener {
ActivityCompat.requestPermissions(this,
arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE),
REQUES_CODE_GALLERY)
}
saveButton.setOnClickListener {
if (nameEditText.text.isNotEmpty()){
val activityIntet = Intent()
val name : String = nameEditText.text.toString()
member = Member(name, profilePictureByteArray)
activityIntet.putExtra(EXTRA_REPLY, member)
setResult(Activity.RESULT_OK, activityIntet)
finish()
}
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode == REQUES_CODE_GALLERY){
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, REQUES_CODE_GALLERY)
}else{
Toast.makeText(this, "You don't have the permission to access gallery", Toast.LENGTH_LONG).show()
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUES_CODE_GALLERY && resultCode == Activity.RESULT_OK && data!= null) run {
val uri: Uri = data.data
try {
val inputStream: InputStream = contentResolver.openInputStream(uri)
val bitmap : Bitmap = BitmapFactory.decodeStream(inputStream)
profilePic.setImageBitmap(bitmap)
profilePictureByteArray = imageToArray(profilePic)
}catch (e : FileNotFoundException){
e.printStackTrace()
}
}
super.onActivityResult(requestCode, resultCode, data)
}
private fun imageToArray(image : ImageView) : ByteArray{
val bitmap = (image.drawable as BitmapDrawable).bitmap
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream)
val image = stream.toByteArray()
return image
}
}
But when i go back to retrieve the data in my main activity the app simply crashes without any logcat warnings. Also I am aware that I need to choose the profile picture from the gallery or the app will crash. I plan on adding a default value to the profilePictureByteArray later.
Here is a snippet of the code from my Main activity where i retrieve the object.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == MEMBER_CREATION_REQUEST_CODE && resultCode == Activity.RESULT_OK){
val member : Member = data!!.getParcelableExtra(MemberCreation.EXTRA_REPLY)
}
}
I would like to point out that I sort of a beginner so I apologize if the question is really simple.

Categories

Resources