-
Q. opening page of app has an editable textbox//end questions
- public class MainActivity extends AppCompatActivity {
- EditText textbox;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- textbox = (EditText)
- findViewById(R.id.main_editText);
- start();
- } //end onCreate()
- //not end of MainActivity
-
The id of a button in a view is btnMonId. View.OnClickListener cl. Code button and set listener
- Button btnMon = (Button) findViewById(R.id.btnMonId);
- btnMon.setOnClickListener(cl);
-
Combine into one line
Button btnMon = (Button) findViewById(R.id.btnMonId);
btnMon.setOnClickListener(cl);
((Button) findViewById(R.id.btnMonId)).setOnClickListener(cl);
-
((Button) findViewById(R.id.btnTues)).setOnClickListener(cl);
cl assigns name of button clicked to putExtras. Write cl
- View.OnClickListener cl = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Button btnClicked = (Button) view;
- Intent intent = new Intent(view.getContext(), WeekDayActivity5.class);
- intent.putExtra("putExtras_daykey", btnClicked.getText());
- startActivity(intent)
- }//end onClick(View view)
- };//end View.OnClickListener()
-
What is an intent?
An Intent is an object that provides runtime binding between separate components, such as two activities. The Intent represents an app’s "intent to do something."
-
us an onclicklistener to add the name of a button that was clicked in an intent. The intent starts an activity
- Button btnMon = (Button) findViewById(R.id.btnMon);
- btnMon.setOnClickListener(cl);
- View.OnClickListener cl
- = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Button btnClicked = (Button) view;
- Intent intent =
- new Intent(view.getContext(),
- WeekDayActivity5.class);
- intent.putExtra("putExtras_daykey",
- btnClicked.getText());
- startActivity(intent);
- }
- };
-
The Intent constructor and methods
- 1st parameter: view.getContext()
- 2nd parameter: The Class of the app component to which the system should deliver the Intent.
- intent.putExtra(): method adds data to the intent. An Intent can carry data types as key-value pairs called extras.
-
How to start the intent
Intent intent = new Intent(view.getContext(), WeekDayActivity5.class);
startActivity(intent);
-
intent.putExtra("putExtras_daykey",btnClicked.getText()); is from MainActivity
How do you start a new activity, add the text from the intent to a TextView?
- public class WeekDayActivity5 extends AppCompatActivity {
- String str_dayText;
- TextView tv_sentDay;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_week_day5);
- Intent intent = getIntent();
- str_dayText = (String) intent.getExtras()
- .get("putExtras_daykey");
- /*TextView*/ tv_sentDay =
- findViewById(R.id.tvID_sentDay5);
- tv_sentDay.setText(str_dayText);
- }
-
In WeekDayActivity.java, get the intent and assign the value in the Extras with key "daykey" to str_dayText
- onCreate(Bundle savedInstanceState){
- super.conCreate(savedInstanceState);
- setContentView(R.layout.activity_week_day);
- ...
- Intent intent = getIntent();
- String str_dayText = (String) intent.getExtras().get("daykey");
- ...}
-
define SharedPreferences
- Interface for accessing and modifying preference data returned by getSharedPreferences(String, int). For any particular set of preferences, there is a single instance of this class that all clients share.
- Modifications to the preferences must go through an SharedPreferences.Editor object to ensure the preference values remain in a consistent state and control when they are committed to storage. Objects that are returned from the various get methods must be treated as immutable by the application.
- If you have a relatively small collection of key-values that you'd like to save, you should use the SharedPreferences APIs. A SharedPreferences object points to a file containing key-value pairs and provides simple methods to read and write them. Each
- SharedPreferences file is managed by the framework and can be private or shared.
-
Get a handle to a SharedPreferences object
- You can create a new shared preference file or access an existing one by calling one of these methods:
- getSharedPreferences() — Use this if you need multiple shared preference files identified by name, which you specify with the first parameter. You can call this from any Context in your app.
- getPreferences() — Use this from an Activity if you need to use only one shared preference file for the activity. Because this retrieves a default shared preference file that belongs to the activity, you don't need to supply a name.
-
code accesses the shared preferences file that's identified by the resource string R.string.preference_file_key and opens it using the private mode so the file is accessible by only your app:
- Context context = getActivity();
- SharedPreferences sharedPref
- =context.getSharedPreferences(
- getString(R.string.preference_file_key),
- Context.MODE_PRIVATE);
-
code if you need just one shared preference file
- SharedPreferences sharedPref
- =getActivity()
- .getPreferences(Context.MODE_PRIVATE);
-
Write to shared preferences
- To write to a shared preferences file, create a SharedPreferences.Editor by calling edit() on your SharedPreferences.
- Pass the keys and values you want to write with methods such as putInt() and putString(). Then call apply() or commit() to save the changes.
-
example write to shared preferences
- SharedPreferences sharedPref
- = getActivity().getPreferences(
- Context.MODE_PRIVATE);
- SharedPreferences.Editor editor
- = sharedPref.edit();
- editor.putInt(
- getString(R.string.saved_high_score_key), newHighScore);
- editor.commit();
-
Read from shared preferences
To retrieve values from a shared preferences file, call methods such as getInt() and getString(), providing the key for the value you want, and optionally a default value to return if the key isn't present.
-
code Read from shared preferences for keys:
R.integer.saved_high_score_default_key
R.string.saved_high_score_key
- SharedPreferences sharedPref
- = getActivity().getPreferences(
- Context.MODE_PRIVATE);
- int defaultValue = getResources().getInteger(
- R.integer.saved_high_score_default_key);
- int highScore = sharedPref.getInt(
- getString(R.string.saved_high_score_key),
- defaultValue);
-
contract defines the table name and column names for a single table representing an RSS feed
- public final class FeedReaderContract {
- private FeedReaderContract() {}
- /* Inner class that defines the table contents */
- public static class FeedEntry implements BaseColumns {
- public static final String TABLE_NAME = "entry";
- public static final String COLUMN_NAME_TITLE = "title";
- public static final String COLUMN_NAME_SUBTITLE = "subtitle";
- }
- }
- To prevent someone from accidentally instantiating the contract class, make the constructor private.
-
Create a Database Using a SQL Helper
some typical statements that create and delete a table:
- private static final String
- SQL_CREATE_ENTRIES
- = "CREATE TABLE " +
- FeedEntry.TABLE_NAME + " (" +
- FeedEntry._ID +
- " INTEGER PRIMARY KEY," +
- FeedEntry.COLUMN_NAME_TITLE +
- " TEXT," +
- FeedEntry.COLUMN_NAME_SUBTITLE
- + " TEXT)";
- private static final String
- SQL_DELETE_ENTRIES
- ="DROP TABLE IF EXISTS "
- + FeedEntry.TABLE_NAME;
- Just like files that you save on the device's internal storage, Android stores your database in your app's private folder. Your data is secure, because by default this area is not accessible to other apps or the user.
-
implementation of DBHelper
- public class FeedReaderDbHelper extends SQLiteOpenHelper {
- public static final int DATABASE_VERSION=1;
- public static final String DATABASE_NAME
- = "FeedReader.db";
- public FeedReaderDbHelper(Context context) {
- super(context, DATABASE_NAME,
- null, DATABASE_VERSION);
- }
- public void onCreate(SQLiteDatabase db) {
- db.execSQL(SQL_CREATE_ENTRIES);}
- public void onUpgrade(SQLiteDatabase db,
- int oldVersion, int newVersion) {
- // This database is only a cache for online data, so its upgrade policy is to simply to discard the data and start over
- db.execSQL(SQL_DELETE_ENTRIES);
- onCreate(db);
- }
- public void onDowngrade(SQLiteDatabase db,
- int oldVersion, int newVersion) {
- onUpgrade(db, oldVersion, newVersion);
- }
- }
-
To access your database
FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
-
Put Information into a Database
- Insert data into the database by passing a ContentValues object to the insert() method.
- The first argument for insert() is simply the table name.
- The second argument tells the framework what to do in the event that the ContentValues is empty.
- The insert() methods returns the ID for the newly created row, or it will return -1 if there was an error inserting the data. This can happen if you have a conflict with pre-existing data in the database.
-
add the strings title and subtitle to the FeedEntry.TABLE_NAME
- // Gets the data repository in write mode
- SQLiteDatabase db = mDbHelper.getWritableDatabase();
- // Create a new map of values, where column names are the keys
- ContentValues values = new ContentValues();
- values.put(FeedEntry.COLUMN_NAME_TITLE, title);
- values.put(FeedEntry.COLUMN_NAME_SUBTITLE, subtitle);
- // Insert the new row, returning the primary key value of the new row
- long newRowId = db.insert(FeedEntry.TABLE_NAME, null, values);
- //The second argument tells the framework what to do in the event that the ContentValues is empty
The insert() methods returns the ID for the newly created row, or it will return -1 if there was an error inserting the data. This can happen if you have a conflict with pre-existing data in the database.
-
Read Information from a Database
- To read from a database, use the query() method, passing it your selection criteria and desired columns.
- The method combines elements of insert() and update(), except the column list defines the data you want to fetch (the "projection"), rather than the data to insert. The results of the query are returned to you in a Cursor object.
-
Get the title and subtitle from FeedEntry table
- SQLiteDatabase db = mDbHelper.getReadableDatabase();
- // Define a projection that specifies which columns from the database you will actually use after this query.
- String[] projection = {
- BaseColumns._ID,
- FeedEntry.COLUMN_NAME_TITLE,
- FeedEntry.COLUMN_NAME_SUBTITLE
- };
- // Filter results WHERE "title" = 'My Title'
- String selection = FeedEntry.COLUMN_NAME_TITLE + " = ?";
- String[] selectionArgs = { "My Title" };
- Cursor cursor = db.query(
- FeedEntry.TABLE_NAME, // The table to query
- projection, // The array of columns to return
- (pass null to get all)
- selection, // The columns for the WHERE clause
- selectionArgs, // The values for the WHERE clause
- null, // don't group the rows
- null, // don't filter by row groups
- null // The sort order
- );
-
To look at a row in the cursor, use
- To look at a row in the cursor, use one of the Cursor move methods, which you must always call before you begin reading values. Since the cursor starts at position -1, calling moveToNext() places the "read position" on the first entry in the results and returns whether or not the cursor is already past the last entry in the result set. For each row, you can read a column's value by calling one of the Cursor get methods, such as getString() or getLong().
- For each of the get methods, you must pass the index position of the column you desire, which you can get by calling getColumnIndex() or getColumnIndexOrThrow().
- When finished iterating through results, call close() on the cursor to release its resources.
-
A cursor contains long values. Add the values to an ArrayList.
- List itemIds = new ArrayList<>();
- while(cursor.moveToNext()) {
- long itemId = cursor.getLong(cursor
- .getColumnIndexOrThrow(FeedEntry._ID));
- itemIds.add(itemId);
- }
- cursor.close();
-
Delete Information from a Database
- To delete rows from a table, you need to provide selection criteria that identify the rows to the delete() method. It divides the selection specification into a selection clause and selection arguments. The clause defines the columns to look at, and also allows you to combine column tests. The arguments are values to test against that are bound into the clause.
- Because the result isn't handled the same as a regular SQL statement, it is immune to SQL injection.
-
delete the row where title = "MyTitle"
- // Define 'where' part of query.
- String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
- // Specify arguments in placeholder order.
- String[] selectionArgs = { "MyTitle" };
- // Issue SQL statement.
- int deletedRows =
- db.delete(FeedEntry.TABLE_NAME,
- selection, selectionArgs);
-
A content provider manages..
- A content provider manages access to a central repository of data. You implement a provider as one or more classes in an Android application, along with elements in the manifest file.
- One of your classes implements a subclass ContentProvider, which is the interface between your provider and other applications.
-
Next, follow these steps to build your provide
- Design the raw storage for your data.
- Define a concrete implementation of the ContentProvider class and its required methods. This class is the interface between your data and the rest of the Android system.
- Define the provider's authority string, its content URIs, and column names. Also define the permissions that you will require for applications that want to access your data. (consider defining all of these values as constants in a separate contract class)
-
A content URI is
- A content URI is a URI that identifies data in a provider.
- Content URIs include the symbolic name of the entire provider (its authority) and a name that points to a table or file (a path). The optional id part points to an individual row in a table.
- Every data access method of ContentProvider has a content URI as an argument; this allows you to determine the table, row, or file to access.
-
Designing an authority
- A provider usually has a single authority, which serves as its Android-internal name.
- If your Android package name is
- com.example.<appname>,
- you should give your provider the authority com.example.<appname>.provider.
-
Designing a path structure
- Developers usually create content URIs from the authority by appending paths that point to individual tables. For example, if you have two tables table1 and table2, you combine the authority from the previous example to yield the content URIs com.example<appname>.provider/table1 and
- com.example.<appname>.provider/table2.
- Paths aren't limited to a single segment, and there doesn't have to be a table for each level of the path.
-
Implementing the ContentProvider Class
- The ContentProvider instance manages access to a structured set of data by handling requests from other applications. All forms of access eventually call ContentResolver, which then calls a concrete method of ContentProvider to get access.
- Required methods: The abstract class ContentProvider defines six abstract methods that
- you must implement as part of your own concrete subclass. All of these methods except onCreate() are called by a client application that is attempting to access your content provider:
- query() returns a Cursor
- insert()
- update()
- delete()
- getType()
- onCreate() Initialize your provider. The Android system calls this method immediately after it creates your provider. Notice that your provider is not created until a ContentResolver object tries to access it.
-
Implementing the Content Provider query() method
- The ContentProvider.query() method must return a Cursor object, or if it fails, throw an Exception.
- If you are using an SQLite database as your data
- storage, you can simply return the Cursor returned by one of the query() methods of the SQLiteDatabase class.
- If the query does not match any rows, you should return a Cursor instance whose getCount() method returns 0.
- You should return null only if an internal error occurred during the query process.
If you aren't using an SQLite database as your data storage, use one of the concrete subclasses of Cursor. For example, the MatrixCursor class implements a cursor in which each row is an array of Object. With this class, use addRow() to add a new row.
-
AsyncTask
- AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
- An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
- AsyncTask must be subclassed to be used. The subclass will override at least one method (doInBackground(Params...))
-
The three types used by an asynchronous task are the following:
- Params, the type of the parameters sent to the task upon execution.
- Progress, the type of the progress units published during the background computation.
- Result, the type of the result of the background computation.
-
When an asynchronous task is executed, the task goes through 4 steps:
- onPreExecute(): invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
- doInBackground(Params...): invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
- onProgressUpdate(Progress...): invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
- onPostExecute(Result): invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
-
There are a few threading rules that must be followed for this class to work properly:
- The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
- The task instance must be created on the UI thread.
- execute(Params...) must be invoked on the UI thread.
- Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
- The task can be executed only once (an exception will be thrown if a second execution is attempted.)
-
Write the ScheduleProviderContract?
- public class ScheduleProviderContract {
- private ScheduleProviderContract(){}
- public static final String AUTHORITY = "ca.on.sl.comp208.ScheduleProvider"
- public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
- public static final class ScheduleProvider implements BaseColumns{
- public static final String DAY = "Day";
- public static final String TIME = "Time";
- public static final String[] ALL_COLUMNS = {_ID, DAY, TIME};
- } // end inner class
- }//end outer class
-
Write ScheduleProvider class beginning
- public class ScheduleProvider extends ContentProvider {
- DBHelper helper:
- SqliteDatabase db;
- public ScheduleProvider(){}
-
public Cursor query(URI uri, String[] projection, String selection,
- String[] selectionArgs, String sortOrder){
- helper = new DBHelper(getContext());
- db = helper.getReadableDatabase();
- return helper.getSchedule(db);
- } // end query
- } // end class
-
How get the cursor from the provider query method from inside onClick?
- Uri.Builder builder = new Uri.Builder();
- builder.schema("content");
- builder.authority(ContractName.AUTHORITY);
- builder.path("context");
- Uri uri = builder.build();
- ContentResolver resolver = new getContentResolver();
- cursor = resolver.query(uri,XProviderContract.XProvider.ALL_COLUMNS,null,null,null);
-
beginning of DBHelper?
- public class DBHelper extends SQLiteOpenHelper{
- Context context;
- public static final int DB_VERSION = 1;
- public static final String DB_NAME = "schedule.db";
- private final String CREATE_COURSE_TABLE =
- "CREATE TABLE "+Contract.Course.COURSE_TABLE_NAME +" ("+
- Contract.Course._ID+" INTEGER PRIMARY KEY, "+
- Contract.Course.COURSE_CODE+" TEXT,"+
- Contract.Course.COURSE_NAME+" TEXT)";
- private final String DROP_COURSE_TABLE = "DROP TABLE "+Contract.Course.COURSE_TABEL;
- public DBHelper(Context context){
- super(context,DB_NAME, null, DB_VERSION);
- this.context = context;}
- } //end class
-
write getCourses method in DBHelper?
- public Cursor getCourses(SQLiteDataBase db) {
- String table = ScheduleContract.Course.COURSE_TABLE;
- String[] projection = ScheduleContract.Course.ALL_COLUMNS;
- return db.query(table,projection,null,null,null,null);
- }
|
|