Process: com.bignerdranch.android.on_callbabysitting, PID: 19624
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bignerdranch.android.on_callbabysitting/com.bignerdranch.android.on_callbabysitting.Home}: java.lang.IllegalStateException: recyclerv_view must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.IllegalStateException: recyclerv_view must not be null
at com.bignerdranch.android.on_callbabysitting.Home.onCreate(Home.kt:42)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
tools:context=".Home">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerv_view"
android:layout_width="match_parent"
android:layout_height ="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
package com.bignerdranch.android.on_callbabysitting
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.inflate
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.recycv1.*
import kotlinx.android.synthetic.main.sidebar.*
import java.lang.IllegalStateException
class Home : AppCompatActivity() {
var names = ArrayList<String>()
var imgUrls = ArrayList<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.homepage)
lateinit var context: Context
var helper = MyDBHelper(applicationContext)
var db = helper.readableDatabase
var rs = db.rawQuery("SELECT * FROM USERS", null)
rs.moveToFirst()
while(rs.isAfterLast == false)
{
names.add(rs.getString(rs.getColumnIndex("EMAIL")))
rs.moveToNext()
names.add(rs.getString(rs.getColumnIndex("FIRST_NAME")))
rs.moveToNext()
//names.add(rs.getString(rs.getColumnIndex("LAST_NAME")))
//rs.moveToNext()
}
recyclerv_view.layoutManager = LinearLayoutManager(this)
recyclerv_view.adapter = RecyclerViewAdapter(imgUrls, names, this)
/*names.add(editTextTextEmailAddress3.getText().toString())
names.add(editTextTextPassword.getText().toString())
//names.add(editTextTextEmailAddress3.getText().toString())
//names.add(editTextTextPassword.getText().toString())*/
//try {
// recyclerv_view.adapter = RecyclerViewAdapter.First(this, imgUrls, names)
//recyclerv_view.layoutManager = LinearLayoutManager(this)
// }catch (ignored: IllegalStateException)
//{
//}
//val recyclerView : RecyclerView = findViewById(R.id.recyclerv_view)
//val recyclerView = findViewById<RecyclerView>(R.id.recyclerv_view)
//recyclerView.setAdapter(first)
//recyclerView.setLayoutManager(LinearLayoutManager(this))
}
}
package com.bignerdranch.android.on_callbabysitting
import android.app.PendingIntent.getActivity
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.recyclerview.widget.RecyclerView
import de.hdodenhof.circleimageview.CircleImageView
import android.widget.TextView
import android.widget.LinearLayout
import com.bumptech.glide.Glide
import java.security.AccessController.getContext
open class RecyclerViewAdapter(val imgNames: ArrayList<String>, val imgPic: ArrayList<String>, val context: Context) : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
//var Context = context
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
{
// lateinit var cimg:CircleImageView
//lateinit var img:TextView
//lateinit var parentLayout: LinearLayout
val CircleImageView = itemView.findViewById<CircleImageView>(R.id.profile_image)
val TextView = itemView.findViewById<TextView>(R.id.textView19)
val TextView1 = itemView.findViewById<TextView>(R.id.textView18)
val TextView2 = itemView.findViewById<TextView>(R.id.textView20)
val parentLayout = itemView.findViewById<LinearLayout>(R.id.parent_layout)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
//var View = LayoutInflater.from(parent.getContext()).inflate(R.layout.homepage, parent, false)
//var viewHolder = ViewHolder(View)
return ViewHolder(LayoutInflater.from(context).inflate(R.layout.homepage, parent, false))
}
override fun getItemCount(): Int {
return imgNames.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
/* Glide
.with(context)
.asBitmap()
.load(imgPic.get(position))
.into(holder.CircleImageView)
var First = First(context,imgNames, imgPic)
First.imgN.add(imgNames.get(position))
*/
holder?.TextView?.text = imgNames.get(position)
holder?.TextView1.text = imgNames.get(position)
holder?.TextView2.text = imgNames.get(position)
holder?.parentLayout.parent
}
}
I am trying to have my code display the user's name at login in the home page, I can successfully move in from one activity to the next with a click, but when I add the recycler view in my home activity, it doesn't work. Attached is the recycler view XML, adapter activity, and my home class activity along with the log.
In your imports there are multiple UI's imported. Just check once where the recyclerview lies actually.
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.recycv1.*
import kotlinx.android.synthetic.main.sidebar.*
you've not initialized the recyclerv_view in the activity class.
Related
I'm trying develope single-activity application using the navigation to corresponding fragment from my home fragment under certain conditions (see my code fragment below). But when I start application with the condition isLoggedIn == true, an exception appears:
2022-05-01 17:42:22.888 14974-14974/com.example.shercofaqapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.shercofaqapp, PID: 14974
java.lang.IllegalStateException: Fragment LoginFragment{d69320f} (2bebfc01-ce4e-435e-be4f-821b5d142eb8 id=0x7f0a0096) did not return a View from onCreateView() or this was called before onCreateView().
at androidx.fragment.app.Fragment.requireView(Fragment.java:2008)
at com.example.shercofaqapp.view.LoginFragment.onCreateView(LoginFragment.kt:47)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2995)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:523)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2777)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3020)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2784)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:262)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:478)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425)
at android.app.Activity.performStart(Activity.java:7825)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
This is a fragment of my code:
package com.example.shercofaqapp.view
import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.navigation.Navigation
import com.example.shercofaqapp.R
import com.example.shercofaqapp.databinding.FragmentLoginBinding
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import kotlin.properties.Delegates
class LoginFragment : Fragment() {
lateinit var binding: FragmentLoginBinding
private var isLoggedIn by Delegates.notNull<Boolean>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val sharedPref = requireActivity()
.getSharedPreferences("MyPreferences", Context.MODE_PRIVATE)
val editor = sharedPref.edit()
var isLoggingIn = false
binding = DataBindingUtil.inflate(
inflater, R.layout.fragment_login, container, false)
binding.apply {
//Log in / sign up logic
isLoggedIn = sharedPref.getBoolean("isLoggedIn", false)
if (isLoggedIn) {
Navigation.findNavController(requireView())
.navigate(R.id.action_loginFragment_to_garageFragment)
}
}
return binding.root
}
}
The question is: how can I get view for Navigation before onCreateView() return it?
I tried to use this solution, but I don't understand what argument I should pass to .findNavController(...) in my case.
P.S. NavHostFragment is in MainActivity:
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/containerView"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph" />
</layout>
As per the Navigate to a destination documentation, you should use the findNavController() Kotlin extension on Fragment, which is a convenience wrapper around calling NavHostFragment.findNavController(this):
binding.apply {
//Log in / sign up logic
isLoggedIn = sharedPref.getBoolean("isLoggedIn", false)
if (isLoggedIn) {
// Make sure to:
// 1. Add a dependency on navigation-fragment-ktx in your build.gradle
// 2. import androidx.navigation.fragment.findNavController
findNavController()
.navigate(R.id.action_loginFragment_to_garageFragment)
}
}
findNavController(requireActivity())
.navigate(R.id.action_loginFragment_to_garageFragment)
use this code of line, I think it is helpful for you
Edit : If you are using it in fragment then,
Navigation.findNavController(getView()).navigate(R.id.action_loginFragment_to_garageFragment)
I'm trying to list song files on the device using RecycleView and get the following error:
Error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference
fragments.LoadFragment.loadTrackData(LoadFragment.kt:50)
fragments.LoadFragment.onCreate(LoadFragment.kt:36)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2949)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:475)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:278)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:524)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Line 50 is recycler_view.layoutManager = layoutManager
and line 36 is loadTrackData() calling the function that line 50 is in.
These lines are in the fragment I'm working in:
import android.Manifest
import android.content.pm.PackageManager
import android.database.Cursor
import android.os.Bundle
import android.provider.MediaStore
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.repea.Adapters.TrackListAdapter
import com.example.repea.R
import com.example.repea.TrackData.TrackData
import kotlinx.android.synthetic.main.fragment_load.*
class LoadFragment : Fragment() {
var trackData:ArrayList<TrackData> = ArrayList()
var trackListAdapter:TrackListAdapter?=null
companion object{
val PERMISSION_REQUEST_CODE = 12
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (context?.let { ContextCompat.checkSelfPermission(it.applicationContext,Manifest.permission.READ_EXTERNAL_STORAGE) } !=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this.requireActivity(),
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE),
PERMISSION_REQUEST_CODE)
}else{
loadTrackData()
}
}
fun loadTrackData(){
var trackCursor:Cursor? = activity?.applicationContext?.contentResolver?.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
null,null,null,null)
while (trackCursor!=null && trackCursor.moveToNext()){
var trackTitle = trackCursor.getString(trackCursor.getColumnIndex(MediaStore.Audio.Media.TITLE))
var trackLength = trackCursor.getString(trackCursor.getColumnIndex(MediaStore.Audio.Media.DURATION))
trackData.add(TrackData(trackTitle,trackLength))
}
trackListAdapter = TrackListAdapter(trackData)
var layoutManager = LinearLayoutManager(activity?.applicationContext)
recycler_view.layoutManager = layoutManager
recycler_view.adapter = trackListAdapter
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode == PERMISSION_REQUEST_CODE){
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(context?.applicationContext,"Permission Granted",Toast.LENGTH_SHORT).show()
loadTrackData()
}
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_load, container, false)
}
}
Here's the adapter:
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.recyclerview.widget.RecyclerView
import com.example.repea.R
import com.example.repea.TrackData.TrackData
class TrackListAdapter(TrackData:ArrayList<TrackData>):RecyclerView.Adapter<TrackListAdapter.TrackListViewHolder>() {
val dtrackData = TrackData
class TrackListViewHolder(itemView: ActionMenuItemView):RecyclerView.ViewHolder(itemView){
var titleTV:TextView
var lengthTV:TextView
var artTV:ImageView
init {
titleTV = itemView.findViewById(R.id.track_title_view)
lengthTV = itemView.findViewById(R.id.track_length_view)
artTV = itemView.findViewById(R.id.track_art_view)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackListViewHolder {
var view = LayoutInflater.from(parent.context).inflate(R.layout.load_item,parent,false)
return TrackListViewHolder(view as ActionMenuItemView)
}
override fun onBindViewHolder(holder: TrackListViewHolder, position: Int) {
var data = dtrackData[position]
var trackName = data.dTrackTitle
var trackLength = data.dTrackLength
holder.titleTV.text = trackName
holder.lengthTV.text = trackLength
}
override fun getItemCount(): Int {
return dtrackData.size
}
}
And the widget:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragments.LoadFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:clipToPadding="false"/>
</RelativeLayout>
What's gone wrong here?
You are not bind recycler_view with any view so it gives null, you should reference any view after inflate the layout that hold views.
here an example of using RecyclerView into Fragment class
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_blank, container, false)
view.recyclerView.layoutManager = LinearLayoutManager(activity)
view.recyclerView.adapter = MainAdapter()
return view
}
The error message saying that your recycler view is null and that because you used it before it created, so you should move the initialization to the onCreateView method
my thouts:
if (context?.let { ContextCompat.checkSelfPermission(it.applicationContext,Manifest.permission.READ_EXTERNAL_STORAGE) } !=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this.requireActivity(),
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE),
PERMISSION_REQUEST_CODE)
}else{
loadTrackData()
}
Try to muve this in onViewCreated()
Because your views inst loaded yet, when onCreate() is called
And i dint found where are you initialize recycler_view?
This question already has answers here:
findViewByID returns null
(33 answers)
NullPointerException when trying to access views in a Kotlin fragment
(9 answers)
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
I am new to android development. I have only been doing it for about a month now so I apologize if this is a simple question.
I am keep getting the following error when trying to run my app
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.swiperefreshlayout.widget.SwipeRefreshLayout.setOnRefreshListener(androidx.swiperefreshlayout.widget.SwipeRefreshLayout$OnRefreshListener)' on a null object reference
at edu.cogswell.tn.prism.MainActivity.onCreate(MainActivity.kt:54)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Here is my code
package (package name)
import android.app.AlertDialog
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.gson.Gson
import edu.cogswell.tn.prism.`interface`.NewsService
import edu.cogswell.tn.prism.adapter.viewHolder.ListSourceAdapter
import edu.cogswell.tn.prism.common.Common
import edu.cogswell.tn.prism.modle.WebSite
import io.paperdb.Paper
import kotlinx.android.synthetic.main.fragment_central.*
import retrofit2.Call
import retrofit2.Response
import javax.security.auth.callback.Callback
class MainActivity : AppCompatActivity() {
lateinit var layoutManager: LinearLayoutManager
lateinit var myService: NewsService
lateinit var adapter: ListSourceAdapter
lateinit var dialog: AlertDialog
var mSwipeRefreshLayout: SwipeRefreshLayout? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNaigationView)
val navController = findNavController(R.id.fragment)
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.central,
R.id.leftWing,
R.id.rightWing
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
bottomNavigationView.setupWithNavController(navController)
Paper.init(this)
myService = Common.newsService
swipe_to_refresh_centreal.setOnRefreshListener {
loadWebSiteSource(true)
}
recycler_view_source_news_central.setHasFixedSize(true)
layoutManager = LinearLayoutManager(this)
recycler_view_source_news_central.layoutManager = layoutManager
//dialog = SpotsDialog.Builder().setContext(this).build()
loadWebSiteSource(false)
}
private fun loadWebSiteSource(isRefresh: Boolean) {
if(!isRefresh){
val cache = Paper.book().read<String>("cache")
if(cache != null && !cache.isBlank() && cache != "null"){
val website = Gson().fromJson<WebSite>(cache, WebSite::class.java)
adapter = ListSourceAdapter(baseContext, website)
adapter.notifyDataSetChanged()
recycler_view_source_news_central.adapter = adapter
}
else{
dialog.show()
myService.sources.enqueue(object:retrofit2.Callback<WebSite>{
override fun onResponse(call: Call<WebSite>, response: Response<WebSite>) {
adapter = ListSourceAdapter(baseContext,response!!.body()!!)
adapter.notifyDataSetChanged()
recycler_view_source_news_central.adapter = adapter
Paper.book().write("cache", Gson().toJson(response!!.body()!!))
dialog.dismiss()
}
override fun onFailure(call: Call<WebSite>, t: Throwable) {
Toast.makeText(baseContext,"Failed",Toast.LENGTH_SHORT).show()
}
})
}
}
else{
swipe_to_refresh_centreal.isRefreshing = true
myService.sources.enqueue(object:retrofit2.Callback<WebSite>{
override fun onResponse(call: Call<WebSite>, response: Response<WebSite>) {
adapter = ListSourceAdapter(baseContext,response!!.body()!!)
adapter.notifyDataSetChanged()
recycler_view_source_news_central.adapter = adapter
Paper.book().write("cache", Gson().toJson(response!!.body()!!))
swipe_to_refresh_centreal.isRefreshing=false
}
override fun onFailure(call: Call<WebSite>, t: Throwable) {
Toast.makeText(baseContext,"Failed",Toast.LENGTH_SHORT).show()
}
})
}
}
}
Here is the xml code
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/swipe_to_refresh_centreal"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Central">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_source_news_central"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp" />
</RelativeLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Not too sure why I keep getting this error. I am using this tutorial https://www.youtube.com/watch?v=mvVcqzJYAbY
For reference.
Thank you in advance.
I see that you use kotlin synthetic properties here. It's deprecated. So I recommend using any other instrument instead. Even findViewById is better in my opinion.
So what's wrong here. It's an often issue related to kotlin synthetic properties - wrong imports.
Look, you do all actions in an activity, but imported
import kotlinx.android.synthetic.main.fragment_central.*
So this line import view from layout named fragment_central. But you inflated activity_main instead. So this view simply does not exist here.
You are importing wrong layout. Can you try this. Pass your main activity layout in import section and remove the swiperefresh layout from import as well as from variable declaratiion.
import kotlinx.android.synthetic.main.your_layout.*
Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
So i just learn kotlin for 3 weeks and i stuck
This is my MainActivity.kt
package com.go.personalitieslist
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.ContactsContract
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.appcompat.widget.Toolbar
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
private lateinit var rvPersonalities: RecyclerView
private var list: ArrayList<Personalities> = arrayListOf()
private lateinit var listPersonalitiesAdapter: ListPersonalitiesAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mtoolbar = findViewById<View>(R.id.toolbar) as Toolbar
setSupportActionBar(mtoolbar)
rvPersonalities = findViewById(R.id.rv_personalities)
rvPersonalities.setHasFixedSize(true)
list.addAll(PersonalitiesData.listData)
showRecyclerList()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.main_menu,menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
val intent = Intent(this, About::class.java)
when(id){
R.id.profile-> startActivity(intent)
}
return super.onOptionsItemSelected(item)
}
private fun showRecyclerList() {
rvPersonalities.layoutManager = LinearLayoutManager(this)
val listPersonalitiesAdapter = ListPersonalitiesAdapter(list)
rvPersonalities.adapter = listPersonalitiesAdapter
listPersonalitiesAdapter.setOnItemClickCallback(object : ListPersonalitiesAdapter.OnItemClickCallback {
override fun onItemClicked(data: Personalities) {
val detailIntent = Intent(this#MainActivity, DetailPage::class.java).apply {
putExtra(DetailPage.EXTRA_NAME,data.name)
putExtra(DetailPage.EXTRA_DETAIL,data.detail)
putExtra(DetailPage.EXTRA_PHOTO,data.photo)
}
showSelectedPersonalities(data)
startActivity(detailIntent)
}
})
}
private fun showSelectedPersonalities(personalities: Personalities) {
Toast.makeText(this, personalities.name, Toast.LENGTH_SHORT).show()
}
}
this is ListPersonalitiesAdapter.kt
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.item_row_personalities.view.*
class ListPersonalitiesAdapter(val listPersonalities:ArrayList<Personalities>) : RecyclerView.Adapter<ListPersonalitiesAdapter.ListViewHolder>() {
private lateinit var onItemClickCallback: OnItemClickCallback
fun setOnItemClickCallback(onItemClickCallback: OnItemClickCallback) {
this.onItemClickCallback = onItemClickCallback
}
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ListViewHolder {
val view: View = LayoutInflater.from(viewGroup.context).inflate(R.layout.item_row_personalities, viewGroup, false)
return ListViewHolder(view)
}
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
holder.bind(listPersonalities[position])
holder.itemView.setOnClickListener(){
onItemClickCallback.onItemClicked(listPersonalities[holder.adapterPosition])
}
}
/*
val personalities = listPersonalities[position]
Glide.with(holder.itemView.context)
.load(personalities.photo)
.apply(RequestOptions().override(55, 55))
.into(holder.imgPhoto)
holder.tvName.text = personalities.name
holder.tvDetail.text = personalities.detail
holder.itemView.setOnClickListener {
onItemClickCallback.onItemClicked(listPersonalities[holder.adapterPosition])
}
*/
override fun getItemCount(): Int {
return listPersonalities.size
}
class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(item : Personalities){
with(itemView){
tv_item_name.text = item.name
tv_item_detail.text = item.detail
Glide.with(this).load(item.photo).into(img_item_photo)
}
}
}
//var tvName: TextView = itemView.findViewById(R.id.tv_item_name)
// var tvDetail: TextView = itemView.findViewById(R.id.tv_item_detail)
// var imgPhoto: ImageView = itemView.findViewById(R.id.img_item_photo)
interface OnItemClickCallback {
fun onItemClicked(data: Personalities)
}
}
this is DetailPage.kt
class DetailPage : AppCompatActivity(){
companion object {
val EXTRA_NAME = "extra_name"
val EXTRA_DETAIL = "extra_detail"
val EXTRA_PHOTO = "extra_photo"
}
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail)
showDetailPersonalities()
}
private fun showDetailPersonalities(){
tv_item_name.setText(intent.getStringExtra(EXTRA_NAME))
tv_item_detail.setText(intent.getStringExtra(EXTRA_DETAIL))
Glide.with(this).load(intent.getIntExtra(EXTRA_PHOTO,0)).into(img_item_photo)
}
}
this is activity_detail.xml where the detail page show up
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="409dp"
android:layout_height="729dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/extra_photo"
android:layout_width="match_parent"
android:layout_height="422dp"
android:contentDescription="#string/todo"
tools:background="#drawable/ic_launcher_background" />
<TextView
android:id="#+id/extra_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="15dp"
android:fontFamily="sans-serif"
android:textAlignment="center"
android:textAppearance="#style/TextAppearance.AppCompat.Display1"
android:textSize="30sp"
android:textStyle="bold"
android:typeface="normal" />
<TextView
android:id="#+id/extra_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:fontFamily="sans-serif"
android:textAlignment="viewStart"
android:textSize="18sp" />
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
and this is the debugger massage
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.go.personalitieslist, PID: 14854
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.go.personalitieslist/com.go.personalitieslist.DetailPage}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.go.personalitieslist.DetailPage.showDetailPersonalities(DetailPage.kt:29)
at com.go.personalitieslist.DetailPage.onCreate(DetailPage.kt:23)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
You are setting text on TextViews with IDs of tv_item_name and tv_item_name in DetailPage activity but there's no TextView with these IDs in your activity_detail.xml.
What you want to do is calling extra_name and extra_detail instead:
private fun showDetailPersonalities(){
extra_name.setText(intent.getStringExtra(EXTRA_NAME)) //change this
extra_detail.setText(intent.getStringExtra(EXTRA_DETAIL)) //and this
Glide.with(this).load(intent.getIntExtra(EXTRA_PHOTO,0)).into(img_item_photo)
}
I have error in this code (
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter result)
And didn't save image
i will give you all the code:
MainActivity code:
package com.masreta87.backhussian
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.masreta87.backhussian.models.BlogPost
import com.masreta87.backhussian.models.DataSource
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private lateinit var blogAdapter:BlogRecyclerAdapter
lateinit var data: List<BlogPost>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initRecyclerView()
addDataSet()
}
private fun addDataSet(){
data=DataSource.createDataSet()
blogAdapter.submitList(data)
}
private fun initRecyclerView(){
recycler_view.apply {
layoutManager=LinearLayoutManager(this#MainActivity)
blogAdapter=BlogRecyclerAdapter()
adapter=blogAdapter
}
}
}
and BlogRecyclerAdapter.kt
package com.masreta87.backhussian
import android.content.Context
import android.graphics.Bitmap
import android.os.AsyncTask
import android.os.Environment
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.masreta87.backhussian.models.BlogPost
import kotlinx.android.synthetic.main.layout_blog_list_item.view.*
import java.net.URL
import android.os.Environment.getExternalStorageDirectory
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy
import java.io.File
import java.io.FileOutputStream
import java.lang.ref.WeakReference
import android.widget.Toast
import android.content.Intent
import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.net.Uri
import com.squareup.picasso.Picasso
import java.io.IOException
class BlogRecyclerAdapter :RecyclerView.Adapter<RecyclerView.ViewHolder>(){
private var items:List <BlogPost> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return BlogViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.layout_blog_list_item,parent,false)
)
}
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when(holder){
is BlogViewHolder ->{
holder.bind(items.get(position))
}
}
}
fun submitList(blogList: List<BlogPost>){
items = blogList
}
class BlogViewHolder constructor(
itemView:View
):RecyclerView.ViewHolder(itemView){
val blogImage:ImageView =itemView.blog_image
fun bind(blogPost:BlogPost){
val requestOptions =RequestOptions()
.placeholder(R.drawable.ic_launcher_background)
.error(R.drawable.ic_launcher_background)
Glide.with(itemView.context)
.applyDefaultRequestOptions(requestOptions)
.load(blogPost.image)
.into(blogImage)
itemView.setOnClickListener{
SaveImage(itemView.context,blogPost.image.toString() );
}
}
}
}
private fun SaveImage(context: Context, MyUrl: String) {
val progress = ProgressDialog(context)
class SaveThisImage : AsyncTask<Void, Void, Void>() {
override fun onPreExecute() {
super.onPreExecute()
progress.setTitle("Processing")
progress.setMessage("Please Wait...")
progress.setCancelable(false)
progress.show()
}
override fun doInBackground(vararg arg0: Void): Void? {
try {
val sdCard = Environment.getExternalStorageDirectory()
#SuppressLint("DefaultLocale") val fileName =
String.format("%dm.png", System.currentTimeMillis())
val dir = File(sdCard.absolutePath + "/Image")
dir.mkdirs()
val myImageFile = File(dir,fileName) // Create image file
**var fos:FileOutputStream? = null**
try {
Log.d("ala",myImageFile.toString())
**fos = FileOutputStream(myImageFile)**
val bitmap = Picasso.get().load(MyUrl).get()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)
val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
intent.data = Uri.fromFile(myImageFile)
context.sendBroadcast(intent)
} catch (e: IOException) {
e.printStackTrace()
} finally {
try {
fos!!.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
} catch (e: Exception) {
}
return null
}
override fun onPostExecute(result: Void) {
super.onPostExecute(result)
if (progress.isShowing) {
progress.dismiss()
}
Toast.makeText(context, "Saved", Toast.LENGTH_SHORT).show()
}
}
val shareimg = SaveThisImage()
shareimg.execute()
}
And BlogPost.class
package com.masreta87.backhussian.models
data class BlogPost(
var image:String
)
{
}
AND DataStore.class
package com.masreta87.backhussian.models
class DataSource{
companion object{
fun createDataSet(): ArrayList<BlogPost>{
val list = ArrayList<BlogPost>()
list.add(
BlogPost(
"https://firebasestorage.googleapis.com/v0/b/databaseim-56ef5.appspot.com/o/rpic%20(2).jpg?alt=media&token=138c2c3b-33ce-4a96-a7f5-74816af21809"
)
)
list.add(
BlogPost(
"https://firebasestorage.googleapis.com/v0/b/databaseim-56ef5.appspot.com/o/v1.png?alt=media&token=2e80d218-eb48-4c51-b51a-0fac43f76da7"
)
)
list.add(
BlogPost(
"https://firebasestorage.googleapis.com/v0/b/databaseim-56ef5.appspot.com/o/v10.jpg?alt=media&token=5e7207eb-1dac-41c0-bb3b-95abf9a54a2e"
)
)
list.add(
BlogPost(
"https://firebasestorage.googleapis.com/v0/b/databaseim-56ef5.appspot.com/o/v11.jpg?alt=media&token=2ab2b0c4-5ca1-4042-85c5-6d3e58181f45"
)
)
return list
}
}
}
And Mainifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:id="#+id/recycler_view"/>
</androidx.constraintlayout.widget.ConstraintLayout>
And layout_blog_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardElevation="10dp"
app:cardCornerRadius="2dp"
app:cardPreventCornerOverlap="false"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="610dp"
app:layout_constraintTop_toTopOf="parent"
android:id="#+id/blog_image"
android:background="#drawable/boder_image"
android:padding="10dp"
android:layout_margin="0dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
and full error:
2020-01-15 21:34:36.509 32083-32083/? E/AndroidRuntime: FATAL
EXCEPTION: main
Process: com.masreta87.backhussian, PID: 32083
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method
kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter
result
at com.masreta87.backhussian.BlogRecyclerAdapterKt$SaveImage$SaveThisImage.onPostExecute(Unknown
Source:2)
at com.masreta87.backhussian.BlogRecyclerAdapterKt$SaveImage$SaveThisImage.onPostExecute(BlogRecyclerAdapter.kt:86)
at android.os.AsyncTask.finish(AsyncTask.java:695)
at android.os.AsyncTask.-wrap1(Unknown Source:0)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
this is full error in app
Change the parameter type in
override fun onPostExecute(result: Void)
to
override fun onPostExecute(result: Void?).
And as Akhilesh Kumar mentioned here you should also change
class SaveThisImage : AsyncTask<Void, Void, Void>()
to
class SaveThisImage : AsyncTask<Void, Void, Void?>()
This is because the doInBackground in your code returns a nullable type Void?. The return value of doInBackground is passed as an argument to onPostExcecute but your onPostExecute accepts a non null value Void instead of a nullable one Void?.
As a side-note you should use Unit instead of Void when in Kotlin
EDIT
To make your saved image appear the media database needs to be updated. The media database is updated when you restart your device or after some time passes it will show up in the save location. To update the media database immediately you can use the MediaScannerConnection object.
Try passing your saved file to this function after bitmap.compress and pass your myImageFile
/**
* Updates the Pictures gallery to include the newly created file.
* #param fileObj: file path to be scanned so that the new file will appear in the gallery
*/
private fun refreshPhoneGallery(fileObj: File)
{
/* Scan the specified file path so that the new file will appear in gallery */
MediaScannerConnection.scanFile(
yourContext,
arrayOf(fileObj.path),
null,
object : MediaScannerConnection.OnScanCompletedListener
{
override fun onScanCompleted(scannedFilePath: String?, p1: Uri?)
{
// Do whatever
}
}
)
}