Unit-IV
Working with Storage, Database
Android Storage:
In android, we have different storage options such as shared preferences, internal
storage, external storage, SQLite storage, etc. to store and retrieve the application data
based on our requirements.
In android,
1.Android Internal Storage:
1. Internal Storage is useful to store the data files locally on the device’s internal
memory using a FileOutputStream object.
2. After storing the data files in device internal storage, we can read the data file from
the device using a FileInputStream object.
3. The data files saved in the internal are managed by an android framework and it can
be accessed anywhere within the app to read or write data into the file, but it’s not
possible to access the file from any other app so it’s secured.
4. When the user uninstalls the app, automatically these data files will be removed from
the device internal storage.
Write a File to Internal Storage
By using the android FileOutputStream object openFileOutput method, we can
easily create and write data to a file in a device’s internal storage.
To create and write a private file to the device's internal memory.
String FILENAME = "user_details";
String name = " ";
FileOutputStream fstream = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fstream.write(name.getBytes());
fstream.close();
Here, we are creating and writing a file in device internal storage by using
FileOutputStream object .
openFileOutput method with file name .
MODE_PRIVATE mode to make the file private to our application.
write() method to write the data in file and used close() method to close the stream.
In android, we have different modes such as MODE_APPEND,
MODE_WORLD_READBLE, MODE_WORLD_WRITEABLE, etc. to use it in our
application based on your requirements.
Apart from the above methods write() and close(), FileOutputStream object is having other
methods, those are
Method
• getChannel(): It returns the unique FileChannel object associated with this file
output stream.
• getFD(): It returns the file descriptor which is associated with the stream.
• write(byte[] b, int off, int len): It writes len bytes from the specified byte array
starting at offset off to the file output stream.
Read a File from Internal Storage
By using String FILENAME = "user_details";
FileInputStream fstream = openFileInput(FILENAME);
StringBuffer sbuffer = new StringBuffer();
int i;
while ((i=fstream.read())!=1){ sbuffer.append((char)i);
}
fstream.close();
the android FileInputStream object openFileInput method, we can easily
read the file from the device’s internal storage.
To read data from a file that is in the device’s internal memory.
Here, we are reading a file from device internal storage by using FileInputStream object
openFileInput method with file name. We used read() method to read one character at a
time from the file and used close() method to close the stream.
Apart from the above methods read() and close(), FileInputStream object is
having other methods, those are
Method
• getChannel() :It returns the unique FileChannel object associated with this file
output stream.
• getFD(): It returns the file descriptor which is associated with the stream.
• read(byte[] b, int off, int len): It reads len bytes of data from the specified
file input stream into an array of bytes.
2.Android External Storage:
In android, External Storage is useful to store the data files publically on the shared
external storage using the FileOutputStream object. After storing the data files on external
storage, we can read the data file from external storage media using
a FileInputStream object.
The data files saved in external storage are word-readable and can be modified by the user
when they enable USB mass storage to transfer files on a computer.
Grant Access to External Storage
To read or write files on the external storage, our app must acquire
the WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE system
permissions. For that, we need to add the following permissions in the android manifest file
like as shown below.
<manifest>
....
<uses-
permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
....
</manifest>
Checking External Storage Availability
Before we do any work with external storage, first we need to check whether the media is
available or not by calling getExternalStorageState(). The media might be mounted to a
computer, missing, read-only or in some other state. To get the media
status, we need to write
boolean Available= false;
boolean Readable= false;
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)){
// Both Read and write operations available Available=
true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){
// Only Read operation available
Available= true;
Readable= true;
} else {
// SD card not mounted
Available = false;
}
Here, we used getExternalStorageState() method to know the status of media mounted
to a computer, such as missing, read-only or in some other state.
In android, by using getExternalStoragePublishDirectory() method we can access the
files from appropriate public directory by passing the type of directory we want, such as
DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONES, etc.
based on our requirements.
If we save our files to corresponding media-type public directory, the system's media scanner
can properly categorize our files in the system.
Following is the example to create a directory for a new photo album in the public pictures
directory.
// Get the directory for the user's public pictures directory.
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
In case, if we are handling the files that are not intended for other apps to use, then we
should use a private storage directory on the external storage by
calling getExternalFilesDir(). Write a
File to External Storage
By using android FileOutputStream object
and getExternalStoragePublicDirectory method, we can easily create and write data to the
file in external storage public folders.
write a public file in the device Downloads folder.
String FILENAME =
"user_details"; String name = " ";
File folder =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOA
DS);
File myFile = new File(folder, FILENAME);
FileOutputStream fstream = new FileOutputStream(myFile);
fstream.write(name.getBytes());
fstream.close();
Here, we are creating and writing a file in device
public Downloads folder by using getExternalStoragePublicDirectory method. We used
write() method to write the data in file and used close() method to close the stream.
Read a File from External Storage:
By using the android FileInputStream object
and getExternalStoragePublicDirectory method, we can easily read the file from external
storage.
To read data from a file that is in the downloads folder.
String FILENAME = "user_details";
File folder =Environment.getExternalStoragePublicDirectory(Environment.
DIRECTORY_DOWNLOA DS);
File myFile = new File(folder, FILENAME);
FileInputStream fstream = new FileInputStream(myFile);
StringBuffer sbuffer = new StringBuffer();
int i;
while ((i = fstream.read())!= -1){
sbuffer.append((char)i);
}
fstream.close();
Here, we are reading a file from device Downloads folder storage by
using FileInputStream object getExternalStoragePublicDirectory method
with file name. We used read() method to read one character at a time from the file and
used close() method to close the stream.
Android SQLite Database:
SQLite is an open-source lightweight relational database management system (RDBMS)
to perform database operations, such as storing, updating, retrieving data from the
database.
Generally, in our android applications Shared Preferences, Internal Storage and External
Storage options are useful to store and maintain a small amount of data. In case, if we
want to deal with large amounts of data, then SQLite database is the preferable option to
store and maintain the data in a structured format.
By default, Android comes with built-in SQLite Database support so we don’t need
to do any configurations.
Just like we save the files on the device’s internal storage, Android stores our
database in a private disk space that’s associated with our application and the data
is secure, because by default this area is not accessible to other applications. The
package android.database.sqlite contains all the required APIs to use an SQLite
database in our android applications.
Now we will see how to create a database and required tables in SQLite and perform
CRUD (insert, update, delete and select) operations in android applications.
Create Database and Tables using SQLite Helper
In android, by using SQLiteOpenHelper class we can easily create the required database
and tables for our application. To use SQLiteOpenHelper, we need to create a subclass
that overrides the onCreate() and onUpgrade() call-back methods.
Creating the database and tables using the SQLiteOpenHelper class in our android
application.
public class DbHandler extends SQLiteOpenHelper {
private static final int DB_VERSION = 1;
private static final String DB_NAME = "usersdb"; private
static final String TABLE_Users = "userdetails"; private
static final String KEY_ID = "id";
private static final String KEY_NAME = "name"; private
static final String KEY_LOC = "location"; private static
final String KEY_DESG = "designation"; public
DbHandler(Context context){
super(context,DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db){
String CREATE_TABLE = "CREATE TABLE " + TABLE_Users + "("
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
KEY_NAME + " TEXT,"
+ KEY_LOC + " TEXT,"
+ KEY_DESG + " TEXT"+ ")";
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
// Drop older table if exist
db.execSQL("DROP TABLE IF EXISTS " + TABLE_Users);
// Create tables again
onCreate(db);
}
}
Here, we are creating database “usersdb” and table “userdetails” using
SQLiteOpenHelper class by overriding onCreate and onUpgrade methods.
Method
onCreate(): This method is called only once throughout the application after the
database is created and the table creation statements can be written in this method.
onUpgrade(): This method is called whenever there is an updation in the database
like modifying the table structure, adding constraints to the database, etc.
Now we will see how to perform CRUD (create, read, delete and update) operations in
android applications.
Insert Data into SQLite Database
In android, we can insert data into the SQLite database by passing ContentValues to
insert() method.
To insert data into the SQLite database using the insert() method in the android
application.
//Get the Data Repository in write mode
SQLiteDatabase db = this.getWritableDatabase();
//Create a new map of values, where column names are the keys
ContentValues cValues = new ContentValues();
cValues.put(KEY_NAME, name);
cValues.put(KEY_LOC, location);
cValues.put(KEY_DESG, designation);
// Insert the new row, returning the primary key value of the new row long
newRowId = db.insert(TABLE_Users,null, cValues);
Here, we are getting the data repository in write mode and adding required values to
columns and inserting into database.
Read the Data from SQLite Database
In android, we can read the data from the SQLite database using the query() method in
android applications.
To read the data from the SQLite Database using a query() method in the android
application.
//Get the Data Repository in write mode
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.query(TABLE_Users, new String[]{KEY_NAME, KEY_LOC,
KEY_DESG}, KEY_ID+ "=?",new String[]{String.valueOf(userid)},null, null, null,
null);
Here, we are getting the details from required table using query() method based on our
requirements.
Update Data in SQLite Database
In android, we can update the data in the SQLite database using an update() method in
android applications.
To update the data in the SQLite database using an update() method in the android
application.
//Get the Data Repository in write mode
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cVals = new ContentValues();
cVals.put(KEY_LOC, location);
cVals.put(KEY_DESG, designation);
int count = db.update(TABLE_Users, cVals, KEY_ID+" = ?",new
String[]{String.valueOf(id)});
Here, we are updating the details using update() method based on our requirements
Delete Data from SQLite Database
In android, we can delete data from the SQLite database using the delete() method in
android applications.
To delete the data from the SQLite database using the delete() method in the android
application.
//Get the Data Repository in write mode
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_Users, KEY_ID+" = ?",new String[]{String.valueOf(userid)});
Here, we are deleting the details using delete() method based on our requirements.
Example using SQLite Database to create table and insert data in table:
Step 1: Create a New Android Project
Open Android Studio.
Click on "Start a new Android Studio project" or go to File > New > New Project. Follow
the steps in the wizard to create a new project with an empty activity.
Step 2: Create DbHelper Class
Right-click on your app package (com.example.signup) in the Project panel. Go to
New > Java Class.
Name the class DbHelper and click "OK".
Copy and paste the provided DbHelper class code into the newly created class file. Step
3: Design Layout
Open activity_main.xml layout file located in the res/layout directory. Design
your layout with EditText fields for name, email, and password, and a Button for
registration.
Copy and paste the provided XML code for the layout. Step
4: Link Views with MainActivity
Open MainActivity.java file located in the java/com.example.signup directory. Define
instance variables for EditText fields (name, email, password) and a DbHelper object
(dbHelper).
In the onCreate() method, link these instance variables with corresponding views from
the layout file.
Instantiate the DbHelper object.
Step 5: Implement registerUser() Method
Inside MainActivity class, implement the registerUser(View view) method. In
this method, retrieve the text entered by the user in EditText fields.
Call the registerUser() method of DbHelper class passing these values. Display a
success or failure message using Toast based on the return value of registerUser()
method.
Step 6: Handle Permissions (if required)
If your app requires any permissions (e.g., for accessing the internet), declare them in
the AndroidManifest.xml file.
Add permission tags within the <manifest> tag.
New project- Empty activity
New class DbHelper
package com.example.signup;
import
android.content.ContentValues;
import android.content.Context;
import
android.database.sqlite.SQLiteDatabase;
import
android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class DbHelper extends SQLiteOpenHelper {
private static final String Database_Name =
"Demo_db"; private static final int
Database_Version = 1;
public DbHelper(@Nullable Context context) {
super(context, Database_Name, null,
Database_Version);
}
@Override
public void onCreate(SQLiteDatabase db) {
String Create_Table_Query = "CREATE TABLE register (id
INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT,
password NUMBER)";
db.execSQL(Create_Table_Query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) { db.execSQL("DROP TABLE IF EXISTS register");
onCreate(db);
}
public boolean registerUserHelper(String name1, String email1, String
password1)
{
SQLiteDatabase sqLiteDatabase =
this.getWritableDatabase(); ContentValues
contentValues = new ContentValues();
contentValues.put("name", name1);
contentValues.put("email", email1);
contentValues.put("password", password1);
long l= sqLiteDatabase.insert("register", null, contentValues);
sqLiteDatabase.close();
return l > 0;
}
}
MainActivity.java
package com.example.signup;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import
android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
EditText name,email,password;
DbHelper DbHelper; @Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name=(EditText) findViewById(R.id.name); email=(EditText) findViewById(R.id.email)
password=(EditText) findViewById(R.id.password); DbHelper=new
DbHelper(getApplicationContext());
}
public void registerUser(View view)
{
String name1=name.getText().toString(); String email1=email.getText().toString();
String password1=password.getText().toString();
boolean b= DbHelper.registerUserHelper(name1, email1, password1); if(b){
Toast.makeText(this,"User registerd successfully...", Toast.LENGTH_LONG).show();
email.setText("");
name.setText(""); password.setText("");
}
else{
Toast.makeText(this,"User not registerd ...", Toast.LENGTH_LONG).show();
}
}}
Activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:layout_gravity="center"
android:orientation="vertical"
android:padding="20dp">
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="name"
android:minHeight="48dp"
android:padding="10dp" />
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="email"
android:minHeight="48dp"
android:padding="10dp" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="pass"
android:inputType="number"
android:minHeight="48dp"
android:padding="10dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Register"
android:onClick="registerUser"/>
</LinearLayout>