In my Android application users can choose to select an image from phone gallery or take a picture with camera. But i realized that Android OS turning off my application after users choose the "take a picture" option(probably because of the low memory) and open the device camera. After users take a picture and click save button, the OS try to open my application again but i am facing with below error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hms.socialsteps/com.hms.socialsteps.ui.MainActivity}: android.view.InflateException: Binary XML file line #21 in com.hms.socialsteps:layout/activity_main: Binary XML file line #21 in com.hms.socialsteps:layout/activity_main: Binary XML file line #21 in com.hms.socialsteps:layout/activity_main: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3526)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3665)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:151)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:111)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2228)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:7888)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:512)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:998)
Caused by: android.view.InflateException: Binary XML file line #21 in com.hms.socialsteps:layout/activity_main: Binary XML file line #21 in com.hms.socialsteps:layout/activity_main: Binary XML file line #21 in com.hms.socialsteps:layout/activity_main: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #21 in com.hms.socialsteps:layout/activity_main: Binary XML file line #21 in com.hms.socialsteps:layout/activity_main: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #21 in com.hms.socialsteps:layout/activity_main: Error inflating class fragment
Caused by: java.lang.IllegalArgumentException: Binary XML file line #21: Duplicate id 0x7f0a01d9, tag null, or parent id 0xffffffff with another fragment for androidx.navigation.fragment.NavHostFragment
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:117)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:136)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:248)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:227)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1069)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:997)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
at android.view.LayoutInflater.inflate(LayoutInflater.java:534)
at com.hms.socialsteps.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:45)
at com.hms.socialsteps.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:39)
at com.hms.socialsteps.ui.MainActivity$special$$inlined$viewBinding$1.invoke(ActivityViewBindingDelegate.kt:11)
at com.hms.socialsteps.ui.MainActivity$special$$inlined$viewBinding$1.invoke(ActivityViewBindingDelegate.kt:8)
at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)
at com.hms.socialsteps.ui.MainActivity.getBinding(MainActivity.kt:31)
at com.hms.socialsteps.ui.MainActivity.hideBottomNavigation(MainActivity.kt:72)
at com.hms.socialsteps.ui.base.BaseFragment.onAttach(BaseFragment.kt:25)
at com.hms.socialsteps.ui.activitydetails.Hilt_ActivityDetailsFragment.onAttach(Hilt_ActivityDetailsFragment.java:47)
at androidx.fragment.app.Fragment.performAttach(Fragment.java:3063)
at androidx.fragment.app.FragmentStateManager.attach(FragmentStateManager.java:464)
2023-04-18 19:37:10.444 8825-8825/com.hms.socialsteps E/AndroidRuntime: at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:254)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1424)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2968)
at androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:2875)
at androidx.fragment.app.Fragment.restoreChildFragmentState(Fragment.java:1990)
at androidx.fragment.app.Fragment.onCreate(Fragment.java:1965)
at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.kt:169)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:3090)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:475)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:257)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:142)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:136)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:248)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:227)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1069)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:997)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
at android.view.LayoutInflater.inflate(LayoutInflater.java:534)
at com.hms.socialsteps.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:45)
at com.hms.socialsteps.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:39)
at com.hms.socialsteps.ui.MainActivity$special$$inlined$viewBinding$1.invoke(ActivityViewBindingDelegate.kt:11)
at com.hms.socialsteps.ui.MainActivity$special$$inlined$viewBinding$1.invoke(ActivityViewBindingDelegate.kt:8)
at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)
at com.hms.socialsteps.ui.MainActivity.getBinding(MainActivity.kt:31)
at com.hms.socialsteps.ui.MainActivity.onCreate(MainActivity.kt:40)
at android.app.Activity.performCreate(Activity.java:7967)
at android.app.Activity.performCreate(Activity.java:7956)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1320)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3497)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3665)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:151)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:111)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2228)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:7888)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:512)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:998)
I found the code that causing this problem, that code is inside the BaseFragment's onAttach method like below:
override fun onAttach(context: Context) {
super.onAttach(context)
baseContext = context
if (!isBottomNavBarVisible){
(activity as MainActivity).hideBottomNavigation()
}
}
When i remove this code part, app is not crashing. Can anyone help me to solve this inflating problem ? What could be the reson for this error ?
My other related classses: MainActivity.kt
package com.hms.socialsteps.ui
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
val TAG = "MainActivity"
private val binding by viewBinding(ActivityMainBinding::inflate)
private val viewModel by viewModels<MainViewModel>()
private lateinit var snackbar: Snackbar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
getToken()
val navView: BottomNavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_main)
navView.setupWithNavController(navController)
observeNetworkStatus()
}
private fun observeNetworkStatus(){
snackbar = Snackbar.make(binding.root,
"There is no internet connection!",
Snackbar.LENGTH_INDEFINITE)
viewModel.networkMonitor.observe(this){ connection ->
if (!connection){
snackbar.show()
}else{
snackbar.dismiss()
}
}
}
fun showBottomNavigation()
{
binding.navView.visibility = View.VISIBLE
}
fun hideBottomNavigation()
{
binding.navView.visibility = View.GONE
}
@OptIn(DelicateCoroutinesApi::class)
fun getToken(){
GlobalScope.launch(Dispatchers.IO) {
try {
val appId = Constants.APP_ID
val tokenScope = "HCM"
val token = HmsInstanceId.getInstance(this@MainActivity).getToken(appId, tokenScope)
Timber.tag(TAG).i( "get token:$token")
// Check whether the token is null.
if (!TextUtils.isEmpty(token)) {
viewModel.setToken(token)
}
} catch (e: ApiException) {
Timber.tag(TAG).e( "get token failed, $e")
}
}
viewModel.tokenResult.observe(this){ result ->
when(result){
is Resource.Empty -> {}
is Resource.Error -> {
Timber.tag(TAG).e( "getToken: ${result.message}")
}
is Resource.Loading -> {
Timber.tag(TAG).d( "getToken: Upsert token started.")
}
is Resource.Success -> {
Timber.tag(TAG).d( "getToken: Token set.")
}
}
}
}
}
BaseFragment.kt
package com.hms.socialsteps.ui.base
abstract class BaseFragment : Fragment {
var baseContext: Context? = null
constructor() : super()
constructor(contentLayoutId: Int) : super(contentLayoutId)
abstract val isBottomNavBarVisible: Boolean
override fun onAttach(context: Context) {
super.onAttach(context)
baseContext = context
if (!isBottomNavBarVisible){
(activity as MainActivity).hideBottomNavigation()
}
}
override fun onDetach() {
super.onDetach()
if (isBottomNavBarVisible) {
(activity as MainActivity).showBottomNavigation()
}
}
override fun onResume() {
super.onResume()
with((requireActivity() as MainActivity)){
if (isBottomNavBarVisible)
showBottomNavigation()
else
hideBottomNavigation()
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Timber.v("LifeCycle", "${name()} onViewCreated")
}
private fun name(): String {
return this.javaClass.simpleName
}
fun createMemberAlertDialog(memberDialogViewBinding: MemberSelectionViewBinding, context: Context):
AlertDialog{
val memberDialogBuilder = AlertDialog.Builder(context)
memberDialogBuilder.setView(memberDialogViewBinding.root)
val memberAlertDialog = memberDialogBuilder.create()
memberAlertDialog.setCancelable(false)
return memberAlertDialog
}
fun createInformationAlertDialog(informationViewBinding: GroupCreationViewBinding, context: Context):
AlertDialog{
val dialogBuilder = AlertDialog.Builder(context)
dialogBuilder.setView(informationViewBinding.root)
val informationAlertDialog = dialogBuilder.create()
informationAlertDialog.setCancelable(false)
return informationAlertDialog
}
}
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=".ui.MainActivity">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
<fragment
android:id="@+id/nav_host_fragment_activity_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/main_nav" />
</androidx.constraintlayout.widget.ConstraintLayout>
ActivityDetailsFragment.kt
@AndroidEntryPoint
class ActivityDetailsFragment : BaseFragment(R.layout.fragment_activity_details) {
private val binding: FragmentActivityDetailsBinding by viewBinding(
FragmentActivityDetailsBinding::bind
)
private lateinit var dropDownMenu: PopupMenu
private lateinit var menu: Menu
private val mainViewModel: MainViewModel by activityViewModels()
private val postViewModel: PostViewModel by activityViewModels()
private val activitiesViewModel by viewModels<ActivitiesViewModel>()
private val editProfileViewModel by viewModels<EditProfileViewModel>()
private var activityId: String? = null
private lateinit var activity: Activities
private var imageUri: Uri? = null
private var croppedUri: Uri? = null
private val values = ContentValues()
@Inject
lateinit var userPreference: UserPreference
override val isBottomNavBarVisible: Boolean
get() = false
private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
takePhoto()
}else {
requireContext().showToastLong("Camera Permission not granted")
}
}
private val pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()){ uri ->
if (uri != null) {
startCrop(uri)
} else {
Timber.tag("PhotoPicker").d("No media selected")
}
}
private val cameraLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
try {
/*setActivityImage(imageUri)*/
startCrop(imageUri!!)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
private val cropImage = registerForActivityResult(CropImageContract()) { result ->
if (result.isSuccessful) {
croppedUri = result.uriContent
editProfileViewModel.setImageUri(croppedUri!!, activity, false)
/*setActivityImage(uriContent)*/
} else {
// An error occurred.
showSnackBarShort(result.error?.message ?: "Image crop failed!")
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.parentConstraintLayout.visibility = View.INVISIBLE
activityId = arguments?.getString("activityId")
initMenu()
initData()
initOnClickListeners()
initObserver()
}
private fun initObserver() {
editProfileViewModel.uploadResult.observe(viewLifecycleOwner) { result ->
when (result) {
is Resource.Empty -> {}
is Resource.Error -> {
hideProgressBar(binding.progressBar)
showSnackBarShort(result.message!!)
}
is Resource.Loading -> {
showProgressBar(binding.progressBar)
}
is Resource.Success -> {
hideProgressBar(binding.progressBar)
showSnackBarShort("Image uploaded successfully.")
setActivityImage(croppedUri, null)
}
}
}
}
private fun takePhoto() {
values.put(MediaStore.Images.Media.TITLE, "New asdasd")
values.put(MediaStore.Images.Media.DESCRIPTION, "From asd Camera")
imageUri = requireContext().contentResolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values
)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
cameraLauncher.launch(intent)
}
private fun startCrop(uri: Uri) {
cropImage.launch(
CropImageContractOptions(
uri = uri,
CropImageOptions(
guidelines = CropImageView.Guidelines.ON, fixAspectRatio = true,
outputRequestWidth = 800, outputRequestHeight = 800
)
)
)
}
}