Introduction
In this article, we will have a brief understanding of handling storage of different input types, and different storage options that you can apply on your android applications depending on your needs and application type, as well as accessing data through a web service which is the most apply method now.
We will cover the following options :
- Storage Options
- Shared Preferences
- What it is?
- When should I use Shared Preferences?
- How to store data?
- How to retrieve data?
- How to delete Shared Preference Data?
- Example
- Tip
- Internal Storage
- What it is?
- When should I use Internal Storage?
- How to store data?
- How to retrieve data?
- How to delete Internal Storage Data?
- Example
- Tip
- External Storage
- What it is?
- When should I use External Storage?
- How to store data?
- How to retrieve data?
- How to delete External Storage Data?
- SQLite Database
- What it is?
- When should I use Shared Preferences?
- Example
- DB Model Classes
- DB Handler
- CRUD
- Create
- Read
- Read All
- Update
- Delete
- User Interaction with DB
- Web Service
- kSOAP 2
- Download kSOAP Library
- Include kSOAP Library Into Our Project
- Create a Response
- JSON Parsing
Background
If you are looking for a complete tutorial, Please refer to the following links
Article 1 - Introduction to Android by Ranjan.D
Article 2 - Setting Up Your Android Development Environment by Peter Leow
Article 3 - Creating a Simple Hello World Android Project by Varavut
Article 4 - Android UI Layout and Controls by Peter Leow
Article 5 - Android User Interactivity and Sensors by Ranjan.D
Article 6 - Beginner’s Guide to Organizing/Accessing Android Resources by Grasshopper.iics
Article 7 - To be Updated Soon
Article 8 - To be Updated Soon
Article 9 - To be Updated Soon
Article 10 - To be Updated Soon
Article 11 - To be Updated Soon
Article 12 - To be Updated Soon
Downloads
Storage Options
In 99% of any android application, you will have to save users data somehow, that's why android provides different storage options and data management that developers can use to save these data and choosing which option to use depends on the developer needs and your application type.
1. Shared Preferences
1.1 - What it is?
Shared Preferences is an API from Android to store and retrieve small application data that are stored persistently which mean that data that you save in Shared Preferences will exist even if you close the application and data will be removed only by uninstalling the application from the device. Also, data saved in Shared Preferences are private to this application only and not accessible by anyway for any other application on the device.
You have to note that data are saved as Key/Value Pair.
Key/Value Pair: it's a known method to save data as a unique identifier and a value that is the data of the identifier or a link on the location of data such that your code looks like <Key, Value> => <"Website","CodeProject">, when you need to find a specific value , you will search by the key as ex: find(website) and it will display the value for this key.
1.2 - When should I use Shared Preferences?
If you need to save simple data for your application, the simplest and straight forward way is Shared Preferences. It's probably used to save simple data like integer,double, boolean, and short text. As Example, It's used to save application settings or user login info.
1.3 - How to store data?
First, you have to initialize a Shared Preference instance and use it to store your data as below
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences _SharedPref = getApplicationContext().getSharedPreferences("MyAppData", 0);
Editor _SharedPrefEditor = _SharedPref.edit();
}
I created a Shared Preferences Instance called _SharedPref of File Name called MyAppData (this can be anything), and the 2nd parameter is set to 0 which means that these data are private for this application only (private mode). Then we created an Editor that we will use to store new values as we will see in the next lines.
Now, you can save the data using the created Editor as below
_SharedPrefEditor.putBoolean(key, value);
_SharedPrefEditor.putFloat(key, value);
_SharedPrefEditor.putInt(key, value);
_SharedPrefEditor.putLong(key, value);
_SharedPrefEditor.putString(key, value);
_SharedPrefEditor.putStringSet(arg0, arg1);
_SharedPrefEditor.commit();
1.4 - How to retrieve data?
Same as storing data, you need to initialize an instance of shared preference and use it to retrieve data
SharedPreferences _SharedPref = getApplicationContext().getSharedPreferences("MyAppData", 0);
_SharedPref.getAll();
_SharedPref.getBoolean(key, defValue);
_SharedPref.getFloat(key, defValue);
_SharedPref.getInt(key, defValue);
_SharedPref.getLong(key, defValue);
_SharedPref.getString(key, defValue);
_SharedPref.getStringSet(arg0, arg1);
1.5 - How to delete Shared Preference Data?
You can 2 options, you can delete a specific data or delete all data inside a Shared Preference
1. Delete specific item
SharedPreferences _SharedPref = getApplicationContext().getSharedPreferences("MyAppData", 0);
Editor _SharedPrefEditor = _SharedPref.edit();
_SharedPrefEditor.remove(key);
_SharedPrefEditor.commit();
2. Delete All Data
SharedPreferences _SharedPref = getApplicationContext().getSharedPreferences("MyAppData", 0);
Editor _SharedPrefEditor = _SharedPref.edit();
_SharedPrefEditor.clear();
_SharedPrefEditor.commit();
1.6 - Example
I created an example to combine all the previous points that we discussed. The example is a simple login form where user have to login to move into next activity then he can logout or stay logged in.
1. I created my XML Layout that contains a title , email input text , password input text and login button.
figure 1.1.6.1 - XML Layout
2. It's time to implement some code, i created a static user and trying to login with. If the data are valid then save UserID in Shared Preferences and go to Profile Page Or if already user is logged in then go directly to Profile Page
SharedPreferences _SharedPref = getApplicationContext()
.getSharedPreferences("MyAppData", 0);
final Editor _SharedPrefEditor = _SharedPref.edit();
int UserKey = _SharedPref.getInt("UserKey", -1);
if (UserKey != -1) {
Intent i = new Intent(MainActivity.this, Profile.class);
startActivity(i);
}
final EditText txt_Email = (EditText) findViewById(R.id.Email);
final EditText txt_Password = (EditText) findViewById(R.id.Password);
Button btn_Login = (Button) findViewById(R.id.btnLogin);
btn_Login.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
int UserID = IsLogin(txt_Email.getText().toString(),
txt_Password.getText().toString());
if (UserID != -1) {
_SharedPrefEditor.putInt("UserKey", UserID);
_SharedPrefEditor.commit();
Intent i = new Intent(MainActivity.this, Profile.class);
startActivity(i);
} else {
Toast msg = Toast.makeText(getApplicationContext(),
"Login Failed", Toast.LENGTH_LONG);
msg.show();
}
}
});
3. Try to close and open the application and it should redirect you to profile page directly without the need to enter your email and password again unless you logged out and Use saved UserID inside Shared Preferences to load information about the user like User Name in our example
SharedPreferences _SharedPref = getApplicationContext()
.getSharedPreferences("MyAppData", 0);
final Editor _SharedPrefEditor = _SharedPref.edit();
int UserKey = _SharedPref.getInt("UserKey", -1);
if (UserKey != -1) {
if (User._CurrentUser.UserID == UserKey) {
TextView txt_Name = (TextView) findViewById(R.id.txtUsername);
txt_Name.setText(User._CurrentUser.Name);
}
} else {
Intent i = new Intent(Profile.this, MainActivity.class);
startActivity(i);
}
figure 1.1.6.2 - Logged In Screen
4. Try to log out and open the application again
Button btn_Logout = (Button)findViewById(R.id.btnLogout);
btn_Logout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
_SharedPrefEditor.remove("UserKey");
_SharedPrefEditor.commit();
Intent i = new Intent(Profile.this, MainActivity.class);
startActivity(i);
}
});
You can download the entire code from: Download SharedPreferences.zip
1.7 - Tip
You can view your Shared Preference files, Edit, and Create new file using Eclipse IDE - DDMS
1. Run Your Application on an Emulator
2. Select DDMS from Menu, then Select Your Emulator and choose File Explorer
figure 1.1.7.1 - DDMS Screen
3. You should see a similar figure, then select data->data
figure 1.1.7.2 - File Explorer
4. Select the com.example.sharedpreferences (Your Project)
5. Here you see your Shared Preference File and you can edit/add/delete/import/export any file from the provided tools
figure 1.1.7.3 - Controllers
2. Internal Storage
2.1 - What it is?
One of the Storage Options is Internal Storage. You can save your application data directly on the device's internal storage and these data are stored persistently which mean that data still exist even if you close the application and data will be removed only by uninstalling the application from the device. Also, data saved in device's internal storage are private to this application only and not accessible by anyway for any other application on the device.
2.2 - When should I use Internal Storage?
The amount of data in Internal Storage depends on the device, so don't try to save a large persistent file because it may crash your application if there isn;t enough space on device. Preferably, keep any data under 1M such as text files or xml files.
2.3 - How to store data?
First, You have to create a FileOutputStream Object that we will use to write our data in a file as BYTES, you have to open/ create a file and use .write() function to write your data as bytes and never forget to close the FileOutputStream as code below
FileOutputStream _FileOutput;
String FileName = "Note";
String FileInput = txt_EditNote.getText().toString();
try {
_FileOutput = openFileOutput(FileName, 0);
_FileOutput.write(FileInput.getBytes());
_FileOutput.close();
Toast.makeText(getApplicationContext(),
FileName + " saved", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
2.4 - How to retrieve data?
You need to create a StringBuffer to save each line you read from data into and Create a BufferReader Object to open file and read line by line and never forget to close the BufferReader as code below
StringBuffer stringBuffer = new StringBuffer();
try {
BufferedReader inputReader = new BufferedReader(new InputStreamReader(
openFileInput(FileName)));
String inputString;
while ((inputString = inputReader.readLine()) != null) {
stringBuffer.append(inputString + "\n");
}
inputReader.close();
} catch (IOException e) {
e.printStackTrace();
}
2.5 - How to delete Internal Storage Data?
This is a very easy step, all you need just the file name you want to delete and the filedir
File dir = getFilesDir();
File file = new File(dir, "filename");
file.delete();
2.6 - Example
I would like to provide an example that will combine all the above points for better explanation. In this example, we will create a note and save it into our device's internal storage then display all notes and show its content.
1. I created my XML Layout that contains a title , note input text , save button, and load all button.
figure 1.2.6.1 - XML Layout
2. As shown, we need to add an input and save it into a file in internal storage. I intiliazed a string for FileName and an FileOutputStream as discussed above to save our data as bytes in a file called Note
final String FileName = "Note";
btn_Save.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
FileOutputStream _FileOutput;
String FileInput = txt_EditNote.getText().toString();
try {
_FileOutput = openFileOutput(FileName, 0);
_FileOutput.write(FileInput.getBytes());
_FileOutput.close();
Toast.makeText(getApplicationContext(),
FileName + " saved", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
figure 1.2.6.2 - Test Application #1
3. I created another Activity to load all my files of this application and only this app since files are private and can't access them from another app. On Creation of this activity, I load all files as below
SavedDataInInternalStorage = getApplicationContext().fileList();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, SavedDataInInternalStorage);
_List.setAdapter(adapter);
figure 1.2.6.3 - Display All Notes
4. On Click of any item of List View, it displays the content of that file as decribed below
_List.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
String FileName = ((TextView) arg1).getText().toString();
StringBuffer stringBuffer = new StringBuffer();
try {
BufferedReader inputReader = new BufferedReader(
new InputStreamReader(openFileInput(FileName)));
String inputString;
while ((inputString = inputReader.readLine()) != null) {
stringBuffer.append(inputString + "\n");
}
inputReader.close();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),
stringBuffer.toString(), Toast.LENGTH_LONG).show();
}
});
figure 1.2.6.4 - Display single note info
You can download the entire code from: Download InternalStorage.zip
2.7 - Tip
1. Detect Internal Storage Space
Maybe, You may need to know Internal Sotrage Space and decide where to save your data on internal or external storage, that's why i think it's important to know the available space on device before saving your data.
You can find this as code below ( Credits goes to: Link )
public static String getAvailableInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return formatSize(availableBlocks * blockSize);
}
public static String formatSize(long size) {
String suffix = null;
if (size >= 1024) {
suffix = "KB";
size /= 1024;
if (size >= 1024) {
suffix = "MB";
size /= 1024;
}
}
StringBuilder resultBuffer = new StringBuilder(Long.toString(size));
int commaOffset = resultBuffer.length() - 3;
while (commaOffset > 0) {
resultBuffer.insert(commaOffset, ',');
commaOffset -= 3;
}
if (suffix != null)
resultBuffer.append(suffix);
return resultBuffer.toString();
}
2. Edit/Remove Internal Storage Files using Eclipse IDE - DDMS
1. Run Your Application on an Emulator
2. Select DDMS from Menu, then Select Your Emulator and choose File Explorer
figure 1.2.7.1 - DDMS
3. You should see a similar figure, then select data->data
figure 1.2.7.2 - File Explorer
4. Select the com.example.internalstorage (Your Project)
5. Here you see your Internal Storage Files and you can edit/add/delete/import/export any file from the provided tools
figure 1.2.7.3 - Display all files through DDMS
3. External Storage
3.1 - What it is?
One of the Storage Options is External Storage. You can save your application data directly on the device's external storage and these data are world-readable and can be modified/transfered on a computer. Also, data saved in device's external storage can be unavailable if user mounts or removed the external media.
3.2 - When should I use External Storage?
You should use External Storage whenever you need to save large files such as audio files or any large file that won't kill your application and can be retrieved by user again multiple of times, or if you want your files to be shared through different application like statistics files.
3.3 - How to store data?
Before storing data in an external media, you have to give permission to your application for such operation by allowing write to external media in manifest file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.externalstorage"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Now, your application is ready to store data in an external media in one of these directories
- Music
- Pictures
- Ringtones
- Movies
- Alarms
- Notifications
- Downloads
How to access one of these files?
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC, FileName);
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES, FileName);
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES, FileName);
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES, FileName);
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_ALARMS, FileName);
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_NOTIFICATIONS, FileName);
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS, FileName);
You need to create file and save it wherever of the above files to save it into as example below
FileOutputStream _FileOutput;
String FileInput = txt_EditNote.getText().toString();
try {
File myFile = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), FileName);
myFile.createNewFile();
_FileOutput = new FileOutputStream(myFile);
_FileOutput.write(FileInput.getBytes());
_FileOutput.close();
Toast.makeText(getApplicationContext(),
FileName + " saved", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
3.4 - How to retrieve data?
In order to retrieve any data or file from External Storage, you have to access the file and read its data. As example i will try to load an image saved inside DIRECTORY_PICTURES and decode it to bitmap image
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES, FileName);
FileInputStream InputFileStream = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeStream(InputFileStream);
InputFileStream.close();
3.5 - How to delete External Storage Data?
In order to delete external storage data, you have to reference to a specific file and simply apply delete function for this file as described
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath(), FileName);
file.delete();
4. SQLite Database
4.1 - What it is?
SQLite is an Open Source database. It supports standard relational database feasure like SQL Syntax and Views. SQLite is a very light weight DB that can be used in any mobile platforms.
For more information about SQLite : http://www.sqlite.org
Download SQLite Studio : http://sqlitestudio.pl/
4.2 - When should I use SQLite DB?
It doesn't have a specific case, you can use it whenever you need to save user data like fetching data from an external API but what if user is not connect to an internet then you can fetch the same data from database on offline mode or saving user search criteria to use it as default whenever user tries to search.
4.3 - Example
I think the best way to get into breif description of SQLite is to move directly into an example.
Our example is as follows : we have a set of cars and its description as well as its model as given in the following DB Diagram
figure 1.4.3.1 - Database Model
1. Create Model Classes
1. We need to build our Model Classes - Create your first class model CarModel. Always Create 3 constructors and set private variables in your class
- Empty Constructor
- Constructor with all fields as parameters WITH ID
- Constructor with all fields as parameters WITHOUT ID
public class CarModel {
int _CarID;
int _CarModelID;
String _CarName;
String _Description;
String _Color;
double _Price;
public CarModel(){
}
public CarModel(int CarID, int CarModelID, String CarName, String Description, String Color, double Price){
this._CarID = CarID;
this._CarModelID = CarModelID;
this._CarName = CarName;
this._Description = Description;
this._Color = Color;
this._Price = Price;
}
public CarModel(int CarModelID, String CarName, String Description, String Color, double Price){
this._CarModelID = CarModelID;
this._CarName = CarName;
this._Description = Description;
this._Color = Color;
this._Price = Price;
}
}
2. We need to create our getters/setter for all DB columns as follows
public int getCarID(){
return this._CarID;
}
public void setCarID(int Carid){
this._CarID = Carid;
}
public int getCarModelID(){
return this._CarModelID;
}
public void setCarModelID(int CarModelID){
this._CarModelID = CarModelID;
}
public String getCarName(){
return this._CarName;
}
public void setCarName(String CarName){
this._CarName = CarName;
}
public String getDescription(){
return this._Description;
}
public void setDescription(String Description){
this._Description = Description;
}
public String getColor(){
return this._Color;
}
public void setColor(String Color){
this._Color = Color;
}
public double getPrice(){
return this._Price;
}
public void setPrice(double Price){
this._Price = Price;
}
3. Do the above 2 steps for Model Class CarModelModel
public class CarModelModel {
int _ModelID;
String _ModelName;
public CarModelModel(){
}
public CarModelModel(int ModelID, String ModelName){
this._ModelID = ModelID;
this._ModelName = ModelName;
}
public CarModelModel(String ModelName){
this._ModelName = ModelName;
}
public int getModelID(){
return this._ModelID;
}
public void setModelID(int ModelID){
this._ModelID = ModelID;
}
public String getModelName(){
return this._ModelName;
}
public void setModelName(String ModelName){
this._ModelName = ModelName;
}
}
2. Create DB Handler Class
1. Create DB Handler Class DBHandler then extends SQLiteOpenHelper and Add Unimplemented methods
public class DBHandler extends SQLiteOpenHelper {
public DBHandler(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
2. You will get an errors unless we add some static data like DB_NAME, DB_VERSION, Tables, Columns
public static final int DB_VERSION = 1;
public static final String DB_NAME = "CarDB";
public static final String TableCar = "car";
public static final String TableCarModel = "model";
public static final String Car_ID = "CarID";
public static final String Car_ModelID = "CarModelID";
public static final String Car_Name = "CarName";
public static final String Car_Description = "Description";
public static final String Car_Color = "Color";
public static final String Car_Price = "Price";
public static final String Model_ID = "ModelID";
public static final String Model_Name = "ModelName";
3. We have to implement OnCreate function that will create table for us for the first time, Create a string that will create the table as SQL Syntax
String CREATE_CAR_TABLE = "CREATE TABLE " + TableCar + "("
+ Car_ID + " INTEGER PRIMARY KEY,"
+ Car_ModelID + " INTEGER," + Car_Name + " TEXT,"
+ Car_Description + " TEXT," + Car_Color + " TEXT,"
+ Car_Price + " double" + " )";
db.execSQL(CREATE_CAR_TABLE);
4. Do the same for Model Table
String CREATE_MODEL_TABLE = "CREATE TABLE " + TableCarModel + "("
+ Model_ID + " INTEGER PRIMARY KEY,"
+ Model_Name + " TEXT" + ")";
db.execSQL(CREATE_MODEL_TABLE);
5. What OnUpgrade does? Simply, it always you to re-create DB table in case of any changes like column name or type or added constrains
db.execSQL("DROP TABLE IF EXISTS " + TableCar);
db.execSQL("DROP TABLE IF EXISTS " + TableCarModel);
onCreate(db);
3. Create Tables ViewModel to hold their CRUD (Created/ Read/ Updated/ Delete)
1. Create a new class CarViewModel that will hold CRUD operations for this table and Add these methods
public class CarViewModel {
private SQLiteDatabase database;
private DBHandler dbHelper;
private String[] CarTableColumns = { DBHandler.Car_ID,
DBHandler.Car_ModelID, DBHandler.Car_Name,
DBHandler.Car_Description, DBHandler.Car_Color,
DBHandler.Car_Price};
public CarViewModel(Context context) {
dbHelper = new DBHandler(context);
}
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public void addCar(CarModel car) {}
public CarModel getCar(int id) {}
public List<CarModel> getAllCars() {}
public int updateCar(CarModel car) {}
public void deleteCar(CarModel car) {}
}
3.1. CRUD - Add Car
We need to create a ContentValues that will hold all our columns values and save this ContentValue inside the db as follows
public void addCar(CarModel car)
{
ContentValues values = new ContentValues();
values.put(DBHandler.Car_ModelID, car._CarModelID);
values.put(DBHandler.Car_Name, car._CarName);
values.put(DBHandler.Car_Description, car._Description);
values.put(DBHandler.Car_Color, car._Color);
values.put(DBHandler.Car_Price, car._Price);
database.insert(DBHandler.TableCar, null, values);
database.close();
}
3.2. CRUD - Read A Car Value By ID
To Read a record from the DB, we need to create something called cursor that will handle our query and navigate between returned records using this record. In the following code, we trying to read a car with its ID and returning a set of columns specified in the new String[] of Table determinded by DBHandler.TableCar and depends on Car_ID as specified
Cursor cursor = database.query(DBHandler.TableCar, new String[] { DBHandler.Car_ID,
DBHandler.Car_ModelID, DBHandler.Car_Name, DBHandler.Car_Description,
DBHandler.Car_Color, DBHandler.Car_Price}, DBHandler.Car_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null);
What are these nulls? They represent some SQL Features like group by, having, order by
figure 1.4.3.2 - SQL Features Supported by Android
And whole code for retrieving an item from DB is as follows
public CarModel getCar(int id) {
Cursor cursor = database.query(DBHandler.TableCar, new String[] { DBHandler.Car_ID,
DBHandler.Car_ModelID, DBHandler.Car_Name, DBHandler.Car_Description,
DBHandler.Car_Color, DBHandler.Car_Price}, DBHandler.Car_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
CarModel Car = new CarModel(Integer.parseInt(cursor.getString(0)),
Integer.parseInt(cursor.getString(1)), cursor.getString(2),
cursor.getString(3), cursor.getString(4),
Double.parseDouble(cursor.getString(5)));
return Car;
}
3.3. CRUD - Read All Cars
It's the same as Load By ID but here we set the selection to null since we are not looking for a specific value of a column
public List<CarModel> getAllCars() {
List<CarModel> Cars = new ArrayList<CarModel>();
Cursor cursor = database.query(DBHandler.TableCar,
CarTableColumns, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
CarModel Car = new CarModel(Integer.parseInt(cursor.getString(0)),
Integer.parseInt(cursor.getString(1)), cursor.getString(2),
cursor.getString(3), cursor.getString(4),
Double.parseDouble(cursor.getString(5)));
Cars.add(Car);
cursor.moveToNext();
}
cursor.close();
return Cars;
}
3.4. CRUD - Update A Car
Here we have to update columns of existing record in database, by specifying the new values of the record then update db using its ID
public int updateCar(CarModel car) {
ContentValues values = new ContentValues();
values.put(DBHandler.Car_ModelID, car.getCarModelID());
values.put(DBHandler.Car_Name, car.getCarName());
values.put(DBHandler.Car_Description, car.getDescription());
values.put(DBHandler.Car_Color, car.getColor());
values.put(DBHandler.Car_Price, car.getPrice());
return database.update(DBHandler.TableCar, values, DBHandler.Car_ID + " = ?",
new String[] { String.valueOf(car.getCarID()) });
}
3.5. CRUD - Delete A Car
It's one of the easiest query you can do in SQL. Just use delete to remove a specific record from the db
public void deleteCar(CarModel car) {
long id = car.getCarID();
database.delete(DBHandler.TableCar, DBHandler.Car_ID
+ " = " + id, null);
}
Now, we need to implement the above steps again for our Model class. I'll skip this part since it's the same and code is available.
4. Create User Interaction with DB
I created my 1st screen that consists of some buttons that will apply the above CRUD operations
figure 1.4.3.3 - XML Layout
1. Add New Car
As we see in the following code, i created a save button and onClick we need to create an instance of our CarViewModel to call addCar function and create another object of car that will be saved with its data.
I created a car object called _Car with CarModel : 1, Name : Aveo, Description : I Love Aveo, Color : Red, Price : 100
Then another object of CarViewModel and pass our context as parameter in the constructor then call addCar function
btn_Save.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
CarViewModel = new CarViewModel(getApplicationContext());
CarViewModel.open();
CarModel _Car = new CarModel(1, "Aveo", "I Love Aveo", "Red", 100);
CarViewModel.addCar(_Car);
Toast.makeText(getApplicationContext(), "Added New Car", Toast.LENGTH_LONG).show();
}
});
figure 1.4.3.4 - Insert
2. Load All Cars
Our next button is Load All Cars screen that will display all our saved cars in the database.
btn_LoadACar.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
CarViewModel = new CarViewModel(getApplicationContext());
CarViewModel.open();
List<CarModel> _List;
_List = CarViewModel.getAllCars();
Toast.makeText(getApplicationContext(), _List.get(0)._CarName, Toast.LENGTH_LONG).show();
}
});
figure 1.4.3.5 - Retrieve All
3. Load A Car
It's the same steps as loading all cars but we have to provide Car_ID in order to load a specific car but it applies the same idea as the previous points. Here we use our ready function getCar(Id) to load a car with specific Car_ID and then displays its name and price
btn_LoadACar.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
CarViewModel = new CarViewModel(getApplicationContext());
CarViewModel.open();
CarModel Car = CarViewModel.getCar(1);
Toast.makeText(getApplicationContext(), Car._CarName + " " + Car._Price, Toast.LENGTH_LONG).show();
}
});
figure 1.4.3.6 - Retrieve by ID
4. Update A Car
Coming to update method that you will need to use it alot. I decided to update the price of the Car that we just loaded in the previous point of ID = 1 and set the price to 200 instead of 100
figure 1.4.3.7 - Update
5. Delete A Car
Our last method we need to test is deleting an object from our application db. First, we need to load the object we have to delete same as loading a car using getCar(Id) then passing this object of CarModel to our function deleteCar(object Car) as below
btn_DeletCar.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
CarViewModel = new CarViewModel(getApplicationContext());
CarViewModel.open();
CarModel Car = CarViewModel.getCar(1);
CarViewModel.deleteCar(Car);
Toast.makeText(getApplicationContext(), "Deleted Car", Toast.LENGTH_LONG).show();
}
});
You can download the entire code from: Download SQLite.zip
Web Service
1. kSOAP 2
kSOAP is one of the famous library to consume web service in android applications. It's a lightweight and efficient library and it's open source and saves alot of time to reach what you need from using web service. As well as it's easy to install in your application as we will see in the next steps.
1.1. Download kSOAP Library
Our first step we need to do is to download kSOAP Library to add it into your lib folder in our project.
kSOAP Project Page : kSOAP Page or you can download the library we will use directly from : kSOAP 2 V 3.1.1
1.2. Include kSOAP Library Into Our Project
We created a new project called kSOAP that will hold our example. First, we need to add an internet access to our application inside manifest file.
1. Open your application Manifest file and add a permission of internet access
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ksoap"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET"/>
2. Now, it's time to add the kSOAP Library into our project. Right-Click on your project-> Properties
figure 2.1.2.1 - Properties Windows
3. From the left bar, select Java Build Path -> Libraries
figure 2.1.2.2 - Libraries
4. Choose External Jars from the right panel then navigate to the downloaded kSOAP Library that you have downloaded
figure 2.1.2.3 - Adding kSOAP Library
5. Click Ok BUT WE ARE NOT DONE after some work and tries to run your application you will get an error saying "java.lang.NoClassDefFoundError" because there is one step left to do
6. We need to add our .jar file inside Lib Folder of our project
figure 2.1.2.4 - Libs Folder
7. Drag and Drop your jar file inside Lib Folder and Select Copy Files
8. Now We are done of adding the library to our project.
1.3. Create a Response
To send a request using kSOAP, we need to create an HTTP request using HttpTransportSE, but before we create our HTTP request, we need to know some points.
I'll be using W3schools Web Service to retrieve data from : W3schools Web Service
1. From any service we will use, we need to extract some information about it like webservice namespace and SOAP ActionName. Open the above link-> click on service description
figure 2.1.3.1 - Temp Converter Website
2. You should see something like this image and you can extract the namespace and soap action names after scrolling down as in the image with the underlines parts
figure 2.1.3.2 - Temp Converter Service Description
3. It's time to add these variables to the project. In MainActivity, onCreate() function simply add these variables
private static final String NAMESPACE = "http://www.w3schools.com/webservices/";
private static final String URL = "http://www.w3schools.com/webservices/tempconvert.asmx?wsdl";
private static final String SOAP_ACTION = "http://www.w3schools.com/webservices/FahrenheitToCelsius";
private static final String METHOD_NAME = "FahrenheitToCelsius";
4. We need to create our request using these variables. First we have to create a SOAP Object and Assign all parameters we have to send and include the SOAP Object to OutputSOAPObject.
String SoapResult = null;
SoapObject SOAPRequest = new SoapObject(NAMESPACE, METHOD_NAME);
SOAPRequest.addProperty("Fahrenheit", "100.0");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.setOutputSoapObject(SOAPRequest);
envelope.dotNet = true;
How did i know the parameter name? - Simply open the webservice you are willing to call and you can determine all the parameters it needs
figure 2.1.3.3 - FahrenheitToCelsius Web Method Info
5. Let's call the web service using HTTP request, simply assign the SoapSerilizationEnvelope to the HTTP request and it will support all the rest, then display the result inside a TextView
HttpTransportSE ht = new HttpTransportSE(URL);
ht.call(SOAP_ACTION, envelope);
if (envelope.bodyIn instanceof SoapFault) {
SoapResult = ((SoapFault) envelope.bodyIn).faultstring;
} else {
SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
SoapResult = resultsRequestSOAP.getProperty(0).toString();
}
final String str = SoapResult;
runOnUiThread(new Runnable() {
public void run() {
txt_Input.setText(str);
}
});
6. AGAIN WE ARE NOT DONE. If we simply add the above code inside our main thread,the application will crash because we idle our main thread waiting for the responce from web service that's why we need to apply the code inside another thread inherited from main thread. To achieve this, we need to create a new thread
Thread SOAPThread = new Thread() {
@Override
public void run() {
}
};
SOAPThread.start();
figure 2.1.3.4 - Temp Converter Example Test
You can download the entire code from: Download kSOAP.zip
1.4. JSON Parser
What if we use a web service that returns multiple columns, not just a single value that's why we use JSON Parser to parse and loop through our json input and return all columns we need to retrieve from the json.
So, JSON Parser means extracting what we need from this string. How we can obtain that? - It's easy we just need to use JSONObject to retrieve data from by parsing the json tree.
Consider the following json input
{
"User":
{
"Name":"Ahmed Alaa ElDin",
"Title":"Software Engineer",
"Company":"Enozom Software Company",
"Copyrights" : "CodeProject"
}
}
and we need to extract these data, each in a separate variable
JSONObject DataReader;
try {
DataReader = new JSONObject(Data);
JSONObject User = DataReader.getJSONObject("User");
String Name = User.getString("Name");
String Title = User.getString("Title");
String Company = User.getString("Company");
String Copyright = User.getString("Copyrights");
txt_Name.setText("Name : " + Name);
txt_Name.setText("Name : " + Name);
txt_Title.setText("Title : " + Title);
txt_Company.setText("Company : " + Company);
txt_Copyrights.setText("Copyrights : " + Copyright);
} catch (JSONException e) {
}
You can download the entire code from: Download JSONParser.zip
Points of Interest
I suggest to investigate more about another web service which is called Android Restful WebService. It's another method used to fetch/save data using a Webservice.
History
1. Article Release - 10/09/2014
2. Update # 1 : Added JSON Parser - 13/09/2014