Showing posts with label Database. Show all posts
Showing posts with label Database. Show all posts

Tuesday, 30 May 2023

A Comprehensive React Native Tutorial: Building an App with User Database, Web API Integration, Charts, and Payment Integration.

React Native has emerged as a powerful framework for building cross-platform mobile applications using JavaScript and React. In this tutorial, we will explore how to create a feature-rich app using React Native that includes user database functionality, web API integration, charts for data visualization, and payment integration. By the end of this tutorial, you'll have a solid understanding of these key aspects and be equipped to develop your own robust mobile apps.

Prerequisites:

Before diving into this tutorial, you should have a basic understanding of JavaScript, React, and React Native. Additionally, familiarity with RESTful APIs and database concepts will be helpful.

Refer the below link for complete sample code:-

Download Sample Code

Let's get started with the step-by-step tutorial:

Step 1: Setting up the React Native Project

To begin, ensure that you have Node.js and npm installed on your machine. Create a new React Native project using the following command:

npx react-native init MyApp

Step 2: User Database
Implementing a user database is essential for many applications. We'll use Firebase, a cloud-based platform, to store and manage user data. Sign up for a Firebase account and create a new project.
Configure Firebase in your React Native app by adding the necessary credentials.
Next, install the Firebase SDK by running the following command within your project directory:

npm install firebase

Step 3: Web API Integration
To interact with web APIs, we'll use the popular fetch function provided by React Native. Create a new file, api.js, and define functions to handle API requests. You can make use of fetch and other JavaScript techniques to fetch data, send POST requests, etc.

Step 4: Data Visualization with Charts
React Native offers several charting libraries, such as Victory Native and React Native Charts Wrapper, that can be used to create visually appealing charts. Install a charting library of your choice and explore its documentation to learn how to create different types of charts, such as line charts, bar charts, or pie charts. Use the fetched data from the API in Step 3 to populate the charts.

Step 5: Payment Integration
To enable payment functionality, we'll integrate a payment gateway into our app. Popular options include Stripe, PayPal, or Braintree. Select a payment gateway of your choice, create an account, and follow their documentation to set up payment integration within your React Native app. Implement features like accepting payments, handling callbacks, and updating user data accordingly.

Step 6: User Interface and Navigation
Design an intuitive and user-friendly interface for your app using React Native's built-in components or third-party libraries like React Navigation. Create navigation flows between screens and ensure seamless user experience.

Step 7: Testing and Deployment
Testing your app thoroughly is crucial before deploying it to production. Utilize testing frameworks like Jest and Enzyme to write unit tests for your components and integration tests for your API calls. Once you're satisfied with the app's functionality and stability, prepare it for deployment. For Android, generate a signed APK, and for iOS, create an archive and submit it to the App Store.




Conclusion:
Congratulations! You have successfully built a feature-rich React Native app with user database functionality, web API integration, charts for data visualization, and payment integration. This tutorial has provided a comprehensive overview of each aspect, empowering you to build powerful and versatile mobile applications. Keep exploring React Native's vast ecosystem to enhance your app further and leverage its full potential. Happy coding!

Monday, 1 May 2017

HB Blog 134: Improve Android Applications Performance.

Hey guys, I hope you liked my previous post on app performance HB Blog 132: Does Your Phone Get Hang? Know Why...  . I got few mails and suggestions for posting similar kind of posts. So, here is my one more post for optimize your app's performance in various ways to improve its responsiveness and battery efficiency.
Basically, user expects app to launch app faster as well as load UI without any glitches. App launch can take place in one of three states, each affecting how long it takes for your app to become visible to the user: cold start, warm start, and lukewarm start. In a cold start, your app starts from scratch. In the other states, the system needs to bring the app from the background to the foreground.
At the beginning of a state, the system has three tasks. These tasks are:
  1.     Loading and launching the app.
  2.     Displaying a blank starting window for the app immediately after launch.
  3.     Creating the app process.
As soon as the system creates the app process, the app process is responsible for the next stages. These stages are:
  1.     Creating the app object.
  2.     Launching the main thread.
  3.     Creating the main activity.
  4.     Inflating views.
  5.     Laying out the screen.
  6.     Performing the initial draw.
