Tag: Android

  • Grant, revoke permissions via Android Studio Terminal (ADB Shell) // Android Dev Diary

    To grant and revoke permissions via Terminal (ADB Shell), run your app on an emulator (I haven’t personally tried on a device but it should work there too).

    Open your Terminal, and then enter the following command:

    adb shell

    Once you’re in, you may use the following syntax for granting or revoking your Android device’s permissions:

    pm grant <package-name> <permission>

    For example, to grant a permission:

    pm grant net.catzie.myapp android.permission.READ_EXTERNAL_STORAGE

    pm grant net.catzie.myapp android.permission.WRITE_EXTERNAL_STORAGE

    And to revoke a permission:

    pm revoke net.catzie.myapp android.permission.READ_EXTERNAL_STORAGE

    pm revoke net.catzie.myapp android.permission.WRITE_EXTERNAL_STORAGE

    Now there’s no need to open the settings screen on your device to play with your Android permissions!

  • A working shared ViewModel between parent and child Fragments //Android Kotlin Dev Diary

    I initially had a problem with the shared ViewModel because the child fragments were creating a new instance from the one held by the parent fragment.

    The ViewModel instantiations below work for me:

    CreateLogFragment.kt (parent)

    CreateLogFoodFragment.kt (child)

    CreateLogNotesFragment.kt (another child)

    by activityViewModels turned things around!

  • My Fave Android Studio Keyboard Shortcuts

    I have been working on small Android apps, and I just want to share some of my favorite keyboard shortcuts. Some of them were manually added by me.

    Keyboard shortcuts are one of my must-haves for productivity as a programmer, as they let me navigate through code faster, allowing me to focus on creating new modules and solving problems.

    Note: I am using Windows.

    Move between Code, Split, and Design when working on an XML layout file

    Alt + Shift + Left/Right Directional Button
    (If it doesn’t work, click on the layout file’s code/design first, then retry.)

    Run app in test device or emulator

    Shift + F10

    Run app in test device or emulator with Debugger

    Shift + F9

    Navigate between open tabs (no split):

    Navigate between points/screens that you’re viewing:

    Ctrl + Alt + Left/Right

    Show Parameter Info while filling in a function call

    Ctrl + P

    Maximize/minimize editor

    Ctrl + Shift + F12

    Created a custom shortcut for Close All Tabs:

    Ctrl + Alt + Shift + F4

    Created a custom shortcut for Rebuild Project:

    Ctrl + Alt + Shift + F10

    Created a custom shortcut to toggle Distraction-Free Mode on/off:

    Ctrl + Alt + Shift + D

    Created a custom shortcut to toggle ZenMode on/off:

    Ctrl + Alt + Shift + Z

    Other keyboard shortcuts: https://developer.android.com/studio/intro/keyboard-shortcuts

  • val vs. const //Kotlin Android Dev Diary

    Let’s start off by introducing val.

    To define a variable in Kotlin, you may use var or val:

    varval
    has a mutable value (changeable)has an immutable value (read-only)

    So we use val for immutable values, so what is the const keyword and what’s its difference from val?

    constval
    has an immutable value (read-only)has an immutable value (read-only)
    initialized at compile time onlyvalue may be assigned during runtime

    Other rules for const in Kotlin:

    • must be a top-level property or placed within a companion object
    • value must be a primitive type (can never have function or any class constructor as its value)
    • no custom getter
  • Error: Type mismatch. Required: ActivityMainBinding. Found: ViewDataBinding! //Android Kotlin Dev Diary

    The problem is that this line of code is producing an error:

            binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
    

    And the error says:

    Type mismatch.
    Required:
    ActivityMainBinding
    Found:
    ViewDataBinding!

    The solution is to add a <layout> tag in the layout file that you are inflating!

  • Error inflating class androidx.fragment.app.FragmentContainerView // Android Kotlin Dev Diary

    The cause of error in Logcat:

         Caused by: android.view.InflateException: Binary XML file line #9 in net.catzie.sampleapp:layout/activity_main: Binary XML file line #9 in net.catzie.sampleapp:layout/activity_main: Error inflating class androidx.fragment.app.FragmentContainerView
         Caused by: android.view.InflateException: Binary XML file line #9 in net.catzie.sampleapp:layout/activity_main: Error inflating class androidx.fragment.app.FragmentContainerView
         Caused by: java.lang.IllegalStateException: no start destination defined via app:startDestination for net.catzie.sampleapp:id/nav_graph

    The fix was to add a startDestination to <navigation> tag in the nav_graph.xml.

  • Expand ScrollView vertically if height is smaller than screen // Android Dev Diary

    I have the following XML layout code in an Android app that I’ve been tinkering with:

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    
        <data>
            <variable
                name="viewModel"
                type="net.catzie.sampleapp.MainViewModel" />
        </data>
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <GridLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#aaa"
                android:columnCount="4"
                android:rowCount="5">
    
                ...
    
            </GridLayout>
        </ScrollView>
    </layout>

    I wrapped my GridLayout in a ScrollView because on the landscape orientation of the Android app’s screen, my grid contents are cut from the view because they’re too tall, and there’s no way to see them without a scrollbar, which the ScrollView provides.

    That gave birth to another problem though. The landscape view looks fine, but the vertical view became too short!

    After a few clicks at Google search results I found something that helped:

    android:fillViewport="true"

    I added the above attribute to my ScrollView, and voila! A GridLayout that scrolls vertically on landscape view, and fits the height of the Android device screen perfectly on portrait view~

  • DataBinderMapperImpl Error: cannot find symbol (DataBinding) //Android Kotlin Dev Diary

    Today I encountered the following error as I was building an Android app:

    DataBinderMapperImpl.java:18: error: cannot find symbol
    import net.catzie.myproject.databinding.ActivityMainBindingImpl;
    ^
    symbol: class ActivityMainBindingImpl
    location: package net.catzie.myproject.databinding

    Turns out, there’s an error in the related XML file, activity_main.xml! 😂

    For other possible solutions, this StackOverflower answer may help: android: data binding error: cannot find symbol class

  • Cannot access ‘‘: it is private in ‘MoshiConverterFactory’ //Android Kotlin Dev Diary

    I’m starting a new category on my blog — Dev Diary, to document some of the errors that I encounter and what I did to fix them. I’m doing this in hopes of helping developers (including my future self!) as they work with code (and to get more blog visits! LOL). It’s nice to save time fixing a problem that you have already encountered and fixed before.

    Today’s problem:

    You are creating an instance of a class such as MoshiConverterFactory, but you get an error that says Cannot access '<init>': it is private in 'MoshiConverterFactory'

    The solution:

    Use the .create() method of the MoshiConverterFactory, like so:

    .addConverterFactory(MoshiConverterFactory.create(moshi))

  • Android app dev: Intent extras set in onBackPressed() misssing when back to onActivityResult()

    It’s funny how we spent about an hour trying to figure out why the Intent extras that we’re setting are not being sent back to onActivityResult(). If we only knew that the solution was as simple as moving one line of code.

    The call to super.onBackPressed() should be placed after setting Intent extras and after finishing the current activity. Like so: