I want to pick image from gallery, I added the READ_EXTERNAL_STORAGE permission to Manifest, but it doesn't work fine. It take path uri of image but doesn't show it. Only rectangle with good proportions (screen and code below)
class NewRestaurantFragment : Fragment(R.layout.fragment_new_restaurant) {
companion object {
private const val TAG = "NewRestaurantFragment"
private const val GET_IMAGE_REQUEST_CODE = 2137
}
private lateinit var ivPhoto: ImageView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
ivPhoto = view.findViewById(R.id.iv_photo)
ivPhoto.setOnClickListener {
selectPhoto()
}
}
private fun selectPhoto() {
val intent = Intent()
intent.apply {
type = "image/"
action = Intent.ACTION_PICK
}
startActivityForResult(intent, GET_IMAGE_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == GET_IMAGE_REQUEST_CODE && resultCode == RESULT_OK) {
val uri = data!!.data
ivPhoto.setImageURI(uri)
}
}
}
Related
I'm new to ML, but thanks to the documentation and the community, I'm developing in this direction. Now I have stumbled upon an error and for several days I could not solve it, what is the problem and how to solve it?
I looked at the tutorials, I didn't seem to forget anything. On the XMl layout there is a picture, a text where the data comes from, their ids match
I want to open an object, take a picture of it and say what it is based on my trained model
Problem: the application crashes on line 194:
inputFeature0.loadBuffer(byteBuffer)
class SortingFragment : Fragment(), View.OnClickListener {
//ML
lateinit var bitmap: Bitmap
lateinit var appCtx: Application
lateinit var btnMLrn : Button
#SuppressLint("WrongConstant")
public fun checkandGetpermissions() {
if (PermissionChecker.checkSelfPermission(
requireActivity(),
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_DENIED
) {
requestPermissions(arrayOf(Manifest.permission.CAMERA), 100)
} else {
requireActivity().showToast("Camera permission granted")
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == 100) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
requireActivity().showToast("Camera permission granted")
} else {
requireActivity().showToast("Permission Denied")
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.v(LOG_SORTING_FRAGMENT, "onCreate called")
// handling permissions
checkandGetpermissions()
appCtx = requireActivity().application
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.v(LOG_SORTING_FRAGMENT, "onCreateView called")
// Inflate the layout for this fragment
val rootView = inflater.inflate(R.layout.fragment_sorting, container, false)
btnMLrn = rootView.findViewById(R.id.btnMLrn)
fltNtf = rootView.findViewById(R.id.fltNtf)
fltNtf.setOnClickListener(this)
btnMLrn.setOnClickListener(View.OnClickListener {
var camera : Intent = Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(camera, 200)
})
return rootView
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == 250){
img_view.setImageURI(data?.data)
var uri : Uri?= data?.data
bitmap = MediaStore.Images.Media.getBitmap(requireActivity().contentResolver, uri)
}
else if(requestCode == 200 && resultCode == Activity.RESULT_OK){
bitmap = data?.extras?.get("data") as Bitmap
img_view.setImageBitmap(bitmap)
var resized = Bitmap.createScaledBitmap(bitmap, 224, 224, true)
val model = ModelUnquant.newInstance(requireActivity())
var tbuffer = TensorImage.fromBitmap(resized)
var byteBuffer = tbuffer.buffer
// Creates inputs for reference.
val inputFeature0 = TensorBuffer.createFixedSize(intArrayOf(1, 224, 224, 3), DataType.FLOAT32)
inputFeature0.loadBuffer(byteBuffer)
// Runs model inference and gets result.
val outputs = model?.process(inputFeature0)
val outputFeature0 = outputs?.outputFeature0AsTensorBuffer
var max = outputFeature0?.let { it1 -> getMax(it1.floatArray) }
val labels = appCtx.assets.open("labels.txt").bufferedReader().use { it.readText() }.split("\n")
sorttext.setText(labels[max!!])
// Releases model resources if no longer used.
if (model != null) {
model.close()
}
}}
fun getMax(arr: FloatArray): Int {
var ind = 0;
var min = 0.0f;
for (i in 0..10) {
if (arr[i] > min) {
min = arr[i]
ind = i;
}
}
return ind
}
} ```
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.
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.
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.
I would like to ask about why run app, avatar of FirebaseUser's profilePhoto will disappear?
But if just login or logout, avatar of FirebaseUser's profilePhoto can retain status.
If I picked one photo from mobile storage to avatar, then logout and login, avatar still the same. But run app, avatar will disappear, why?
class ProfileFragment : Fragment() {
companion object {
val TAG = ProfileFragment::class.java.simpleName
val instance by lazy {
ProfileFragment()
}
var user:FirebaseUser? = null
private val REQUEST_CODE_CHOOSE_AVATAR: Int = 200
// var userPhotoUrl:Uri? = null
}
private lateinit var viewModel: ProfileViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.profile_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
retainInstance = true
viewModel = ViewModelProviders.of(this).get(ProfileViewModel::class.java)
// TODO: Use the ViewModel
user = FirebaseAuth.getInstance().currentUser
// userPhotoUrl = user?.photoUrl
Picasso.get()
.load(user?.photoUrl)
.placeholder(R.mipmap.ic_launcher)
.transform(CropCircleTransformation())
.into(avatar_url)
name.text = user?.displayName
avatar_url.setOnClickListener {
val intent = Intent().apply {
type = "image/*"
action = Intent.ACTION_GET_CONTENT
action = Intent.ACTION_PICK
}
startActivityForResult(Intent.createChooser(intent,"Choose avatar"),REQUEST_CODE_CHOOSE_AVATAR)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_CHOOSE_AVATAR) {
if (resultCode == RESULT_OK) {
if (data != null) {
// val user = FirebaseAuth.getInstance().currentUser
val uri = data.data
val userProfileChangeRequest = UserProfileChangeRequest.Builder()
.setPhotoUri(uri)
.build()
user?.updateProfile(userProfileChangeRequest)
?.addOnCompleteListener {
if (it.isSuccessful) {
Picasso.get()
.load(user?.photoUrl)
.transform(CropCircleTransformation())
.into(avatar_url)
FirebaseFirestore.getInstance()
.collection("uploadedImages")
.whereEqualTo("uid",user?.uid)
.addSnapshotListener { querySnapshot, firebaseFirestoreException ->
if (querySnapshot != null && !querySnapshot.isEmpty) {
for (doc in querySnapshot.documents) {
Log.d(TAG, "uploadedImages's doc: ${doc.data}");
doc.data?.set("avatarUrl", user?.photoUrl.toString())
}
} else {
firebaseFirestoreException.toString()
}
}
FirebaseFirestore.getInstance()
.collection("userData")
.document(user!!.uid)
.update("avatarUrl", user!!.photoUrl.toString())
}
}
}
}
}
}
}
Login and logout, avatar still retain
Why re-run app avatar will disappear?
Have solved the problem.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_CHOOSE_AVATAR) {
if (resultCode == RESULT_OK) {
if (data != null) {
// val user = FirebaseAuth.getInstance().currentUser
val uri = data.data
val avatarRef = FirebaseStorage.getInstance().reference
.child("userAvatar")
.child(user!!.uid)
.child(uri.toString())
avatarRef.putFile(uri!!)
.continueWithTask {
if (!it.isSuccessful) {
it.exception?.let {
throw it
}
}
avatarRef.downloadUrl
}.addOnCompleteListener {
if (it.isSuccessful) {
val avatarDownloadUrl = it.result
val userProfileChangeRequest = UserProfileChangeRequest.Builder()
.setPhotoUri(avatarDownloadUrl)
.build()
user?.updateProfile(userProfileChangeRequest)
?.addOnCompleteListener { it1 ->
if (it1.isSuccessful) {
Picasso.get()
.load(user?.photoUrl)
.transform(CropCircleTransformation())
.into(avatar_url)