Java Android App Development Course, Creating Sign Up and Login Features

Android app development is an interesting field of mobile application development, and Java is widely used as the primary programming language for Android. This article will provide a detailed explanation of how to implement a simple sign-up and login feature using Java. In this process, we will use Android Studio and utilize Firebase as the backend for login and sign-up functionalities.

1. Project Setup

  1. Launch Android Studio.
  2. Create a new project. Select “Empty Activity” and enter the project name and package name.
  3. Create a project in the Firebase Console to integrate with Firebase, and add the Android app.
  4. Download the google-services.json file and add it to the app folder of the project.
  5. Modify the build.gradle file to add Firebase dependencies.

    dependencies {
        implementation 'com.google.firebase:firebase-auth:21.0.1'
        // Other dependencies
    }

2. Firebase Setup

Set up Firebase Authentication service to allow sign-up and login with email and password.

  1. Select Authentication in the Firebase Console and click “Get Started.”
  2. Enable “Email/Password” under sign-in methods.

3. Create XML Layouts

Create individual layout files for the sign-up and login screens.

activity_signup.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/signupEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Email" />

    <EditText
        android:id="@+id/signupPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Password"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/signupButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Sign Up" />

</LinearLayout>

activity_login.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/loginEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Email" />

    <EditText
        android:id="@+id/loginPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Password"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/loginButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Login" />

</LinearLayout>

4. Implement Java Code

Now, implement the sign-up and login functionalities in the Activity class.

SignupActivity.java


import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

public class SignupActivity extends AppCompatActivity {

    private EditText signupEmail, signupPassword;
    private Button signupButton;
    private FirebaseAuth mAuth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_signup);

        signupEmail = findViewById(R.id.signupEmail);
        signupPassword = findViewById(R.id.signupPassword);
        signupButton = findViewById(R.id.signupButton);

        mAuth = FirebaseAuth.getInstance();

        signupButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String email = signupEmail.getText().toString();
                String password = signupPassword.getText().toString();

                registerUser(email, password);
            }
        });
    }

    private void registerUser(String email, String password) {
        mAuth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, task -> {
                if (task.isSuccessful()) {
                    FirebaseUser user = mAuth.getCurrentUser();
                    Toast.makeText(SignupActivity.this, "Sign-up Successful: " + user.getEmail(), Toast.LENGTH_SHORT).show();
                    startActivity(new Intent(SignupActivity.this, LoginActivity.class));
                    finish();
                } else {
                    Toast.makeText(SignupActivity.this, "Sign-up Failed: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
    }
}

LoginActivity.java


import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

public class LoginActivity extends AppCompatActivity {

    private EditText loginEmail, loginPassword;
    private Button loginButton;
    private FirebaseAuth mAuth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        loginEmail = findViewById(R.id.loginEmail);
        loginPassword = findViewById(R.id.loginPassword);
        loginButton = findViewById(R.id.loginButton);

        mAuth = FirebaseAuth.getInstance();

        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String email = loginEmail.getText().toString();
                String password = loginPassword.getText().toString();

                loginUser(email, password);
            }
        });
    }

    private void loginUser(String email, String password) {
        mAuth.signInWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, task -> {
                if (task.isSuccessful()) {
                    FirebaseUser user = mAuth.getCurrentUser();
                    Toast.makeText(LoginActivity.this, "Login Successful: " + user.getEmail(), Toast.LENGTH_SHORT).show();
                    // Move to MainActivity
                } else {
                    Toast.makeText(LoginActivity.this, "Login Failed: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
    }
}

5. Testing

Run the app, sign up, and check if the login functionality works correctly. You can verify the registered user information through the Authentication section in the Firebase Console.

6. Conclusion

In this tutorial, we simply implemented the sign-up and login functionalities using Java in Android app development with Firebase. This basic feature will serve as a stepping stone to create more advanced applications.

We plan to cover more topics related to Android app development in the future. We hope this helps in your Android development journey!

References

Java Android App Development Course, Expanded Floating Action Button

In Android app development, the user interface (UI) is a very important element.
To enhance user experience, it is necessary to provide an intuitive and efficient UI.
In this article, we will take a look at the ‘Floating Action Button (FAB)’.
In particular, we will explain the extended floating action button in detail and guide you step by step on how to implement it.

What is a Floating Action Button (FAB)?

A floating action button is a circular button that floats in a specific area of the screen, usually representing the most important action.
For example, in a note app, it is a button for ‘Create New Note’, and in a chat app, it is a button for ‘Compose Message’.
FAB is very intuitive and helps users easily access important actions.

Need for an Extended Floating Action Button

While a basic FAB is optimized for a single action, there is a need for an extended version when it is necessary to show several related actions to the user.
An extended FAB shows multiple additional buttons or options when the user presses the button.
This allows users to perform a variety of tasks through more options.

Design of the Extended Floating Action Button

The design of the extended FAB can be broadly divided into two parts:
1. Basic FAB
2. Additional icons to show in the expanded state.
By combining these two elements well, an intuitive UI can be provided to the user.

Setting Up the Project in Android Studio

First, open Android Studio and create a new project.
Select ‘Java’ as the language and choose ‘Empty Activity’ to provide the basic template.

         
        // build.gradle (Module: app)
        dependencies {
            implementation 'com.android.support:design:28.0.0'
        }
        
    

By adding dependencies like the above, support for Material Components is added.
To use the latest version of libraries, set it up to use Google’s Maven repository.

Designing the Layout File

Open the ‘res/layout/activity_main.xml’ file and set up the basic layout.
Below is the XML code that includes the floating action button and additional buttons.

        
        <RelativeLayout 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">

            <com.getkeepsafe.taptargetview.TapTargetView
                android:id="@+id/tap_target_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:tapTarget="Create a new note here!"
                app:outerCircleColor="#f44336"
                app:targetCircleColor="#ffffff"
                app:textColor="#000000">
            </com.getkeepsafe.taptargetview.TapTargetView>

            <android.support.design.widget.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_alignParentBottom="true"
                app:srcCompat="@drawable/ic_add">
            </android.support.design.widget.FloatingActionButton>

            <LinearLayout
                android:id="@+id/expanded_menu"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:layout_alignParentEnd="true"
                android:layout_above="@id/fab"
                android:visibility="gone">

                <android.support.design.widget.FloatingActionButton
                    android:id="@+id/fab_item_1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:srcCompat="@drawable/ic_item1">
                </android.support.design.widget.FloatingActionButton>

                <android.support.design.widget.FloatingActionButton
                    android:id="@+id/fab_item_2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:srcCompat="@drawable/ic_item2">
                </android.support.design.widget.FloatingActionButton>

                <android.support.design.widget.FloatingActionButton
                    android:id="@+id/fab_item_3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:srcCompat="@drawable/ic_item3">
                </android.support.design.widget.FloatingActionButton>

            </LinearLayout>

        </RelativeLayout>
        
    

Implementation of MainActivity.java File

Open the ‘MainActivity.java’ file and add code to handle button click events.
Implement logic to expand or collapse the additional buttons when the FAB is clicked.

        
        package com.example.fabexample;

        import android.os.Bundle;
        import android.support.design.widget.FloatingActionButton;
        import android.support.v7.app.AppCompatActivity;
        import android.view.View;
        import android.widget.LinearLayout;

        public class MainActivity extends AppCompatActivity {
            private FloatingActionButton fab;
            private LinearLayout expandedMenu;

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                fab = findViewById(R.id.fab);
                expandedMenu = findViewById(R.id.expanded_menu);

                fab.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if (expandedMenu.getVisibility() == View.GONE) {
                            expandedMenu.setVisibility(View.VISIBLE);
                        } else {
                            expandedMenu.setVisibility(View.GONE);
                        }
                    }
                });

                findViewById(R.id.fab_item_1).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // Add action for item 1
                    }
                });

                findViewById(R.id.fab_item_2).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // Add action for item 2
                    }
                });

                findViewById(R.id.fab_item_3).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // Add action for item 3
                    }
                });
            }
        }
        
    

Adding Icons and Design Elements

Add the icons to be used in the ‘res/drawable’ folder of the project.
These icons provide clear indications for each action, helping users to easily recognize them.
Additionally, adjust the button’s color and size considering user feedback.

Adding Animation

To improve the transition effects of the extended FAB, you can add animations.
Smooth animations when the button expands or collapses can enhance the user experience.

        
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (expandedMenu.getVisibility() == View.GONE) {
                    expandedMenu.setVisibility(View.VISIBLE);
                    expandedMenu.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_down));
                } else {
                    expandedMenu.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_up));
                    expandedMenu.setVisibility(View.GONE);
                }
            }
        });
        
    

Creating Animation XML

Create slide animation XML files in the ‘res/anim’ folder.

        
        // slide_down.xml
        <translate xmlns:android="http://schemas.android.com/apk/res/android"
            android:fromYDelta=-100% 
            android:toYDelta=0
            android:duration=300 />

        // slide_up.xml
        <translate xmlns:android="http://schemas.android.com/apk/res/android"
            android:fromYDelta=0 
            android:toYDelta=-100%
            android:duration=300 />
        
    

Testing and Debugging

After writing the code and ensuring that all elements work perfectly,
test the app on various devices to check if the UI displays correctly.
You can test using either an emulator or a real device.

Conclusion

In this tutorial, we learned how to improve user experience in Android apps using the extended floating action button.
The FAB is a simple button, but if implemented correctly, it can provide significant convenience to users.
Based on what you learned in this tutorial, try adding various features to your app.

Additional Resources

Official Documentation for FloatingActionButton
Material Design Guidelines

Java Android App Development Course, Creating a To-Do List App

This course will teach you how to develop a simple To-Do List app using Java. It is aimed at individuals with basic knowledge of Android application development and will cover various concepts such as classes, lists, and databases. By the end of the course, you will be able to complete a basic To-Do List app.

1. Setting Up the Android App Development Environment

To develop Android apps, you need to install an integrated development environment (IDE) called Android Studio. Android Studio is officially supported by Google and optimized for Android app development. Here are the basic steps to set up the development environment:

  1. Visit the official Android Studio website and download the latest version.
  2. Run the downloaded file to install it.
  3. Once the installation is complete, run Android Studio.
  4. Install the SDK (Software Development Kit).

2. Creating a Project

To create a new project in Android Studio, follow these steps:

  1. Run Android Studio and select “Start a new Android Studio project.”
  2. Select “Empty Activity” and click “Next.”
  3. Specify the project name and set the package name, storage location, etc. Select “Java” as the language.
  4. Click “Finish” to create the project.

3. Designing the UI

Now let’s design the UI. The basic UI components of the To-Do List app are as follows:

  • EditText for inputting tasks
  • Button to add tasks
  • ListView to display the list of tasks

3.1 Modifying the XML Layout File

Open the res/layout/activity_main.xml file in Android Studio and modify it as follows:

        <?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">

            <EditText
                android:id="@+id/editTextTask"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Please enter a task" />

            <Button
                android:id="@+id/buttonAdd"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Add"
                android:layout_below="@id/editTextTask" />

            <ListView
                android:id="@+id/listViewTasks"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/buttonAdd" />
          
        </RelativeLayout>
    

4. Writing Java Code

After creating the layout, let’s write the Java code to add functionality. Open the MainActivity.java file, which is the main activity, and implement it as follows:

        package com.example.todolist;

        import android.os.Bundle;
        import android.view.View;
        import android.widget.ArrayAdapter;
        import android.widget.Button;
        import android.widget.EditText;
        import android.widget.ListView;

        import androidx.appcompat.app.AppCompatActivity;

        import java.util.ArrayList;

        public class MainActivity extends AppCompatActivity {

            private EditText editTextTask;
            private Button buttonAdd;
            private ListView listViewTasks;
            private ArrayList<String> tasks;
            private ArrayAdapter<String> adapter;

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                editTextTask = findViewById(R.id.editTextTask);
                buttonAdd = findViewById(R.id.buttonAdd);
                listViewTasks = findViewById(R.id.listViewTasks);

                tasks = new ArrayList<>();
                adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, tasks);
                listViewTasks.setAdapter(adapter);

                buttonAdd.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        String task = editTextTask.getText().toString();
                        if (!task.isEmpty()) {
                            tasks.add(task);
                            adapter.notifyDataSetChanged();
                            editTextTask.setText("");
                        }
                    }
                });
            }
        }
    

5. Running the App

After writing the code, follow these steps to run the app:

  1. Click the “Run” button in the toolbar of Android Studio.
  2. Select an emulator or a physical device.
  3. Once the app runs successfully, enter a task in the input field and click the “Add” button to confirm that the task is added to the list.

6. Implementing Additional Features

The basic To-Do List app is now complete. However, you can enhance the app by implementing additional features. Here are some features you can add:

  • Functionality to delete items from the task list
  • Functionality to mark items as completed
  • Implementing a database so that data persists even after exiting the app

6.1 Implementing the Delete Functionality

You can add functionality to delete an item when long-clicking an item in the ListView. Please add the following code to MainActivity.java:

        listViewTasks.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                tasks.remove(position);
                adapter.notifyDataSetChanged();
                return true;
            }
        });
    

6.2 Implementing the Completed Marking Feature

It is also useful to add a check mark to tasks when completed. Using RecyclerView makes it easier to manage a checklist, and you can add checkboxes for each item.

6.3 Integrating SQLite Database

To ensure that tasks persist even after exiting the app, you can use an SQLite database. You can create a SQLiteOpenHelper class to manage the database.

Conclusion

In this course, you learned how to develop an Android To-Do List app using Java. We covered not only how to create a basic app but also how to implement additional features. These basic components and concepts will serve as a foundation for developing more complex apps in the future. Continuous learning is essential in Android app development, so please try various projects.

Reference Materials

Java Android App Development Course, Fragment – A View that Works Like an Activity

In Android application development, various components are used to build the user interface (UI). Among these, the Fragment plays an important role alongside the Activity. In this course, we will explore the basic concepts, usage, advantages, and example code of fragments in depth, including how to apply fragments in practice.

1. What is a Fragment?

A fragment is a module that makes up part of the UI. Fragments, which have several advantages, help to manage complex UIs more easily and have a lighter structure than activities. Fragments can be reused multiple times within an activity and provide the flexibility to be configured differently based on various screen sizes and orientations (portrait/landscape).

2. Features of Fragments

  • Reusability: The same fragment can be reused in multiple activities, reducing code duplication.
  • Modularity: Each part of the UI can be modularized into fragments, creating an easily manageable structure.
  • Dynamic UI: Fragments can be added or removed at runtime, allowing for dynamic management of the UI.
  • Lifecycle Management: Fragments have their own lifecycle, which helps in easily managing the state of the user interface.

3. Lifecycle of a Fragment

Fragments manage their lifecycle separately from activities, but they are dependent on the activity’s lifecycle. Here are the main lifecycle methods of a fragment:

  • onAttach: Called when the fragment is attached to the activity.
  • onCreate: Called when the fragment is first created in the lifecycle.
  • onCreateView: Called to create the UI for the fragment.
  • onActivityCreated: Called when the activity and fragment initialization is complete.
  • onStart: Called when the fragment is ready to be displayed on the screen.
  • onResume: Called when the fragment is ready to interact with the user.
  • onPause: Called when the interaction with the user is temporarily paused.
  • onStop: Called when the fragment is no longer visible on the screen.
  • onDestroyView: Called when the UI of the fragment is removed.
  • onDetach: Called when the fragment is detached from the activity.

4. Creating a Fragment

The process of creating a fragment is very simple. First, define the fragment class, then create an XML layout file to set up the UI. Let’s create a fragment in the example below.

4.1. Creating a Fragment Class


import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;

public class MyFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_my, container, false);
    }
}

4.2. Creating an XML Layout File


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello from MyFragment!" />

</LinearLayout>

5. Adding a Fragment to an Activity

After creating a fragment, you need to add it to the activity. You can add the fragment either dynamically or statically in the XML layout. The example below shows how to add a fragment dynamically.

5.1. Creating a Space for the Fragment in the Activity Layout


<FrameLayout
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" /
>

5.2. Adding the Fragment in the Activity Class


import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyFragment myFragment = new MyFragment();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.fragment_container, myFragment);
        transaction.commit();
    }
}

6. Passing Data Between Fragments

You can use a Bundle to pass data between fragments. This method allows you to pass data when creating the fragment from the activity. The example below shows how to pass data to a fragment.

6.1. Passing Data to a Fragment


public static MyFragment newInstance(String data) {
    MyFragment fragment = new MyFragment();
    Bundle args = new Bundle();
    args.putString("key", data);
    fragment.setArguments(args);
    return fragment;
}

6.2. Receiving Data Inside the Fragment


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        String data = getArguments().getString("key");
        // Use the data to update the UI
    }
}

7. Managing Fragment Lifecycle

Managing the lifecycle of a fragment is very important. It’s necessary to update the UI or fetch data at the right moments. For example, you can run code to fetch data when the user is ready to view the fragment.


@Override
public void onStart() {
    super.onStart();
    // Fetch data when the fragment is visible on the screen
    loadData();
}

8. Adding Fragments to the Back Stack

The back stack feature helps users easily return to a previous fragment while navigating through fragments. You can activate this by using the `addToBackStack()` method when adding a fragment.


FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container, myFragment);
transaction.addToBackStack(null);
transaction.commit();

9. Advantages and Disadvantages of Fragments

9.1. Advantages

  • Improved maintainability with a modular UI.
  • Dynamic UI can adapt to various screens.
  • Reusable, reducing code duplication.

9.2. Disadvantages

  • Need to manage lifecycle between fragments and activities carefully.
  • Creating a complex UI structure can make management more difficult.

10. Conclusion

Fragments are very useful components in Android application development. They focus on modularizing the UI, enhancing reusability, and providing an interesting user experience suitable for various screen sizes. Based on the contents covered in this tutorial, we encourage you to effectively utilize fragments in your Android applications.

11. References

Java Android App Development Course, Setting Permissions

When developing an Android app, setting permissions is essential to use specific features or data. In this tutorial, we will learn in detail about the importance and methods of permission settings in Android app development using Java.

1. The Importance of Permissions

Permissions are the rights that allow the app to access specific features. For example, when accessing the camera, microphone, location information, or storage, permissions must be requested. If permissions are not set, these features cannot be used, and they play an important role in protecting user data and enhancing security.

1.1 Types of Permissions

In Android, permissions can be divided into two main types:

  • Normal Permissions: Features that do not significantly affect the user and are automatically granted during app installation. E.g., internet access.
  • Dangerous Permissions: Features that access sensitive user information and require explicit user consent. E.g., location information, camera access.

2. How to Set Permissions

There are two steps to set permissions in an Android app. We will look at each method based on the type.

2.1 Declaring Permissions in the AndroidManifest.xml File

All permissions must first be declared in the AndroidManifest.xml file. This file defines the app’s basic information, including permission settings.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.myapp">

    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <application
        ...
    >
        ...
    </application>

</manifest>

2.2 Requesting Runtime Permissions

Starting from Android 6.0 (API level 23), when using dangerous permissions, user approval must be requested at runtime. You can use the code below to request permissions.

import android.Manifest;
import android.content.pm.PackageManager;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {

    private static final int CAMERA_REQUEST_CODE = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
        } else {
            // If permission has already been granted
            Toast.makeText(this, "Camera permission has been granted.", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == CAMERA_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "Camera permission has been granted.", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Camera permission has been denied.", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

In the above code, the ContextCompat.checkSelfPermission() method checks if the permission has already been granted, and ActivityCompat.requestPermissions() requests approval. When the user chooses to allow or deny, the result is handled in the onRequestPermissionsResult() method.

3. Permission Handling Example

In the example below, we will request camera permission and implement functionality to take a photo if the user grants the request.

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {

    private static final int CAMERA_REQUEST_CODE = 100;
    private static final int IMAGE_CAPTURE_REQUEST = 1;
    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.imageView);
        Button button = findViewById(R.id.captureButton);

        button.setOnClickListener(v -> {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
            } else {
                openCamera();
            }
        });
    }

    private void openCamera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, IMAGE_CAPTURE_REQUEST);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == IMAGE_CAPTURE_REQUEST && resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");
            imageView.setImageBitmap(imageBitmap);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == CAMERA_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                openCamera();
            } else {
                Toast.makeText(this, "Camera permission has been denied.", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

In this example, the user is prompted to request camera permission, and if granted, the camera app is opened, allowing them to take a picture. The captured image is displayed in the ImageView.

4. Tips Related to Permissions

When using permissions, consider the following tips:

  • Request Minimum Permissions: Since users may not accept them, only request the permissions you need.
  • Provide a Clear Reason: It’s a good idea to provide a message that explains why the permission is needed, so users can understand the request.
  • Consider User Experience: To avoid disrupting the user’s flow during permission requests, ask for them at appropriate times.

5. Conclusion

In this tutorial, we discussed how to set permissions in Android apps. Since permissions are crucial in protecting user data, it is essential to set and request them correctly. Utilize what you learned in this tutorial when developing your apps in the future.

6. References