Open In App

How to Access SQLite Database in Android For Debugging?

Last Updated : 29 Oct, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

A software library that provides a relational database management system is called SQLite. It allows the users to interact with RDBMS. The lite in SQLite denotes the lightweight when it comes to setup, database administration, and resources required. In SQLite, a database is stored in a single file — a property that differentiates it from other database engines. The SQLite code is open source and available publicly. It can be used for any purpose and free of cost. It’s the most widely deployed database around the globe and includes very high-profile projects such as Whatsapp. It is a very compact library. The library size depends on the target platform and compiler settings, but it can be less than 600KiB even after enabling all the features. SQLite’s response to memory allocation failures and disk I/O errors is very graceful. All the transactions in SQLite follow ACID properties, even if it is interrupted by system crashes or even power failures. All the transactions are verified by automated tests. SQLite has the following major features: self-contained, serverless, zero-configuration, transactional.

Advantages of SQLite

1. Self Contained

The self-contained property of SQLite means that it requires minimum support from the OS(operating system) or any external library. This enables SQLite to be usable in any type of environment, especially in embedded devices like Android, iPhone, game consoles, etc. ANSI-C is used to develop SQLite. Its source code is available as a big sqlite3.c and its header file sqlite3.h. If anyone wants to enable the use of SQLite in their app, they just need to drop these files in the project and compile them in the code.  

2. Serverless

RDBMS such as MySQL, PostgreSQL requires a separate server process to operate. The applications that need to access the database server uses TCP/IP protocol to send and receive requests. This is termed Client/server architecture. The following diagram explains the RDBMS client/server architecture:

Whereas SQLite does not work in this manner, it doesn’t require a server to run. In SQLite database is integrated with the application that accesses it. The application directly interacts with the database, reading and writing from the database files stored on the disk. The following diagram explains the SQLite server-less architecture:

3. Zero configuration

For using SQLite, no installation is required due to its serverless architecture. No server process is present that needs to be configured, started, and stopped. Also, SQLite does not use any configuration files.

4. Transactional

All the transactions in SQLite are completely ACID-compliant. It means all queries and changes are Atomic, Consistent, Isolated, and Durable. All the changes within a transaction either take place completely or not at all even when an unexpected situation like application crash, power failure, or operating system crash occurs.

Methods to Access SQLite Database in Android for Debugging

Method 1: Stetho

It is a simple library from Facebook, which can be used to easily debug network calls. While using Stetho, there is no need to add logs during the development phase and remove them while releasing. The debugger is not needed. In 3 easy steps, we are able to get all the network calls on our Chrome browser. All network requests getting fired from the application, such as latency, fire sequence, request params, response data. In Stetho, there are many more features apart from network inspection.

Step 1: Add dependency in build.gradle

implementation 'com.facebook.stetho:stetho:1.5.1'
implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1'                          
implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1'

Javascript Console can also be added

implementation 'com.facebook.stetho:stetho-js-rhino:1.5.1'

Step 2: Initialize it in the application class with one line of code

public class MyApplication extends Application {
    public void onCreate() {
        super.OnCreate();

        if(BuildConfig.DEBUG) {

            Stetho.initializeWithDefaults(this)
        }
    }
}

Register the class in AndroidManifest.xml

<manifest
       xmlns:android="http://schemas.android.com/apk/res/android"
       ...>
       <application
               android:name="MyApplication"
               ...>
        </application>
</manifest>  

Step 3: Enable network inspection

If OkHttp library at 3.x release is being used, then one can use the interceptors system to add data to the existing stack, that too automatically. This is the most straightforward way to enable network inspection.

OkHttpClient.Builder()
  .addNetworkInterceptor(StethoInterceptor())
  .build()

Interceptors are the mechanism used to monitor, retry and rewrite network calls. The setup to inspect every call arising from the app is complete, now the steps to see them in Chrome browser remain.

Step 4: Setup Chrome DevTool to inspect

Client or server protocol provided by the Stetho software provides for the application, are used to implement the integration of Chrome DevTools. Now open Chrome and connect the device which is having the app.

Enter chrome://inspect in the URL bar of Chrome. 

Hit enter and the connected devices will be displayed.

All the devices with USB debugging options will be shown here, also all the apps on the device with stetho integrated. Click on inspect below the app name, a new window opens and it gives an overview of all the services in a list format with all the details. Any duplicate request being fired will also be displayed. Clicking on any single request shows three different sections – Headers, preview, and response. Click on each one to view the individual section.

Step 5: Database inspection with Stetho

When the pop window is opened after clicking on inspecting, select resources at the top. Many options will appear on the left side, select Web SQL from it, it’s a dropdown where all the app databases are seen. By clicking on any table, it shows the structure with all the data inside it. There is also absolutely no need to export or import things. Queries to check the result can also be executed. Click on the .db file and an editor will open up on the right side. Write queries depending on the requirements.

Method  2: Using Shell 

  1. Enable Developer option in Android device
  2. Enable USB debugging
  3. Connect your device via USB
  4. When prompted ‘Allow USB debugging. Click OK.

