I'm trying to upload an image to the server after clicking from the camera but the server returns
($_File) JSON Response after clicking the image from server and uploading
{
"data":78,
"status":true,
"files":
{
"photo":
{
"name":"IMG_20191108_115642_5386652903586463966.jpg",
"type":"",
"tmp_name":"",
"error":1,
"size":0
}
}
}
($_File) JSON Response after picking the image from Gallery and uploading
{
"data":79,
"status":true,
"files":
{
"photo":
{
"name":"Screenshot_20191108_081937_com.instagram.android.jpg",
"type":"*\/*",
"tmp_name":"C:\\xampp\\tmp\\php50A6.tmp",
"error":0,
"size":518164
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_pharmacy)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(this, permission, REQUEST_PERMISSION)
}
next.setOnClickListener {
if (prescriptionid == "") {
Toast.makeText(
applicationContext,
"Select/Upload Prescription First",
Toast.LENGTH_LONG
).show()
} else {
intent = Intent(applicationContext, SelectAddressActivity::class.java)
imageFilePath = ""
imageView.setImageResource(R.drawable.ic_image)
imagedisplay.visibility = View.GONE
startActivity(intent)
}
}
if (imageFilePath == "") {
imagedisplay.visibility = View.GONE
} else {
imagedisplay.visibility = View.GONE
}
}
Camera Intent
private fun openCameraIntent() {
val pictureIntent = Intent(
MediaStore.ACTION_IMAGE_CAPTURE)
if (pictureIntent.resolveActivity(getPackageManager()) != null)
{
try
{
photoFile = createImageFile()
}
catch (ex:IOException) {}// Error occurred while creating the File
if (photoFile != null)
{
val photoURI = FileProvider.getUriForFile(this, packageName+".provider", photoFile)
pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,photoURI)
startActivityForResult(pictureIntent,CAMERA_REQUEST_CODE)
}
}
}
GalleryIntent
private fun pickFromGallery() {
//Create an Intent with action as ACTION_PICK
val intent = Intent(Intent.ACTION_PICK)
// Sets the type as image/*. This ensures only components of type image are selected
intent.type = "image/*"
//We pass an extra array with the accepted mime types. This will ensure only components with these MIME types as targeted.
val mimeTypes = arrayOf("image/jpeg", "image/png")
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
// Launching the Intent
startActivityForResult(intent, GALLERY_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
imagedisplay.visibility = View.VISIBLE
when (requestCode) {
CAMERA_REQUEST_CODE -> {
if (resultCode == Activity.RESULT_OK) {
correct.visibility = View.VISIBLE
imageView.setImageBitmap(setScaledBitmap())
}
}
GALLERY_REQUEST_CODE -> {
//data.getData returns the content URI for the selected Image
if (resultCode == Activity.RESULT_OK) {
correct.visibility = View.VISIBLE
var selectedImage = data!!.data as Uri
var filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
// Get the cursor
var cursor = getContentResolver().query(
selectedImage,
filePathColumn, null, null, null
);
// Move to first row
cursor!!.moveToFirst();
//Get the column index of MediaStore.Images.Media.DATA
var columnIndex = cursor.getColumnIndex(filePathColumn[0])
//Gets the String value in the column
var imgDecodableString = cursor.getString(columnIndex)
cursor.close()
// Set the Image in ImageView after decoding the String
Log.i("filepath", imgDecodableString)
imageFilePath = imgDecodableString
imageView.setImageBitmap(BitmapFactory.decodeFile(imgDecodableString))
}
}
else -> {
Toast.makeText(this, "Unrecognized request code", Toast.LENGTH_SHORT).show()
}
}
}
Code To Create image file
#Throws(IOException::class)
private fun createImageFile(): File {
// Create an image file name
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES) as File
return File.createTempFile(
"IMG_${timeStamp}_", /* prefix */
".jpg", /* suffix */
storageDir /* directory */
).apply {
// Save a file: path for use with ACTION_VIEW intents
imageFilePath = absolutePath
}
}
Code To Upload Image To Server
val file = File(imageFilePath)
//creating request body for file
var requestBody = file.asRequestBody("*/*".toMediaTypeOrNull())
// val requestFile = file.asRequestBody("*/*".toMediaTypeOrNull())
var photo = MultipartBody.Part.createFormData("photo", file.name, requestBody)
// RequestBody descBody = RequestBody.create(MediaType.parse("text/plain"), desc);
Log.e("requestFile", imageFilePath)
val uploadImage =
RetrofitCall.provideRetrofit().create(uploadPrescriptionApi::class.java)
uploadImage.uploadPrescription("Bearer ".plus(sharedPreference!!.token.toString()), photo)
.enqueue(object : Callback<UploadPhototPOJO> {
override fun onResponse(
call: Call<UploadPhototPOJO>,
response: Response<UploadPhototPOJO>
) {
if (response.body()!!.status!!) {
progressDialog!!.dismiss()
prescriptionid = response.body()!!.id.toString()
Log.i("id", prescriptionid.toString())
} else {
Toast.makeText(
applicationContext,
"Oops Something Went Wrong!! Try again",
Toast.LENGTH_LONG
).show()
progressDialog!!.dismiss()
}
}
override fun onFailure(call: Call<UploadPhototPOJO>, t: Throwable) {
// handle execution failures like no internet connectivity
Log.i("Faliure", t.toString())
}
})
}
The maximum allowed size for uploading files is 2Mb. As you mentioned in your comment the size of the photo being uploaded is 4Mb.
If you want to upload files greater than the size set, just open the php.ini file to increase the size.
Open C:/xampp/php/php.ini file in any one of your favorite text editors. Search for upload_max_filesize and change it the size. For example, 50Mb
upload_max_filesize = 50M
And also the maximum size of POST data that PHP will accept is 8Mb. If you want to extend it, search for post_max_size and increase the size.
Finally, don't forget to restart the Apache server.
Related
Hy
I created a file picker in my application. The first idea was, after the user pick a file, I concert to bae64 string and temporary I save it in the room database, while it won't be uploaded to the server. Unfortunatelly the room doesn't like files over 2 mb, so I get exception.
Se after that, I thought that, I store just the file path, and later I check the file if exists, and if it is, then I convert to base64 and upload the server.
It seems a good idea, but I can't open the file, because the file path doesn't exists. I checked File.exists but it always return false.
I use my application private storage because of android 11.
The path which is provided by uri.path gives this string: "/document/document:690"
But my file is locatid in Download folder(not inside my application folder). The uri is good, because I can open the file from my application.
The plan B is that, all the files which the user choose, I create a copy in my private directory, and with the file name and the extension, I can check it is exists
0. Camera and file picker
private fun openFilePicker() {
try {
myFileIntent = Intent(Intent.ACTION_GET_CONTENT)
myFileIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
myFileIntent.addCategory(Intent.CATEGORY_OPENABLE)
myFileIntent.type = "*/*"
startActivityForResult(myFileIntent, RequestCodes.DocumentUploadSelectFileRequestCode.code)
}catch (e: ActivityNotFoundException){
showSnackbar(getString(R.string.not_found_application_label),false)
}
}
private fun openCameraIntent() {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
try {
val photoFile = documentManagerService.createFile(requireActivity(),Environment.DIRECTORY_PICTURES,".jpg","IMG",true)
imageFilePath = photoFile?.path
photoFile?.let {
val photoUri = FileProvider.getUriForFile(requireContext(),requireContext().packageName,photoFile)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,photoUri)
startActivityForResult(takePictureIntent,RequestCodes.DocumentUploadTakePictureRequestCode.code)
}
}catch (ex: ActivityNotFoundException){
showSnackbar(getString(R.string.not_found_application_label),false)
}
}
1. Activity Result
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
//Pick files
RequestCodes.DocumentUploadSelectFileRequestCode.code -> {
if (resultCode == Activity.RESULT_OK) {
data?.let { it ->
if (it.clipData != null) {
for (i in 0 until it.clipData!!.itemCount) {
it.clipData?.getItemAt(i)?.uri?.let { uri ->
documentManagerService.getFileMetaData(uri,requireContext(),requireActivity())?.let {
viewModel.addDocumentView(it)
}
}
}
} else {
it.data?.let { uri ->
documentManagerService.getFileMetaData(uri,requireContext(),requireActivity())?.let {
viewModel.addDocumentView(it)
}
}
}
}
}
}
//Take a picture
RequestCodes.DocumentUploadTakePictureRequestCode.code -> {
if (resultCode == Activity.RESULT_OK) {
imageFilePath?.let {
val file = File(it)
val uri = FileProvider.getUriForFile(requireContext(),requireContext().packageName,file)
documentManagerService.getFileMetaData(uri,requireContext(),requireActivity())?.let { documentView ->
viewModel.addDocumentView(documentView)
}
}
}
}
}
}
2. Get file meta data
override fun getFileMetaData(uri: Uri,context: Context): DocumentView? {
val documentView = DocumentView()
val cursor: Cursor?
documentView.uri = uri
documentView.id = UUID.randomUUID().toString()
if ("file".equals(uri.scheme, ignoreCase = true)) {
uri.path?.let {
val file = File(it)
documentView.name = file.name
documentView.extension = file.extension
return documentView
}
} else {
val contentResolver = context.contentResolver
cursor = contentResolver.query(uri, null, null, null, null)
try {
if (cursor != null && cursor.moveToFirst()) {
var size = cursor.getColumnIndex(OpenableColumns.SIZE)
documentView.name =
cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
}
documentView.filePath = uri.toString()
val mimeType = MimeTypeMap.getSingleton()
documentView.extension = mimeType.getExtensionFromMimeType(
contentResolver.getType(
uri
)
) ?: "N/A"
return documentView
} catch (e: Exception) {
Timber.e(e)
} finally {
cursor?.close()
}
}
return null
}
3. Check the sync status, where is the file
private fun openOrDownloadFile(documentView: DocumentView) {
//The file is exists on server, have to download
if (viewModel.customerComplaint.value?.syncStatus == 2) {
viewModel.downloadDocument(documentView.id)
//There is in somewhere in local storage
} else {
//val existingFile = documentManagerService.getFileIfExists(documentView.name,documentView.extension,requireActivity())
//create Uri from saved uri string
val u = Uri.parse(documentView.filePath)
openFile(u, documentView.extension)
}
}
4. Get Intent based on uri
override fun getFileIntent(extension: String,uri: Uri) : Intent {
val intent = Intent(Intent.ACTION_VIEW)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
if (extension == "jpeg" || extension == "jpg" || extension == "png")
intent.setDataAndType(uri, "image/$extension")
else
intent.setDataAndType(uri, "application/$extension")
return intent
}
5. Open File
private fun openFile(uri: Uri, extension: String) {
try {
startActivity(documentManagerService.getFileIntent(extension, uri))
} catch (e: Exception) {
showSnackbar(getString(R.string.can_not_open_the_file_label), false)
}
}
I am trying to let the users of my record a video. Using the following code.
private fun handleRecordVideoRequest() {
val videoName = getVideoName()
val videoUri = getVideoUri(videoName)
Timber.tag(TAG).i(">>>> Video URI: $videoUri")
val videoRecorder = getVideoRecorder()
videoRecorder.launch(videoUri)
}
private fun getVideoRecorder() =
registerForActivityResult(ActivityResultContracts.TakeVideo()) { bitmap ->
Timber.tag(TAG).i(">>>> Video Bitmap: $bitmap") // bitmap is NULL
}
private fun getVideoUri(videoName: String): Uri? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val videoStore = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val newVideoDetails = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, videoName)
}
contentResolver.insert(videoStore, newVideoDetails)
} else {
val mediaDir = getExternalFilesDir("video/*")
mediaDir?.mkdirs()
val sdImageMainDirectory = File(mediaDir, videoName)
FileProvider.getUriForFile(this, applicationContext.packageName + ".provider", sdImageMainDirectory)
}
}
private fun getVideoName() = "app_video_" + System.currentTimeMillis() + ".mp4"
The code runs without any exceptions being thrown. However the bitmap in method getVideoRecorder() is always null. When I view the folders on the emulator I can see that the video was recorded successfully.
I also have the write to storage permission enabled.
If you take a look at the implementation of the .ActivityResultContracts.TakeVideo contract you'll see that the result type is actually nullable.
The parseResult method will return null if 1. the resultCode != Activity.RESULT_OK and 2. if intent.getParcelableExtra("data") is not a Bitmap.
#Nullable
#Override
public final Bitmap parseResult(int resultCode, #Nullable Intent intent) {
if (intent == null || resultCode != Activity.RESULT_OK) return null;
return intent.getParcelableExtra("data");
}
I ran into the same issue on Android 11(Q) because the contents of the resulting Intent is the URI passed in; not a Bitmap. So.. I'd suggest just using ActivityResultContracts.StartActivityForResult() instead.
Like so:
val videoLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
activityResult.data?.data?.let {
// Do something with the video URI
}
} else {
//handle user cancel
}
}
And use it:
fun captureVideo() {
mediaStoreService.createNewMediaFile(MediaAssetType.Video)?.let { uri ->
Intent(MediaStore.ACTION_VIDEO_CAPTURE).apply {
putExtra(MediaStore.EXTRA_OUTPUT, uri)
}.also { takeVideoIntent ->
takeVideoIntent.resolveActivity(requireContext().packageManager)?.also {
videoLauncher.launch(takeVideoIntent)
}
}
}
}
On my app, users can save some notes with image. But, users can not save their notes without image. Thus image is compulsory to save their data. But ı want to change it. I want to allow them to save their note without image. How can ı do this ? This is my saveclcikbutton codes;
class TakeNotesActivity : AppCompatActivity() {
var selectedPicture: Uri? = null
var selectedBitmap: Bitmap? = null
private lateinit var db: FirebaseFirestore
private lateinit var auth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_take_notes)
auth = FirebaseAuth.getInstance()
db = FirebaseFirestore.getInstance()
}
fun putPictureClick(view: View) {
val popupMenu = PopupMenu(this, view)
val inflater = popupMenu.menuInflater
inflater.inflate(R.menu.secondmenu, popupMenu.menu)
popupMenu.show()
popupMenu.setOnMenuItemClickListener {
if (it.itemId == R.id.galleryImage) {
if (ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.READ_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE),
1
)
} else {
val intentToGallery =
Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intentToGallery, 2)
}
}
if (it.itemId == R.id.capturePhoto) {
if (ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.CAMERA),
10
)
} else {
openCamera()
}
}
if (it.itemId == R.id.cancel) {
Toast.makeText(applicationContext, "Canceled", Toast.LENGTH_LONG).show()
}
true
}
}
fun openCamera() {
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE, "New Picture")
values.put(MediaStore.Images.Media.DESCRIPTION, "From the Camera")
selectedPicture =
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
// Camera Intent
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, selectedPicture)
startActivityForResult(cameraIntent, 20)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode == 1) {
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
val intentToGallery =
Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intentToGallery, 2)
}
}
if (requestCode == 10) {
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openCamera()
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_LONG).show()
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == 2 && resultCode == Activity.RESULT_OK && data != null) {
selectedPicture = data.data
try {
if (selectedPicture != null) {
if (Build.VERSION.SDK_INT >= 28) {
val source =
ImageDecoder.createSource(this.contentResolver, selectedPicture!!)
selectedBitmap = ImageDecoder.decodeBitmap(source)
imageButton.setImageBitmap(selectedBitmap)
} else {
selectedBitmap =
MediaStore.Images.Media.getBitmap(this.contentResolver, selectedPicture)
imageButton.setImageBitmap(selectedBitmap)
}
}
} catch (e: Exception) {
}
}
//called when image was captured from camera intent
if (requestCode == 20 && resultCode == Activity.RESULT_OK && data != null) {
imageButton.setImageURI(selectedPicture)
}
super.onActivityResult(requestCode, resultCode, data)
}
fun saveClick(view: View) {
//UUID -> Image Name
val uuid = UUID.randomUUID()
val imageName = "$uuid.jpg"
val storage = FirebaseStorage.getInstance()
val reference = storage.reference
val imagesReference = reference.child("images").child(imageName)
if (selectedPicture != null) {
imagesReference.putFile(selectedPicture!!).addOnSuccessListener { taskSnapshot ->
// take the picture link to save the database
val uploadedPictureReference =
FirebaseStorage.getInstance().reference.child("images").child(imageName)
uploadedPictureReference.downloadUrl.addOnSuccessListener { uri ->
val downloadUrl = uri.toString()
println(downloadUrl)
val noteMap = hashMapOf<String, Any>()
noteMap.put("downloadUrl", downloadUrl)
noteMap.put("userEmail", auth.currentUser!!.email.toString())
noteMap.put("noteTitle", titleText.text.toString())
noteMap.put("yourNote", noteText.text.toString())
noteMap.put("date", Timestamp.now())
db.collection("Notes").add(noteMap).addOnCompleteListener { task ->
if (task.isComplete && task.isSuccessful) {
finish()
}
}.addOnFailureListener { exception ->
Toast.makeText(
applicationContext,
exception.localizedMessage?.toString(),
Toast.LENGTH_LONG
).show()
}
}
}
}
}
}
I also try to add on saveClick fun the codes below but did not work. What should I do ?
fun saveClick(view: View) {
//UUID -> Image Name
val uuid = UUID.randomUUID()
val imageName = "$uuid.jpg"
val storage = FirebaseStorage.getInstance()
val reference = storage.reference
val imagesReference = reference.child("images").child(imageName)
if (selectedPicture != null) {
imagesReference.putFile(selectedPicture!!).addOnSuccessListener { taskSnapshot ->
// take the picture link to save the database
val uploadedPictureReference =
FirebaseStorage.getInstance().reference.child("images").child(imageName)
uploadedPictureReference.downloadUrl.addOnSuccessListener { uri ->
val downloadUrl = uri.toString()
println(downloadUrl)
val noteMap = hashMapOf<String, Any>()
noteMap.put("downloadUrl", downloadUrl)
noteMap.put("userEmail", auth.currentUser!!.email.toString())
noteMap.put("noteTitle", titleText.text.toString())
noteMap.put("yourNote", noteText.text.toString())
noteMap.put("date", Timestamp.now())
db.collection("Notes").add(noteMap).addOnCompleteListener { task ->
if (task.isComplete && task.isSuccessful) {
finish()
}
}.addOnFailureListener { exception ->
Toast.makeText(
applicationContext,
exception.localizedMessage?.toString(),
Toast.LENGTH_LONG
).show()
}
}
}
}else {
val noteMap = hashMapOf<String, Any>()
noteMap.put("userEmail", auth.currentUser!!.email.toString())
noteMap.put("noteTitle", titleText.text.toString())
noteMap.put("yourNote", noteText.text.toString())
noteMap.put("date", Timestamp.now())
db.collection("Notes").add(noteMap).addOnCompleteListener { task ->
if (task.isComplete && task.isSuccessful) {
finish()
}
}
}
}
}
So all your logic is basically wrapped up in that putFile success callback, which requires an image to be successfully stored and retrieved (?) before anything will be added to the database.
You need to break that logic up, so you can only run the parts you want to - like just running the database update part if you don't have an image, or running that part later once your image is successfully handled.
So really, you need a "store in database" function to handle the final writing - call that directly if you don't have an image, call it in the success callbacks if you do. I'm just going to pseudocode this but:
saveData(noteMap: Map) {
add note to DB
}
saveClick() {
create noteMap with basic, non-image details (email, title etc)
if image is null, call saveData(noteMap)
else do the image stuff:
onSuccess:
add the downloadUrl to noteMap
call saveData(noteMap)
}
I see you've made an edit with an else branch which creates the map sans url and writes it - you're basically almost there, just make it a function instead, and pass the map in!
I have written code to upload images to the server using kotlin, that is, the user takes a picture through the camera then displays the image in the imageView when the user clicks the send button, I want the image from ImageView to be sent to the server, but I don't know how to change the image from ImageView be a file that can be sent to the server.
I have designed code to capture image and set the image in image view to preview it but not getting idea to upload it to the server using http request.
for opening camera and setting image into imageview:
private fun openCamera(){
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE, "New Picture")
values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera")
private fun openCamera() {
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE, "New Picture")
values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera")
image_uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri)
startActivityForResult(cameraIntent, IMAGE_CAPTURE_CODE)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
when (requestCode) {
PERMISSION_CODE_CAM -> {
if (grantResults.size!! > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openCamera()
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show()
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && resultCode == IMAGE_CAPTURE_CODE) {
imageView.setImageURI(image_uri)
}
}
I want to upload image to server using http request, I am getting many codes in java but not in kotlin. I am not getting any idea to upload in kotlin.
As this is question is still open. We can use OKHTTP library which is very easy to use and we have to write very less code. Here I have written a detailed article on the topic
Upload Image or File to Server in Android Kotlin
I am not going to copy the same code again, I have written a UploadUtility class. Just copy it in your project from the above link and it will do the rest.
Api Interface
#Multipart
#POST("your_url")
suspend fun uploadImage(
#Part file:MultipartBody.Part
): Response<String>
Kotlin code
val file: File = ImagePicker.getFile(data)!!
val requestFile =RequestBody.create("multipart/form-data".toMediaTypeOrNull(),file)
val requestFile=RequestBody.create(MediaType.parse("image/*"),file)
val body = MultipartBody.Part.createFormData("profile_picture", file.name, requestFile)
uploadImage(body)
this is image upload using kotlin Retrofit code 100% working
private fun UploedImage(User_id:String , newfile: File) {
Commons.showProgressDialog(this#StoreDetailActivity)
//creating a file
var requestFile: RequestBody? = null
var document: MultipartBody.Part
var ImageUloloadgetCall: Call<ImageUloloadgetUrlModel?>? = null
if (newfile != null) {
val MEDIA_TYPE_IMAGE = "image/*".toMediaTypeOrNull()
requestFile = create(MEDIA_TYPE_IMAGE, newfile)
document = createFormData(
"image",
newfile.getName(),
requestFile
)
val userId= create("text/plain".toMediaTypeOrNull(), User_id)
ImageUloloadgetCall = getApiInstance().ImageUpload(
alldata,
document
)
}
ImageUloloadgetCall!!.enqueue(object : Callback<ImageUloloadgetUrlModel?> {
override fun onResponse(
call: Call<ImageUloloadgetUrlModel?>,
response: Response<ImageUloloadgetUrlModel?>
) {
dismissProgressDialog()
if (!response.isSuccessful()) {
Log.d(
TAG,
"onResponse: fail " + response.code()
)
Toast.makeText(
this#StoreDetailActivity,
"" + response.message(),
Toast.LENGTH_SHORT
).show()
return
}
Log.d(
TAG,
"onResponse: success" + response.code() + response.body()
)
if (response.body() != null) {
var imageUloloadgetUrlModel: ImageUloloadgetUrlModel? = null
try {
imageUloloadgetUrlModel = response.body()
} catch (e: Exception) {
Toast.makeText(
this#StoreDetailActivity,
"Error in response",
Toast.LENGTH_SHORT
).show()
return
}
} else {
Toast.makeText(
this#StoreDetailActivity,
"Invalid response from server",
Toast.LENGTH_SHORT
).show()
}
}
override fun onFailure(call: Call<ImageUloloadgetUrlModel?>, t: Throwable) {
dismissProgressDialog()
}
})
}
You can use these functions to capture an image by the camera:
public static Uri getTakenPictureUri(Context mContext, Intent data) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = mContext.getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
picturePath = "file://" + picturePath;
LogHelper.trace("Selected file uri:" + picturePath);
return Uri.parse(picturePath);
}
public static File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = MyPharmacy.getmInstance().getExternalCacheDir();
LogHelper.trace("createImageFile:" + storageDir.getAbsolutePath());
File image = File.createTempFile(
imageFileName,
".jpg",
storageDir
);
return image;
}
public static File openCamera(Activity mActivity, int requestCode) {
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
File photoFile = createImageFile();
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(MyPharmacy.getmInstance(), BuildConfig.APPLICATION_ID + ".provider", photoFile);
camera.putExtra(MediaStore.EXTRA_OUTPUT,
photoURI);
if (camera.resolveActivity(mActivity.getPackageManager()) != null) {
mActivity.startActivityForResult(camera, requestCode);
return photoFile;
}
}
} catch (IOException ex) {
}
return null;
}
public static File openCamera(Fragment fragment, int requestCode) {
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
File photoFile = createImageFile();
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(MyPharmacy.getmInstance(), BuildConfig.APPLICATION_ID + ".provider", photoFile);
camera.putExtra(MediaStore.EXTRA_OUTPUT,
photoURI);
if (camera.resolveActivity(fragment.getActivity().getPackageManager()) != null) {
fragment.startActivityForResult(camera, requestCode);
return photoFile;
}
}
} catch (IOException ex) {
}
return null;
}
Then use below codes to upload it by retrofit
public static void uploadImage(final String filePath,
final String token,
final APIResponseCallback<UploadResponse> cb) {
if (filePath != null && !filePath.isEmpty()) {
final File file = new File(filePath);
if (file.exists()) {
Glide.with(App.getmInstance().getContext()).load(file).asBitmap().override(700, 700).into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation<? super Bitmap> glideAnimation) {
OutputStream os = null;
try {
String realPath = StorageHelper.getRealPathFromUri(App.getmInstance().getContext(), Uri.fromFile(file));
os = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, os);
os.flush();
os.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
if (file != null) {
// creates RequestBody instance from file
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
// MultipartBody.Part is used to send also the actual filename
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
// adds another part within the multipart request
String descriptionString = "Image";
RequestBody description = RequestBody.create(okhttp3.MultipartBody.FORM, descriptionString);
// executes the request
ServiceGenerator.getAPIServices().uploadImage(body, description, token).enqueue(new Callback<UploadResponse>() {
#Override
public void onResponse(Call<UploadResponse> call, Response<UploadResponse> response) {
if (response.isSuccessful()) {
cb.onSuccess(response.body());
} else {
checkError(response, token);
}
}
#Override
public void onFailure(Call<UploadResponse> call, Throwable t) {
cb.onError(t);
}
});
}
}
});
}
}
}
And API interface is:
#Multipart
#POST("Uploads/image/upload")
Call<UploadResponse> uploadImage(#Part MultipartBody.Part file,
#Part("description") RequestBody description,
#Query("access_token") String token);
Also, you can convert these codes to the kotlin equivalent.
All I want to do is allow users to take a photo and then after they've finished filling out a form submit that photo and upload to server.
I think I need the image in bitmap form so I can convert to Base64 string.
I've tried multiple different things I've found but none of them are working. I either get directory errors or intent null errors.
class Register : AppCompatActivity(), View.OnClickListener {
var PlayerID = ""
var mCurrentPhotoPath = ""
var stuff: File? = null
private var filePath: Uri? = null
private val PICK_IMAGE_REQUEST = 1
#RequiresApi(Build.VERSION_CODES.O)
override fun onClick(v: View?) {
if(v === buttonLoadPicture)
showFileChooser()
else if (v == btn_register)
uploadFile()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
if (resultCode != RESULT_CANCELED) {
if (requestCode == PICK_IMAGE_REQUEST) {
val thumbnail = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath)
PhotoImageView.setImageBitmap(thumbnail)
filePath = getRealPathFromURI(Uri.parse(filePath.toString()))
}
}
}
//////////////
fun getImageUri(inContext: Context , inImage: Bitmap): Uri {
val bytes = ByteArrayOutputStream()
inImage.compress(Bitmap.CompressFormat.PNG, 100, bytes)
val path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null)
return Uri.parse(path)
}
fun getRealPathFromURI(uri: Uri): Uri? {
val proj = arrayOf(MediaStore.Images.Media.DATA)
val cursor = getContentResolver().query(uri, proj, null, null, null)
cursor.moveToFirst()
val idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
return Uri.parse(cursor.getString(idx))
}
////////////////
#RequiresApi(Build.VERSION_CODES.N)
private fun showFileChooser() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.CAMERA),
1)
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
1)
}
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(intent, 1)
}
val jsonobject = JSONObject()
#RequiresApi(Build.VERSION_CODES.O)
private fun uploadFile() {
val progress: ProgressBar = progressBarR
progress.visibility= View.VISIBLE
val iStream = contentResolver.openInputStream(filePath)
val bitmap = BitmapFactory.decodeStream(iStream)
val baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val m = baos.toByteArray()
val imageString = Base64.encodeToString(m,Base64.DEFAULT)
//get form data from register layout
jsonobject.put("FirstName", input_fname.text)
jsonobject.put("LastName", input_lname.text)
jsonobject.put("UserName", input_username.text)
jsonobject.put("Phone", input_phone.text)
jsonobject.put("DOB", input_DOB.text)
jsonobject.put("Photo", imageString)
jsonobject.put("Profile", input_profile.text)
jsonobject.put("Email", input_email.text)
jsonobject.put("Password", input_password.text)
jsonobject.put("ConfirmPassword", input_confirm.text)
var url = "https://elimination.azurewebsites.net/api/Account/Post"
val que = Volley.newRequestQueue(this#Register)
val req = JsonObjectRequest(Request.Method.POST, url, jsonobject,
Response.Listener<JSONObject>{
response -> response.toString()
//save PlayerID to val PlayerID
PlayerID = response.get("PlayerID").toString()
//save to sharedPreferences
val email = input_email.text.toString()
val mypref = getSharedPreferences(email, Context.MODE_PRIVATE)
val editor = mypref.edit()
editor.putString(email, PlayerID)
editor.apply()
val intent = Intent(this, Login::class.java)
startActivity(intent)
},
Response.ErrorListener{
response ->
Log.e("Something went wrong", response.toString())
})
//if server is slow
val socketTimeout = 30000 // 30 seconds
val policy = DefaultRetryPolicy(socketTimeout,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)
req.setRetryPolicy(policy)
// Adding request to request queue
que.add(req)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
buttonLoadPicture.setOnClickListener(this)
btn_register.setOnClickListener(this)
}
}
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(intent, 1)
You are invoking ACTION_IMAGE_CAPTURE without EXTRA_OUTPUT.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
if (resultCode != RESULT_CANCELED) {
if (requestCode == PICK_IMAGE_REQUEST) {
val thumbnail = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath)
PhotoImageView.setImageBitmap(thumbnail)
filePath = getRealPathFromURI(Uri.parse(filePath.toString()))
}
}
}
You are not using the Bitmap that you get back from ACTION_IMAGE_CAPTURE when you do not supply EXTRA_OUTPUT. Instead, you are looking in a filePath value that may well be null and certainly has nothing to do with the photo that the user's chosen camera app may have taken.
If you want to tell the camera app where to put a full-size photo, use EXTRA_OUTPUT. However, then, bear in mind that you are unlikely to be able to convert a full-size photo to base64, as you will run out of memory.