There are few safety measures we can take for improving application performance such as,
  1. Remove unused resource IDs:- We often declare and find a view using android:id="@+id/view". But, while actual calling it in java classes is not needed. Sometimes, we don't need any changes in that particular view so e can avoid creating this ids. Because, these ids are creating public static final constant variable which are taking up unneeded memory.
  2. Remove unused resource:- Many times we keep on changing UI/UX so in that case we might add up resource but won't remove it once they are unused, so try to remove unused resource it may be images, icons as well as layout and other XML.
  3. Minimize load on onCreate():-  When your application launches, the blank starting window remains on the screen until the system finishes drawing the app for the first time. At that point, the system process swaps out the starting window for your app, allowing the user to start interacting with the app. If you’ve overloaded Application.oncreate() in your own app, the system invokes the onCreate() method on your app object. Afterwards, the app spawns the main thread, also known as the UI thread, and tasks it with creating your main activity. From Android 4.4 (API level 19), logcat includes an output line containing a value called Displayed. This value represents the amount of time elapsed between launching the process and finishing drawing the corresponding activity on the screen. We understand that which activity is taking more time for loading and using tools like Method Tracer, Inline Tracer, etc. It also gives which methods are the culprits, most of the time it is onCreate() method. We need to optimize the load of these method by initializing resource that are needed at startup itself. We can also use methods such as reportFullyDrawn() to let the system know that your activity is finished with its lazy loading.
  4. Use injection framework like Dagger:- Whether the problem lies with unnecessary initialization or disk I/O, the solution calls for lazy-initializing objects: initializing only those objects that are immediately needed. We can have a dependency injection framework like Dagger that creates objects and dependencies are when they are injected for the first time.
  5. Use Asynchronous operation:- Using a background thread ("worker thread") removes strain from the main thread so it can focus on drawing the UI. In many cases, using AsyncTask provides a simple way to perform your work outside the main thread. AsyncTask automatically queues up all the execute() requests and performs them serially. This behavior is global to a particular process and means you don’t need to worry about creating your own thread pool. For background database operations we can use compile statements can be used. Have a look on similar post for more information, HB Blog 95: How To Compile SQL Statement Into Reusable Pre-compiled Statement Object???
  6. Avoid Virtualization:- If you don't need to access an object's fields, make your method static. Invocations will be about 15%-20% faster. It's also good practice, because you can tell from the method signature that calling the method can't alter the object's state. In native languages like C++ it's common practice to use getters (i = getCount()) instead of accessing the field directly (i = mCount). This is an excellent habit for C++ and is often practiced in other object oriented languages like C# and Java, because the compiler can usually inline the access, and if you need to restrict or debug field access you can add the code at any time. However, this is a bad idea on Android. Virtual method calls are expensive, much more so than instance field lookups. It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly.
  7. Use Enhanced For Loop Syntax:- The enhanced for loop (also sometimes known as "for-each" loop) can be used for collections that implement the Iterable interface and for arrays. There are several alternatives for iterating through an array:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    static class Foo {
        int mSplat;
    }
    
    Foo[] mArray = ...
    
    public void zero() {
        int sum = 0;
        for (int i = 0; i < mArray.length; ++i) {
            sum += mArray[i].mSplat;
        }
    }
    
    public void one() {
        int sum = 0;
        Foo[] localArray = mArray;
        int len = localArray.length;
    
        for (int i = 0; i < len; ++i) {
            sum += localArray[i].mSplat;
        }
    }
    
    public void two() {
        int sum = 0;
        for (Foo a : mArray) {
            sum += a.mSplat;
        }
    }
    

    • zero() is slowest, because the JIT can't yet optimize away the cost of getting the array length once for every iteration through the loop. 
    • one() is faster. It pulls everything out into local variables, avoiding the lookups. Only the array length offers a performance benefit. 
    • two() is fastest for devices without a JIT, and indistinguishable from one() for devices with a JIT. It uses the enhanced for loop syntax introduced in version 1.5 of the Java programming language.
  8. Avoid complex Layout Hierarchies:- Layouts are a key part of Android applications that directly affect the user experience. If implemented poorly, your layout can lead to a memory hungry application with slow UIs. The Android SDK includes tools to help you identify problems in your layout performance, which will help to implement smooth scrolling interfaces with a minimum memory footprint. In the same way a complex web page can slow down load time, your layout hierarchy if too complex can also cause performance problems. If your application UI repeats certain layout constructs in multiple places, you can use the <include/> and <merge/> tags to embed another layout inside the current layout. Beyond simply including one layout component within another layout, you might want to make the included layout visible only when it's needed, sometime after the activity is running. Deferring loading resources is an important technique to use when you have complex views that your app might need in the future. You can implement this technique by defining a ViewStub for those complex and rarely used views.
  9. Use View Holder for listview:- Listview is one of the most important and very excessively used view. The key to a smoothly scrolling ListView is to keep the application’s main thread (the UI thread) free from heavy processing. Ensure you do any disk access, network access, or SQL access in a separate thread. The key to a smoothly scrolling ListView is to keep the application’s main thread (the UI thread) free from heavy processing. Ensure you do any disk access, network access, or SQL access in a separate thread. A way around repeated use of findViewById() is to use the "view holder" design pattern. A ViewHolder object stores each of the component views inside the tag field of the Layout, so you can immediately access them without the need to look them up repeatedly.
  10. Use 3rd party libraries carefully:- Actually, we use available libraries and resources for fasten our development time. It might not work as expected all the time and not all the design patterns and precautions are followed in these kinda libraries. So do explore complete libraries and then go for it. Android Arsenal is one of the interesting and helpful site which has categorized directory of libraries and tools for Android.

Sunday, 27 September 2015

HB Blog 95: How To Compile SQL Statement Into Reusable Pre-compiled Statement Object???

Database transactions are slow and in situations where there is need for thousands of records have to be inserted, inserting each record takes a lot of time and valuable resources.
Basically, insert() is convenience method for inserting a row into the database. But, for saving time and valuable resources we can use compile statement().  It compiles an SQL statement into a reusable pre-compiled statement object.

SQLite provides methods in SQLiteDatabase class can be used to make all the insert calls in the same batch in a single transaction. Start a transaction by calling the beginTransaction() method. Perform the database operations and then call the setTransactionSuccessful() to commit the transaction. Once the transaction is complete call the endTransaction() function.
    beginTransaction();
    compileStatement(String sql)
    setTransactionSuccessful();
    endTransaction();

Here is the standard idiom for transactions:
db.compileStatement (String sql)
db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}

Refer the below link for complete sample code:-
Download Sample Code
Download Apk File
Have a look on few code snippets,

MainActivity.java
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
package com.databasecompilestatement_as;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import com.dbUtils.DBManager;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;

public class MainActivity extends Activity {
    private ArrayAdapter<String> arrayAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button insert_raw_query = (Button) findViewById(R.id.insert_raw_query);
        Button insert_compile_statement = (Button) findViewById(R.id.insert_compile_statement);
        Button save_to_sdcard = (Button) findViewById(R.id.save_to_sdcard);
        ListView listView=(ListView)findViewById(R.id.listView);
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, arrayList);
        listView.setAdapter(arrayAdapter);

        final DBManager dbManager = new DBManager(MainActivity.this);
        insert_raw_query.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                long startTime = System.currentTimeMillis();
                dbManager.insertRawQuery(MainActivity.this);
                long diff = System.currentTimeMillis() - startTime;
                String result="insertRawQuery time diff: " + diff;
                arrayAdapter.add(String.valueOf(result));
            }
        });

        insert_compile_statement.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                long startTime = System.currentTimeMillis();
                dbManager.insertCompileStatement(MainActivity.this);
                long diff = System.currentTimeMillis() - startTime;
                String result="insertCompileStatement time diff: " + diff;
                arrayAdapter.add(result);
            }
        });


        save_to_sdcard.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                saveDatabaseToSdcard(MainActivity.this);
            }
        });
    }

    /**
     * save Database To Sdcard
     *
     * @param context
     */
    public static void saveDatabaseToSdcard(Context context) {
        try {
            InputStream myInput = new FileInputStream("/data/data/com.databasecompilestatement_as/databases/" + "hbdemodb.db");

            File file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "hbdemodb.db");
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                }
            }

            OutputStream myOutput = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/" + "hbdemodb.db");

            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }

            //Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ApplicationClass.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.dbUtils;

import android.app.Application;
import android.database.sqlite.SQLiteDatabase;

/**
 * This is application class is used to declare global variable at application level.
 * Created by harshalb
 */
public class ApplicationClass extends Application {
    private SQLiteDatabase mSqLiteDatabase;

    @Override
    public void onCreate() {
        DBHelper dbHelper = new DBHelper(getApplicationContext());
        mSqLiteDatabase = dbHelper.getWritableDatabase();
        super.onCreate();
    }


    /**
     * This method is used to get database object.
     *
     * @return SQLiteDatabase
     */
    public SQLiteDatabase getReadableDatabase() {
        if (mSqLiteDatabase == null || mSqLiteDatabase.isOpen() == false) {
            DBHelper dbHelper = new DBHelper(getApplicationContext());
            mSqLiteDatabase = dbHelper.getReadableDatabase();
        }

        return mSqLiteDatabase;
    }

    /**
     * This method is used to get database object.
     *
     * @return SQLiteDatabase
     */
    public SQLiteDatabase getWritableDatabase() {
        if (mSqLiteDatabase == null || mSqLiteDatabase.isOpen() == false) {
            DBHelper dbHelper = new DBHelper(getApplicationContext());
            mSqLiteDatabase = dbHelper.getWritableDatabase();
        }
        return mSqLiteDatabase;
    }

    /**
     * This method is used to close database object.
     */
    public void closeDB() {
        if (mSqLiteDatabase != null)
            mSqLiteDatabase.close();
    }
}

DBHelper.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.dbUtils;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * The DB helper class used to create database.
 * Created by harshalb
 */
public class DBHelper extends SQLiteOpenHelper {
    public static String DATABASE_NAME = "hbdemodb.db";
    static int DATABASE_VERSION = 1;

    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DatabasePojo.CREATE_TABLE_QUERY);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        super.onDowngrade(db, oldVersion, newVersion);
    }

    public void restoreDatabase() {
        SQLiteDatabase sqLiteDatabase = getWritableDatabase();
        sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + DatabasePojo.TABLENAME);
        sqLiteDatabase.execSQL(DatabasePojo.CREATE_TABLE_QUERY);
        sqLiteDatabase.close();
    }
}

DatabasePojo.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.dbUtils;

/**
 * This is database pojo class.
 * Created by harshalb
 */
public class DatabasePojo {

    public static String TABLENAME = "hbdemoTable";
    public static String CREATE_TABLE_QUERY = "CREATE TABLE IF NOT EXISTS " + TABLENAME + " ("
//            + "_id INTEGER PRIMARY KEY, " //Don't remove this column.
            + "name VARCHAR, "
            + "surname VARCHAR, "
            + "result VARCHAR "
            + ")";
    public int name;
    public int surname;
    public int result;
}

DBManager.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.dbUtils;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;


/**
 * This is a manager class used to manage database related information.
 * Created by harshalb
 */
public class DBManager {
    Context mContext;

    public DBManager(Context context) {
        this.mContext = context;
    }

    public void insertRawQuery(Context context) {
        ApplicationClass applicationClass = (ApplicationClass) context.getApplicationContext();
        SQLiteDatabase sqLiteDatabase = applicationClass.getWritableDatabase();

        for (int i = 0; i < 100; i++) {
            ContentValues values = new ContentValues();
            values.put("name", "rawname" + i);
            values.put("surname", "rawsurname" + i);
            values.put("result", i * i);
            sqLiteDatabase.insert(DatabasePojo.TABLENAME, null, values);
        }
    }

    public void insertCompileStatement(Context context) {
        ApplicationClass applicationClass = (ApplicationClass) context.getApplicationContext();
        SQLiteDatabase sqLiteDatabase = applicationClass.getWritableDatabase();
        String sql = "INSERT INTO " + DatabasePojo.TABLENAME + " VALUES (?,?,?);";
        SQLiteStatement statement = sqLiteDatabase.compileStatement(sql);
        sqLiteDatabase.beginTransaction();
        for (int i = 0; i < 100; i++) {
            statement.clearBindings();
            statement.bindString(1, "name" + i);
            statement.bindString(2, "surname" + i);
            statement.bindLong(3, i * i);
            statement.execute();
        }
        sqLiteDatabase.setTransactionSuccessful();
        sqLiteDatabase.endTransaction();
    }

}

activity_main.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<LinearLayout 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"
    android:orientation="vertical">

    <Button
        android:id="@+id/insert_raw_query"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Insert Raw Query" />

    <Button
        android:id="@+id/insert_compile_statement"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Insert Compile Statement" />

    <Button
        android:id="@+id/save_to_sdcard"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Save To Sdcard" />

    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/listView"
        android:layout_gravity="center_horizontal" />


</LinearLayout>

AndroidManifest.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.databasecompilestatement_as">

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21"></uses-sdk>

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

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:name="com.dbUtils.ApplicationClass"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Monday, 4 May 2015

HB Blog 71: Active Android - ORM (Object Relational Mapper).

Object-relational mapping is a programming technique for converting data between incompatible type systems in object-oriented programming languages. ActiveAndroid is an active record style ORM (object relational mapper). ActiveAndroid allows you to save and retrieve SQLite database records without ever writing a single SQL statement. Each database record is wrapped neatly into a class with methods like save() and delete().

There are few below steps to follow for using ActiveAndroid :-
1)Add ActiveAndroid library to your project. If you're using Android Studio, drag the jar to the libs folder of project and select "Add as a Library…".
2)Modify your build.gradle as below,
1
2
3
4
5
6
repositories {
    mavenCentral()
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}

compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'

3)Update Android Manifest file of your project for global setting as below,
1
2
3
4
5
6
7
8
<manifest>
    <application android:name="com.activeandroid.app.Application">

        <meta-data android:name="AA_DB_NAME" android:value="Pickrand.db" />
        <meta-data android:name="AA_DB_VERSION" android:value="5" />

    </application>
</manifest>

4)Just extend com.activeandroid.app.Application instead of android.app.Application or initialise using ActiveAndroid.initialize(this); in the Application class.
5)Finally the setup is completed and now you can now create the database model, create classes named your desired table name, which have annotated fields for each of the columns. Your class must extend the Model class and your members must be annotated using @Column. ActiveAndroid will handle primitive data types as well as relationships to other tables and date classes. ActiveAndroid creates an id field for your tables. This field is an auto-incrementing primary key.

Here is a sample example,
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
@Table(name = "Items")
public class Item extends Model {
        // If name is omitted, then the field name is used.
        @Column(name = "Name")
        public String name;

        @Column(name = "Category")
        public Category category;

        public Item() {
                super();
        }

        public Item(String name, Category category) {
                super();
                this.name = name;
                this.category = category;
        }
}

Friday, 3 April 2015

HB Blog 66: Android Persistent Application Storage.

Storing data has always been a important factor of every programming platforms. In Android specifically, there are several options for you to save persistent application data as follows,

Shared Preferences
    Store private primitive data in key-value pairs.
Internal Storage
    Store private data on the device memory.
External Storage
    Store public data on the shared external storage.
SQLite Databases
    Store structured data in a private database.
Network Connection
    Store data on the web with your own network server.

Shared Preferences is simply and editor which allows to store data in key-value pair. It is generally managed by getters and setters.You can use SharedPreferences to save any primitive data: booleans, floats, ints, longs, and strings. 
To write values:
    Call edit() to get a SharedPreferences.Editor.
    Add values with methods such as putBoolean() and putString().
    Commit the new values with commit()
To read values, use SharedPreferences methods such as getBoolean() and getString().

Internal storage allows to store data on device memory and it is used for private data.
To create and write a private file to the internal storage:
    Call openFileOutput() with the name of the file and the operating mode. This returns a FileOutputStream.
    Write to the file with write().
    Close the stream with close().
To read a file from internal storage:
    Call openFileInput() and pass it the name of the file to read. This returns a FileInputStream.
    Read bytes from the file with read().
    Then close the stream with close().

External storage is the storage place provided on sd-card. The data is public and can be accces by users directly.In order to read or write files on the external storage, your app must acquire the READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE system permissions.
Below is the code snippet, to save database file to Sd-Card,
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 public static void saveDatabaseToSdcard(Context context) {
        try {
            InputStream myInput = new FileInputStream("/data/data/com.example/databases/" + "MyDB.db");

            File file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "MyDB.db");
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                }
            }

            OutputStream myOutput = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/" + "MyDB.db");

            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }

            //Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();
        } catch (Exception e) {
        }
    }

SQLite Databases allows to store structured data in a private database. SQLite is a software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. The recommended method to create a new SQLite database is to create a subclass of SQLiteOpenHelper and override the onCreate() method, in which you can execute a SQLite command to create tables in the database.

Network Connection allows to store data on the web with your own network server. To store and retrieve data web-based services can be written. To do network operations, use classes in the following packages,

    java.net.*
    android.net.*