i can't upload image,video and files in kotlin webview - android

I can select a videos and images but i could not upload in my webview ,kotlin program.
webview.setWebChromeClient(object:WebChromeClient() {
override fun onShowFileChooser(webView:WebView, filePathCallback:ValueCallback<Array<Uri>>, fileChooserParams:FileChooserParams):Boolean {
var mFilePathCallback = filePathCallback
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.setType("*/*")
val PICKFILE_REQUEST_CODE = 100
startActivityForResult(intent, PICKFILE_REQUEST_CODE)
return true
}
})
fun onActivityResult(requestCode: Int, resultCode: Int,
intent: Intent,
mFilePathCallback: Any): Boolean {
var PICKFILE_REQUEST_CODE = null
if (requestCode == PICKFILE_REQUEST_CODE)
{
val result = if (intent == null || resultCode != RESULT_OK)
null
else
intent.getData()
val resultsArray = arrayOfNulls<Uri>(1)
resultsArray[0] = result
mFilePathCallback.onReceiveValue(resultsArray)
}
return true
}

You need add to your #Override onActivityResult
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_SELECT_FILE) {
if (null == uploadMessage) {
return
}
uploadMessage?.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode,data))
uploadMessage = null
}
}
but not inside of your "webview.setWebChromeClient(object:WebChromeClient()" hier doesnt override.

class MainActivity : AppCompatActivity() {
val TAG = "hellow web view"
val webURL: String = "https://www.google.com"
override fun onCreate(savedInstanceState: Bundle?): Unit {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
webview.restoreState(savedInstanceState)
// Log.i(TAG,"onCreate")
webview.webViewClient = WebViewClient()
webview.loadUrl(webURL)
webview.settings.javaScriptEnabled = true
webview.settings.builtInZoomControls = true
webview.settings.displayZoomControls = true
webview.settings.allowFileAccess = true
webview.settings.allowFileAccessFromFileURLs = true
webview.setWebChromeClient(object:WebChromeClient() {
override fun onShowFileChooser(webView:WebView, filePathCallback:ValueCallback<Array<Uri>>, fileChooserParams:FileChooserParams):Boolean {
var mFilePathCallback = filePathCallback
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.setType("*/*")
val PICKFILE_REQUEST_CODE = 100
startActivityForResult(intent, PICKFILE_REQUEST_CODE)
return true
}
})
fun onActivityResult(requestCode: Int, resultCode: Int,
intent: Intent,
mFilePathCallback: Any): Boolean {
var PICKFILE_REQUEST_CODE = null
if (requestCode == PICKFILE_REQUEST_CODE)
{
val result = if (intent == null || resultCode != RESULT_OK)
null
else
intent.getData()
val resultsArray = arrayOfNulls<Uri>(1)
resultsArray[0] = result
mFilePathCallback.onReceiveValue(resultsArray)
}
return true
}
webview.setDownloadListener(object : DownloadListener {
override fun onDownloadStart(url: String, userAgent: String,
contentDisposition: String, mimetype: String,
contentLength: Long) {
val request = DownloadManager.Request(Uri.parse(url))
request.allowScanningByMediaScanner()
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) //Notify client once download is completed!
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, mimetype)
val webview = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
webview.enqueue(request)
Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show()
}
})
class webviewclient : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
webview.loadUrl("http://google.com")
return true
}
}
searchbtn.setOnClickListener({ (webview.loadUrl("https://www.google.com")) })
btn1.setOnClickListener({ (webview.goBack()) })
btn3.setOnClickListener({ (webview.goForward()) })
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBack()) {
webview.goBack()
return true
}
return super.onKeyDown(keyCode, event)
}
override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)
webview.saveState(outState)
Log.i(TAG, "onSaveInstanceState")
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
super.onRestoreInstanceState(savedInstanceState)
webview.restoreState(savedInstanceState)
Log.i(TAG, "onRestoreInstanceState")
}
private fun Any.onReceiveValue(resultsArray: Array<Uri?>) {}
}

Related

Embed activity inside jetpack composable

Can we embed activity inside composable, so for example, when navigate to that composable its shows the activity content inside it(and not just start activity outside the composable),
That what i succeed so far, but its just show the activity and not embed it
#Composable
fun MyContent() {
val context = LocalContext.current
val intent = Intent(context, MyActivity::class.java)
context.startActivity(intent)
}
The activity
class WebViews : ComponentActivity() {
var webView: WebView? = null
private var mUploadMessage: ValueCallback<Uri>? = null
var uploadMessage: ValueCallback<Array<Uri>>? = null
val REQUEST_SELECT_FILE = 100
private val FILECHOOSER_RESULTCODE = 1
var url = "http://example.com"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_web_views)
webView = findViewById<View>(R.id.webView) as WebView
webView!!.settings.javaScriptEnabled = true
webView!!.loadUrl(url)
webView!!.webViewClient = xWebViewClient()
webView!!.webChromeClient = object : WebChromeClient() {
// For 3.0+ Devices (Start)
// onActivityResult attached before constructor
protected fun openFileChooser(
uploadMsg: ValueCallback<Uri>?, acceptType: String?
) {
mUploadMessage = uploadMsg
val i = Intent(Intent.ACTION_GET_CONTENT)
i.addCategory(Intent.CATEGORY_OPENABLE)
i.type = "image/*"
startActivityForResult(Intent.createChooser(i, "File Browser"), FILECHOOSER_RESULTCODE)
}
// For Lollipop 5.0+ Devices
override fun onShowFileChooser(
mWebView: WebView?,
filePathCallback: ValueCallback<Array<Uri>>?,
fileChooserParams: WebChromeClient.FileChooserParams
): Boolean {
if (uploadMessage != null) {
uploadMessage!!.onReceiveValue(null)
uploadMessage = null
}
uploadMessage = filePathCallback
var intent: Intent? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent = fileChooserParams.createIntent()
}
try {
startActivityForResult(intent, REQUEST_SELECT_FILE)
} catch (e: ActivityNotFoundException) {
uploadMessage = null
return false
}
return true
}
//For Android 4.1 only
protected fun openFileChooser(
uploadMsg: ValueCallback<Uri>?,
acceptType: String?,
capture: String?
) {
mUploadMessage = uploadMsg
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "image/*"
startActivityForResult(Intent.createChooser(intent, "File Browser"), FILECHOOSER_RESULTCODE)
}
protected fun openFileChooser(uploadMsg: ValueCallback<Uri>?) {
mUploadMessage = uploadMsg
val i = Intent(Intent.ACTION_GET_CONTENT)
i.addCategory(Intent.CATEGORY_OPENABLE)
i.type = "image/*"
startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
super.onActivityResult(requestCode, resultCode, intent)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (requestCode == REQUEST_SELECT_FILE) {
if (uploadMessage == null) return
uploadMessage!!.onReceiveValue(
WebChromeClient.FileChooserParams.parseResult(
resultCode,
intent
)
)
uploadMessage = null
}
} else if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage) return
// Use MainActivity.RESULT_OK if you're implementing WebView inside Fragment
// Use RESULT_OK only if you're implementing WebView inside an Activity
// val result: Uri? =
// if (intent == null || resultCode != WebViews.RESULT_OK) null else intent.data
// mUploadMessage.onReceiveValue(result)
mUploadMessage = null
}
}
private class xWebViewClient : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String?): Boolean {
if (url != null) {
view.loadUrl(url)
}
return true
}
}
}
Is there a way to make it work as composable?
Thanks
Can we embed activity inside composable
Not really.
If the activity you are trying to start is from some third-party app, or is yours but is not written in Compose UI, the best that you can do is try activity embedding on Android 12L and higher.
If the activity that you are trying to start is your own, and it itself is built in Compose UI, you could get rid of that activity and navigate to its composable.
You can try to reference the activity through an extenstion function:
inline fun <reified Activity : ComponentActivity> Context.getActivity(): Activity? {
return when (this) {
is Activity -> this
else -> {
var context = this
while (context is ContextWrapper) {
context = context.baseContext
if (context is Activity) return context
}
null
}
}
}
Usage:
#Composable
fun YourComposable() {
val activity = LocalContext.current.getActivity<MainActivity>()
}
I think a good way of approaching your solution is just to hoist the open of the webview outside your composable
Example
class MainActivity() {
setContent {
YourComposable(param1, param2) {
openWebViewCallBack
}
}
}
#Composable
fun YourComposable(param1:Int, param2:String, onWebViewOpen: (url:String) -> Unit) { ... }

Cannot finish register with register api

excuse me, in this code I want to send data into the database through registerReseller API. when I run this code with the virtual device, it works perfectly. while I run this code with real device, it works as well but some real device doesn't work. when it doesn't work on some device, the app does not crash or force close but stays on that page. Is anybody know how to fix this? Thank you
class RegisterFotoResellerActivity : AppCompatActivity() {
companion object {
val IMAGE_REQUEST_CODE = 1000
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register_foto_reseller)
iv_addimage.setOnClickListener{
ImageChooser()
}
}
private fun getRealPathFromURIPath(contentURI: Uri, activity: Activity): String? {
val cursor: Cursor? = activity.contentResolver.query(contentURI, null, null, null, null)
return if (cursor == null) {
contentURI.path
} else {
cursor.moveToFirst()
val idx: Int = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
cursor.getString(idx)
}
}
private fun ImageChooser() {
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, IMAGE_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == IMAGE_REQUEST_CODE && resultCode == RESULT_OK) {
val uri = data?.data
Glide.with(this)
.load(data?.data)
.apply(RequestOptions.circleCropTransform())
.into(iv_imageperson)
/*val uriPathHelper = URIPathHelper()
val filePath = uriPathHelper.getPath(this, uri!!)*/
//tv.setText(filePath)
btn_Verifikasi.setOnClickListener {
val filePath = uri?.let { getRealPathFromURIPath(it, this#RegisterFotoResellerActivity) }
val file = File(filePath!!)
val mFile: RequestBody = file.asRequestBody("image/*".toMediaTypeOrNull()) //membungkus file ke dalam request body
val body = MultipartBody.Part.createFormData("file", file.name, mFile)
val sharedPreferences = getSharedPreferences("sharedPrefs", android.content.Context.MODE_PRIVATE)
val savednohp = sharedPreferences.getString("nohp", null)
val savedpin = sharedPreferences.getString("pin", null)
val savednama = sharedPreferences.getString("namaReseller", null)
val alamatReseller = sharedPreferences.getString("alamatReseller", null)
val apiService = ApiService.getInstance().create(ApiEndpoint::class.java)
apiService.uploadimgreseller(body).enqueue(object : Callback<UploadImgResponse> {
override fun onResponse(call: Call<UploadImgResponse>, response: Response<UploadImgResponse>) {
val responseUpload = response.body()?.link.toString()
val apiService2 = ApiService.getInstance().create(ApiEndpoint::class.java)
apiService2.registerReseller( savednohp!!, savednama!!, responseUpload, alamatReseller!!, savedpin!!, 0)
.enqueue(object : Callback<ResponseBody> {
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
val sharedPreferencesLogin = getSharedPreferences("sharedPrefs", Context.MODE_PRIVATE)
val editor = sharedPreferencesLogin.edit()
editor.apply {
putString("login_nohp", savednohp)
putString("login_pin", savedpin)
putString("login_nama", savednama)
putString("login_alamat", alamatReseller)
putString("login_resplink", responseUpload)
putString("login_verified", 0.toString())
putString("login_key", "reseller")
}.apply()
val intent = Intent(this#RegisterFotoResellerActivity, Dashboard_user::class.java)
startActivity(intent)
finishAffinity()
}
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
Toast.makeText(this#RegisterFotoResellerActivity, "belum bisa", Toast.LENGTH_SHORT).show()
}
})
}
override fun onFailure(call: Call<UploadImgResponse>, t: Throwable) {
Log.d("TAG", "durung bisa kyeeehhh")
}
})
}
}
}
}

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() {...}

Pick file with registerForActivityResult on Androidx

I need to implement the select file option in my webviewActivity and all the tutorials I found have only the example with the startActivityResult, but it is currently deprecated and so I would like some help on how to transform this code to the new templates of a register as in the documentation: https://developer.android.com/training/basics/intents/result.
WebviewActivity.kt
class WebviewActivity: AppCompatActivity() {
val REQUEST_SELECT_FILE = 1
val FILE_CHOOSER_RESULT = 2
var uploadMessage: ValueCallback<Array<Uri>>? = null
var uploaded: ValueCallback<Uri>? = null
private fun launchWebview(url: String): WebView =
webview_id.apply{
loadUrl(url)
webViewClient : object = WebViewClient(){
//...//
}
webChromeClient : object = WebChromeClient(){
override fun onShowFileChooser(
webView: WebView?,
filePathCallback: ValueCallback<Array<Uri>>?,
fileChooserParams: WebChromeClient.FileChooserParams
): Boolean{
if (uploadMessage != null){
uploadMessage!!.onReceiveValue(null)
uploadMessage = null
}
uploadMessage = filePathCallback
val intent = fileChooserParams.createIntent()
startActivityForResult(intent, REQUEST_SELECT_FILE)
return true
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_SELECT_FILE){
uploadMessage!!.onReceiveValue(
WebChromeClient.FileChooserParams.parseResult(
resultCode, data
)
)
uploadMessage = null
} else if (requestCode == FILE_CHOOSER_RESULT){
val result = if (data == null || resultCode != RESULT_OK) null else data.data
uploaded!!.onReceiveValue(result)
uploaded = null
}
super.onActivityResult(requestCode, resultCode, data)
}
}
I used this link to make the code above: Android File Chooser not calling from Android Webview
You have to do sth. like that:
private fun createFile() {
getResult.launch("chartName.pdf")
}
private val getResult = registerForActivityResult(
CreateSpecificTypeDocument("application/pdf")
) { uri ->
if(uri != null){
contentResolver.openFileDescriptor(uri, "w")?.use {
FileOutputStream(it.fileDescriptor).use { fileOutputStream ->
//DO sth. with file
}
}
}
}
with:
class CreateSpecificTypeDocument(private val type: String) :
ActivityResultContracts.CreateDocument() {
override fun createIntent(context: Context, input: String): Intent {
return super.createIntent(context, input).setType(type)
}
}

Why FirebaseUser photoUrl run app not show?

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)

Categories

Resources