Unix Shell can be used to run a variety of commands on a device. Android Debug Bridge(adb) provides access to it. Open ADB’s shell from the command prompt by running ADB shell. This shell can be used to copy the database out of the applications directory and paste it to any location on the device. 

hell@device:/ $ mkdir /sdcard/data/
shell@device:/ $ run-as <com.your.package>
shell@device:/data/data/com.your.package $ cp databases/<database>.db /sdcard/data/
shell@device:/data/data/com.your.package $ exit
shell@device:/ $ exit

Now the database file is accessible from “/sdcard/data/”. One can use ADB pull to pull the file to the localhost:

adb pull /sdcard/data/<database>.db

Similarly, you can use ADB push to push a file to the device and therefore update the database. Simply execute the steps in reverse.

Open the database

A copy of the application’s database is created. Now an SQLite compatible database explorer is required to open the database. SQLite database browser is one of the best tools for browsing and editing SQLite database files. It’s open-source software available for Windows, macOS, and Linux.

Method 3: Using Android Debug Database (ADD)

Tasks done by Android debug database:

  • See all the databases.
  • See all the data in the shared preferences used in the application.
  • Run any SQL query on the given database to update and delete the data.
  • Directly edit the database values.
  • Directly edit shared preferences.
  • Directly add a row in the database.
  • Directly add a key value in the shared preferences.
  • Delete database rows and shared preferences.
  • Search in the data.
  • Sort data.
  • Export Database.
  • Check the Database version.
  • Download database

Prerequisite:

Before implementing the Android debug database library in the app, a few things need to be taken care of

  1. Android device and laptop should be on the same network. (LAN or Wifi)
  2. If using a mobile phone over USB, execute the following command in the terminal
adb forward tcp:8080 tcp:8080

If you need to use any other port than 8080, make the following changes in the build.gradle file

debug {
   resValue("string", "PORT_NUMBER", "8081")
}

Using Android Debug Database library

Add the following dependency to start using the Android debug database in the app. Add this dependency in build.gradle file.

dependencies {
   ...
   debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
   ...
}

Now run the application, you will see a similar entry to one given below in the logcat.

D/DebugDB: 

Open http://XXX.XXX.X.XXX:8080 in your browser

To get the debug address URL from the code, just call the below method:

DebugDB.getAddressLog();

Open the URL in the browser and an interface will open up, showing all the details related to the databases and shared preferences.

Add. Delete or edit operations on the values present in the table can be done easily just by clicking on the add, delete or edit button respectively

Any database operation can also be done using the SQL query, just type the query in the query section and the Android debug database will do the rest.

Getting Debug Address URL in Toast

Debug address can also be displayed using the Toast message. It can be done using the following code.

public static void showDebugDBAddressLogToast(Context context) {
   if (BuildConfig.DEBUG) {
      try {
           Class<?> debugDB = Class.forName("com.amitshekhar.DebugDB");
           Method getAddressLog = debugDB.getMethod("getAddressLog");
           Object value = getAddressLog.invoke(null);
           Toast.makeText(context, (String) value, Toast.LENGTH_LONG).show();
      } catch (Exception ignore) {

      }
   }
}

Adding Custom Database Files

The Android Database Library is auto-initialized, to debug a custom database file, add the below method and call it.

public static void setCustomDatabaseFiles(Context context) {
   if (BuildConfig.DEBUG) {
       try {
           Class<?> debugDB = Class.forName("com.amitshekhar.DebugDB");
           Class[] argTypes = new Class[]{HashMap.class};
           Method setCustomDatabaseFiles = debugDB.getMethod("setCustomDatabaseFiles", argTypes);
           HashMap<String, Pair<File, String>> customDatabaseFiles = new HashMap<>();
           // set your custom database files
           customDatabaseFiles.put(ExtTestDBHelper.DATABASE_NAME,
                   new Pair<>(new File(context.getFilesDir() + "/" + ExtTestDBHelper.DIR_NAME +
                                                   "/" + ExtTestDBHelper.DATABASE_NAME), ""));
           setCustomDatabaseFiles.invoke(null, customDatabaseFiles);
       } catch (Exception ignore) {

       }
   }
}

Disadvantage of SQLite

SQLite’s signature feature, which makes it very much different from others, is its portability. Unfortunately, it makes it a poor choice when many different users are updating the same table simultaneously. It’s a golden rule, to maintain the integrity of data, only one user can write to the file at a time. It also requires more work to ensure the security of private data due to features that make SQLite accessible. SQLite is quite different from other database systems, it limits many advanced features that are offered by other relational database systems. SQLite does not validate data types. SQLite allows users to store data of any type into any column, whereas many other database software would reject data that does not conform to a table’s schema.

SQLite creates schemas, which limit the type of data in each column, but it does not enforce them. The example below shows that the id column wants to store integers, the name column wants to store text, and the age column wants to store integers:

CREATE TABLE celebs (
 id INTEGER,
 name TEXT,
 age INTEGER
);

SQLite will never reject values of the different data types. We may insert the wrong data types in the columns. Storing different data types in the same column is unacceptable behavior that can lead to unfixable errors, so it’s required to be consistent about the data that goes in a particular column, even though SQLite will not enforce it.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads