==================================================================
Shared Preferences
Write value to SharedPreferences
SharedPreferences myPrefs = getSharedPreferences("PREF_COUNT",0); SharedPreferences.Editor myEditor = myPrefs.edit(); myEditor.putInt("COUNT", count); myEditor.commit();
Read value from SharedPreferences
SharedPreferences myPrefs = getSharedPreferences("PREF_COUNT",0);
SharedPreferences.Editor myEditor = myPrefs.edit();
int count = myPrefs.getInt("COUNT",0);
CreateDatabase and create table statement
SQLiteDatabase db;
//#2 Place Create SQLite database code below try { db = SQLiteDatabase.openOrCreateDatabase("sdcard/mdb.db", null); db.beginTransaction(); db.execSQL("create table if not exists tData (recID integer PRIMARY KEY autoincrement, pname text, score integer);"); db.setTransactionSuccessful(); db.endTransaction(); } catch (Exception e) { Toast.makeText(DataStorage.this, e.getMessage(),Toast.LENGTH_LONG).show(); }
SQL insert statement
try { db.beginTransaction(); db.execSQL("insert into tData(pname,score) values('"+name+"','"+score+"');"); db.setTransactionSuccessful(); db.endTransaction(); et.setText("");//clear editText score=100; //reset score to initial value of 100 } catch (Exception e) { Toast.makeText(DataStorage.this, e.getMessage(),Toast.LENGTH_LONG).show(); }
SQL select statement
Cursor c1 = db.rawQuery("select * from tData", null); String s1, s2, sc=""; while(c1.moveToNext()) { s1=c1.getString(1); s2=c1.getString(2); sc+=s1+"\t"+s2+"\n"; }
tvDisplay.setText("Count from Preferences: ["+count+"]\nScoreboard\n"+sc);
================================================================== LAB 7: Mobile Device Application [Shared Preferences and SQLite Database]
Storing to Shared Preferences and SQLite Database
1.
Create a new Android Project called DataStorage
with package mdad.lab7 and Activity name: DataStorage.
2. Copy/replace
activity_data_storage.xml file with the file downloaded from OLIVE.
3.
For external SD card file
input/output, you need
to add permissions in the AndroidManifest.xml { Refer to Lab 6 Step 6 }
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
/>
4.
Copy and replace the DataStorage.java file with the
one downloaded from OLIVE.
5.
In the DataStorage class, complete the missing codes
after each of the comment
headers:
//#1 Place btnDecCount (Decrease Count) code below
btnDecCount = (Button)findViewById(R.id.btnDecCount);
btnDecCount = (Button)findViewById(R.id.btnDecCount);
btnDecCount.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
SharedPreferences
myPrefs = getSharedPreferences("PREF_COUNT",0);
SharedPreferences.Editor
myEditor = myPrefs.edit();
int count = myPrefs.getInt("COUNT",0);
--count;
DataStorage.this.btnDecCount.setText("Decrease Count ["+count+"]");
myEditor.putInt("COUNT", count);
|
} });
6. Create SQLite database and
database table (continue inside onCreate method):
//#2 Place Create
SQLite database code below
try {
db =
SQLiteDatabase.openOrCreateDatabase("sdcard/mdb.db", null);
db.beginTransaction();
db.execSQL("create table if not exists tData (recID integer PRIMARY KEY
autoincrement, pname text, score integer);");
db.setTransactionSuccessful();
db.endTransaction();
}
catch
(Exception e) {
Toast.makeText(DataStorage.this, e.getMessage(),Toast.LENGTH_LONG).show(); }
rnum=(int)(Math.random()*10); //random number from 1 to 10
Log.d("rnum","rnum is "+rnum);
7. Add the
event handling for button btnPlay for the SQLITEDB tab (inside
onCreate method):
//#3 Place btnPlay code below
btnPlay.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
num = Integer.parseInt(et.getText().toString());
if(num==rnum)
{
et.setText("");
et.setHint("Bravo!
"+ score +"pts Enter Your Name"); et.setInputType(InputType.TYPE_CLASS_TEXT) ;
btnEnterName.setEnabled(true); //Enable enter name btn
btnPlay.setEnabled(false);//Disable play btn
}else{
et.setText("");
et.setHint("Try
Again. dun give up.");
score-=10; //reduce
score by 10 points
if(score==0) score=10;//lowest score is 10
}
}
});
8. Add the
event handling for button btnEnterName for the SQLITEDB tab
(inside onCreate method):
//#4 Place btnEnterName code
below
btnEnterName= (Button) findViewById(R.id.btnEnterName);
btnEnterName.setOnClickListener(new View.OnClickListener() {
public void
onClick(View arg0) {
String name = et.getText().toString();
et.setText("");et.setHint("Guess the next number");
et.setInputType(InputType.TYPE_CLASS_NUMBER) ;
btnEnterName.setEnabled(false); //Disable enter name btn
btnPlay.setEnabled(true);//Enable play btn
rnum=(int)(Math.random()*10); //random number from 1 to 10
Log.d("rnum","rnum is "+rnum);
try {
db.beginTransaction();
db.execSQL("insert into tData(pname,score)
values('"+name+"','"+score+"');");
db.setTransactionSuccessful();
db.endTransaction();
et.setText("");//clear editText
}
catch (Exception e) {
Toast.makeText(DataStorage.this, e.getMessage(),Toast.LENGTH_LONG).show();
}
} });
9.
Test run the application for SQLITEDB tab.
You are expected to see the program stopped as shown below.
You are expected to see the program stopped as shown below.
Look at the Logcat, it showed that there is a
NullPointerException occurred at line 110 of DataStorage.java
btnPlay.setOnClickListener(new View.OnClickListener() { //LINE 110
NullPointerException occurred when
it returned a Null object
This is a very common mistake encountered by many students.
Button
btnPlay was declared but
was NOT Instantiated (Created)
public class DataStorage extends Activity {
Button
btnIncCount, btnDecCount, btnPlay, btnEnterName, btn5;
SQLiteDatabase
db;
TextView tv;
EditText et; //et is declared but not created yet so et is Null
int num, rnum, score=100;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data_storage);
et = (EditText)
findViewById(R.id.etResult);
btnEnterName = (Button) findViewById(R.id.btnEnterName);
Solution: Add one more line for to
instantiate btnPlay , as shown below:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data_storage);
et = (EditText)
findViewById(R.id.etResult);
btnEnterName = (Button) findViewById(R.id.btnEnterName);
btnPlay = (Button) findViewById(R.id.btnEnterName);
10. Run the app and test the SHAREDPREF tab buttons.
Pressing each button will increase or
decrease the count value. Close and open the App. The last number is still saved in the sharedpreferenced value.
Pressing each button will increase or
decrease the count value. Close and open the App. The last number is still saved in the sharedpreferenced value.
Mobile Device Application (Part 2)
Objective: Persistent Data Storage in Android mobile
devices
Modify DataStorage
program so that when the last button, btnShow, is pressed, the count value
stored in Shared Preferences and the names & scores in SQLite Database must
be read again and shown in the TextView of the DISPLAY tab as shown.
Fill
in the blanks for marking
Declare a Button btnShow and TextView
tvDisplay; as class variable
Then type these lines inside onCreate method of
DataStorage.java
//In onCreate()
method:
tvDisplay = (TextView)findViewById(R.id.tvDisplay);
btnShow = (Button) findViewById(R.id.btnShow);
btnShow.setOnClickListener(
new View.OnClickListener() {
public void
onClick(View arg0) {
try {
SharedPreferences
myPrefs = getSharedPreferences(_______________,0);
int count = myPrefs.getInt("____________",0);
Cursor
c1 = db.rawQuery("_______________________", null);
String
s1, s2, sc="";
while(c1.moveToNext())
{
s1=c1.getString(______________);
s2=c1.getString(______________);
sc+=s1+"\t"+s2+"\n";
}
tvDisplay.setText("Count from Preferences: ["+count+"]\nScoreboard\n"+sc);
}
catch (Exception e) {
Toast.makeText(DataStorage.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
});
Lab7 Solution
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mdad.lab7" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="mdad.lab7.DataStorage" 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>
activity_data_storage.xml
<TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/DStabhost" android:layout_width="match_parent" android:layout_height="match_parent"> <TabWidget android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="60dp" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="60dp"> <LinearLayout android:id="@+id/content1" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btnIncCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Increase Count" > </Button> <Button android:id="@+id/btnDecCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Decrease Count" > </Button> </LinearLayout> <LinearLayout android:id="@+id/content2" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/etIntroTab2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Enter a number from 1 to 10 "></TextView> <EditText android:id="@+id/etResult" android:layout_width="match_parent" android:layout_height="wrap_content" > <requestFocus /> </EditText> <Button android:id="@+id/btnPlay" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Play " > </Button> <Button android:id="@+id/btnEnterName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Enter name " > </Button> </LinearLayout> <LinearLayout android:id="@+id/content3" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/etIntroTab3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Read data from SharedPreferences and SQLite" > </TextView> <Button android:id="@+id/btnShow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show " > </Button> <TextView android:id="@+id/tvDisplay" android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="textMultiLine" > </TextView> </LinearLayout> </FrameLayout> </TabHost>
DataStorage.java
package mdad.lab7; import android.os.Bundle; import android.app.Activity; import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.text.InputType; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TabHost; import android.widget.TabHost.TabSpec; import android.widget.TextView; import android.widget.Toast; public class DataStorage extends Activity { Button btnIncCount, btnDecCount, btnPlay, btnEnterName, btnShow; SQLiteDatabase db; TextView tvDisplay; EditText et; //et is declared but not created yet so et is Null int num, rnum, score=100; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_data_storage); et = (EditText) findViewById(R.id.etResult); btnEnterName = (Button) findViewById(R.id.btnEnterName); btnPlay = (Button) findViewById(R.id.btnPlay); tvDisplay = (TextView)findViewById(R.id.tvDisplay); //Initial conditions et.setInputType(InputType.TYPE_CLASS_NUMBER) ; btnEnterName.setEnabled(false); TabHost tabs =(TabHost) this.findViewById(R.id.DStabhost); tabs.setup(); TabSpec ts1 = tabs.newTabSpec("SharedPreferences"); ts1.setIndicator("SharedPref"); ts1.setContent(R.id.content1); tabs.addTab(ts1); TabSpec ts2 = tabs.newTabSpec("SQLiteDatabase"); ts2.setIndicator("SQLiteDB"); ts2.setContent(R.id.content2); tabs.addTab(ts2); TabSpec ts3 = tabs.newTabSpec("DisplayAll"); ts3.setIndicator("Display"); ts3.setContent(R.id.content3); tabs.addTab(ts3); tvDisplay = (TextView)findViewById(R.id.tvDisplay); btnShow = (Button) findViewById(R.id.btnShow); btnShow.setOnClickListener( new View.OnClickListener() { public void onClick(View arg0) { try { SharedPreferences myPrefs = getSharedPreferences("PREF_COUNT",0); int count = myPrefs.getInt("COUNT",0); Cursor c1 = db.rawQuery("select * from tData", null); String s1, s2, sc=""; while(c1.moveToNext()) { s1=c1.getString(1); s2=c1.getString(2); sc+=s1+"\t"+s2+"\n"; } tvDisplay.setText("Count from Preferences: ["+count+"]\nScoreboard\n"+sc); } catch (Exception e) { Toast.makeText(DataStorage.this, e.getMessage(), Toast.LENGTH_LONG).show(); } } }); //btnIncCount (Increase Count) code below btnIncCount = (Button)findViewById(R.id.btnIncCount); btnIncCount.setOnClickListener(new View.OnClickListener(){ public void onClick(View v){ SharedPreferences myPrefs = getSharedPreferences("PREF_COUNT",0); SharedPreferences.Editor myEditor = myPrefs.edit(); int count = myPrefs.getInt("COUNT",0); ++count; DataStorage.this.btnIncCount.setText("Increase Count ["+count+"]"); myEditor.putInt("COUNT", count); myEditor.commit(); } }); //#1 Place btnDecCount (Decrease Count) code below btnDecCount = (Button)findViewById(R.id.btnDecCount); btnDecCount.setOnClickListener(new View.OnClickListener(){ public void onClick(View v){ SharedPreferences myPrefs = getSharedPreferences("PREF_COUNT",0); SharedPreferences.Editor myEditor = myPrefs.edit(); int count = myPrefs.getInt("COUNT",0); --count; DataStorage.this.btnDecCount.setText("Decrease Count ["+count+"]"); myEditor.putInt("COUNT", count); myEditor.commit(); } }); //#2 Place Create SQLite database code below try { db = SQLiteDatabase.openOrCreateDatabase("sdcard/mdb.db", null); db.beginTransaction(); db.execSQL("create table if not exists tData (recID integer PRIMARY KEY autoincrement, pname text, score integer);"); db.setTransactionSuccessful(); db.endTransaction(); } catch (Exception e) { Toast.makeText(DataStorage.this, e.getMessage(),Toast.LENGTH_LONG).show(); } rnum=(int)(Math.random()*10); //random number from 1 to 10 Log.d("rnum","rnum is "+rnum); //#3 Place btnPlay code below btnPlay.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { num = Integer.parseInt(et.getText().toString()); if(num==rnum) { et.setText(""); et.setHint("Bravo! "+ score +"pts Enter Your Name"); et.setInputType(InputType.TYPE_CLASS_TEXT) ; btnEnterName.setEnabled(true); //Enable enter name btn btnPlay.setEnabled(false);//Disable play btn }else{ et.setText(""); et.setHint("Try Again. dun give up."); Log.d("rnum","rnum is "+rnum); score-=10; //reduce score by 10 points if(score==0) score=10;//lowest score is 10 } } }); //#4 Place btnEnterName code below btnEnterName = (Button) findViewById(R.id.btnEnterName); btnEnterName.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { String name = et.getText().toString(); et.setText("");et.setHint("Guess the next number"); et.setInputType(InputType.TYPE_CLASS_NUMBER) ; btnEnterName.setEnabled(false); //Disable enter name btn btnPlay.setEnabled(true);//Enable play btn rnum=(int)(Math.random()*10); //random number from 1 to 10 Log.d("rnum","rnum is "+rnum); try { db.beginTransaction(); db.execSQL("insert into tData(pname,score) values('"+name+"','"+score+"');"); db.setTransactionSuccessful(); db.endTransaction(); et.setText("");//clear editText score=100; //reset score to initial value of 100 } catch (Exception e) { Toast.makeText(DataStorage.this, e.getMessage(),Toast.LENGTH_LONG).show(); } } }); } //end of onCreate method }// end of DataStorage class