Download Activities

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
CS499 – Mobile Application
Development
Fall 2013
Programming the Android Platform
Activities & Intents
Activity
• Provides a visual interface
• Typically supports one thing a user can do
– View an email message
– Show a login screen
• Applications can include several activities
• Only one activity can have ‘focus’ at a time.
Other activities are paused or stopped.
Tasks
• Set of related activities
• Android manages an activity ‘back stack’
– Launching an activity pushes it onto the stack
– Hitting the back button pops the top activity off
the stack, deleting it.
Task Stack
Activity States
• Not started – not yet created
• Active
– Resumed/Running – visible, has focus
– Paused – visible, does not have focus, can be
terminated
– Stopped – not visible, can be terminated
• Finished
Activity Lifecycle
Android communicates state changes to application by
calling specific lifecycle methods:
protected void onCreate()
protected void onStart()
protected void onResume()
protected void onPause()
protected void onRestart()
protected void onStop()
protected void onDestroy()
onCreate()
• protected void onCreate(Bundle
savedInstanceState)
• Called when Activity is first being created
• Must be defined by the activity
• Setup global state:
– call super.onCreate()
– inflate UI views
– Configure views
Activity functions
• All must call super.<fn>()
• protected void onStart() Called when the activity starts.
• protected void onRestart() Called if the activity has been stopped
and is about to be started again. Update
any saved info.
• protected void onResume() –
return to ‘focus’. Restart foreground
effects
Activity functions
• protected void onPause() –
focus is switching to another activity.
Shut down foreground resources.
• protected void onStop() –
Activity no longer visible but might be
used again eventually. Can save state
in case destroyed.
• protected void onDestroy()
– removed from back stack. Save any
important data and release any held
resources.
public class ExampleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The activity is being created.
}
@Override
protected void onStart() {
super.onStart();
// The activity is about to become visible.
}
@Override
protected void onResume() {
super.onResume();
// The activity has become visible (it is now "resumed").
}
@Override
protected void onPause() {
super.onPause();
// Another activity is taking focus (this activity is about to
be "paused").
}
@Override
protected void onStop() {
super.onStop();
// The activity is no longer visible (it is now "stopped")
}
@Override
protected void onDestroy() {
super.onDestroy();
// The activity is about to be destroyed.
}
}
Example: Pause/Resume
@Override
public void onPause() {
super.onPause(); // Always call the superclass method first
// Release the Camera because we don't need it when paused
// and other activities might need to use it.
if (mCamera != null) {
mCamera.release()
mCamera = null;
}
}
@Override
public void onResume() {
super.onResume(); // Always call the superclass method first
// Get the Camera instance as the activity achieves full user
focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera init
}
}
Example: Stop
@Override
protected void onStop() {
super.onStop(); // Always call the superclass method first
// Save the note's current draft, because the activity is
stopping
// and we want to be sure the current note progress isn't
lost.
ContentValues values = new ContentValues();
values.put(NotePad.Notes.COLUMN_NAME_NOTE,
getCurrentNoteText());
values.put(NotePad.Notes.COLUMN_NAME_TITLE,
getCurrentNoteTitle());
…
}
Example: Start or Restart
@Override
protected void onStart() {
super.onStart(); // Always call the superclass method first
// The activity is either being restarted or started for the first time
// so this is where we should make sure that GPS is enabled
LocationManager locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean gpsEnabled =
locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!gpsEnabled) {
// Create a dialog here that requests the user to enable GPS, and
use an intent
// with the
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
// to take the user to the Settings screen to enable GPS when they
click "OK"
}
}
Activity Lifetime
• Entire lifetime – from onCreate() to
onDestroy()
• Visible lifetime – from onStart() to onStop()
• Foreground (focus) lifetime – from
onResume() to onPause()
Configuration Changes
• Device configuration can change at runtime
– orientation, locale, etc.
• On configuration changes, Android typically
kills & restarts the current activity
– Basic UI information is saved automatically.
– Hard to recompute data can be saved & restored
explicitly.
Example: saving state
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...
@Override
public void onSaveInstanceState(Bundle
savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE,
mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL,
mCurrentLevel);
// Always call the superclass so it can save the
view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
Example: restoring state
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the
superclass first
// Check whether we're recreating a previously
destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore =
savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel =
savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values
for a new instance
}
...
}
Starting New Activities
• Create an Intent object specifying the activity
to start
– Can be explicit (by name) or implicit (by purpose)
• Pass newly created Intent to one of the
following:
– startActivity()
– startActivityForResult()
The Intent Class
• An Intent is a data structure that specifies
– An operation to be performed
– An event that has occurred
• Broadcast by one component
• Received by 0 or more components
• This lecture focuses on using intents to
represent operations rather than events.
Example: Explicit
public class MyAppActivity extends Activity {
public final static String EXTRA_MESSAGE = "cs499.examples.myapp.MESSAGE";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
/** Called when the user selects the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}
public class DisplayMessageActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the message from the intent
Intent intent = getIntent();
String message =
intent.getStringExtra(MyAppActivity.EXTRA_MESSAGE);
// Create the text view
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
setContentView(textView);
}
// when this activity finishes, it is popped from the stack
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cs499.examples.myapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".MyAppActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".DisplayMessageActivity" />
</application>
</manifest>
Getting Results from Activities
• startActivityForResult()
– Implement onActivityResult() callback method
– When the activity is done, it will return the result
in an intent to your callback
– onActivityResult() – handles this return event
– Note: If the current activity can start multiple
activities returning values, the returns are all
handled with a single onActivityResult() method.
Example: getting return values
static final int PICK_CONTACT_REQUEST = 1;
// The request code
...
private void pickContact() {
Intent pickContactIntent = new
Intent(Intent.ACTION_PICK,
new Uri("content://contacts"));
pickContactIntent.setType(Phone.CONTENT_TYPE);
// Show user only contacts w/ phone numbers
startActivityForResult(pickContactIntent,
PICK_CONTACT_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int
resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which
contact was selected.
// Do something with the contact here
}
}
}
More complete Example
• Main activity – gets two integers and sends
these to the second activity on a button press.
When data arrives back, print out this
• Second activity – started by another activity,
receives two strings that represent integers.
On a button press, adds the integers and
returns the result.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cs499.examples.intentexample" android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity android:name=".IntentExampleActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ActivityA" />
</application>
</manifest>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="First Activity" />
<EditText android:layout_width="fill_parent“ android:layout_height="wrap_content“
android:hint="Enter an integer" android:id="@+id/input1” />
<EditText android:layout_width="fill_parent“ android:layout_height="wrap_content“
android:hint="Enter an integer“ android:id="@+id/input2” />
<Button android:layout_width="fill_parent“ android:layout_height="wrap_content"
android:text="Update int“ android:onClick="sendMessage“ />
<TextView android:layout_width="fill_parent“ android:layout_height="wrap_content"
android:id="@+id/result” />
</LinearLayout>
Step 1 – create Main Activity
package cs499.examples.intentexample;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class IntentExampleActivity extends Activity {
// parameters for the new activity
public void sendMessage(View view) {
// Create an intent to send values in response
to button
Intent intent = new Intent(this,
ActivityA.class);
String s1 = mVal1.getText().toString();
if (s1.length() != 0)
intent.putExtra(ActivityA.PARAM1, s1);
else intent.putExtra(ActivityA.PARAM1,"0");
String s2 = mVal2.getText().toString();
if (s2.length() != 0)
intent.putExtra(ActivityA.PARAM2, s2);
else intent.putExtra(ActivityA.PARAM2,"0");
public final int ACTIVITY_RESULT = 1;
private TextView mResultText;
private EditText mVal1, mVal2;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mResultText=(TextView)findViewById(R.id.result);
mVal1 =(EditText)findViewById(R.id.input1);
mVal2=(EditText)findViewById(R.id.input2);
}
startActivityForResult(intent,ACTIVITY_RESULT);
}
@Override
protected void onActivityResult(int requestCode,
int resultCode, Intent data)
{
if (requestCode == ACTIVITY_RESULT) {
String address = data.getExtras().
getString(ActivityA.RETVAL);
mResultText.setText(address);
}
}
}
Step 2 – User presses button in Main Activity
package cs499.examples.intentexample;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class IntentExampleActivity extends Activity {
// parameters for the new activity
public void sendMessage(View view) {
// Create an intent to send values in response
to button
Intent intent = new Intent(this,
ActivityA.class);
String s1 = mVal1.getText().toString();
if (s1.length() != 0)
intent.putExtra(ActivityA.PARAM1, s1);
else intent.putExtra(ActivityA.PARAM1,"0");
String s2 = mVal2.getText().toString();
if (s2.length() != 0)
intent.putExtra(ActivityA.PARAM2, s2);
else intent.putExtra(ActivityA.PARAM2,"0");
public final int ACTIVITY_RESULT = 1;
private TextView mResultText;
private EditText mVal1, mVal2;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mResultText=(TextView)findViewById(R.id.result);
mVal1 =(EditText)findViewById(R.id.input1);
mVal2=(EditText)findViewById(R.id.input2);
}
startActivityForResult(intent,ACTIVITY_RESULT);
}
@Override
protected void onActivityResult(int requestCode,
int resultCode, Intent data)
{
if (requestCode == ACTIVITY_RESULT) {
String address = data.getExtras().
getString(ActivityA.RETVAL);
mResultText.setText(address);
}
}
}
Step 3 - Second
Activity starts
package cs499.examples.intentexample;
import
import
import
import
import
android.app.Activity;
android.content.Intent;
android.os.Bundle;
android.view.View;
android.widget.TextView;
public class ActivityA extends Activity {
public final static String RETVAL =
"cs499.examples.activitya.RETVAL";
public final static String PARAM1 =
"cs499.examples.activitya.P1";
public final static String PARAM2 =
"cs499.examples.activitya.P2";
private TextView mInt1, mInt2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get parameters from the calling activity
Intent intent = getIntent();
String str1 =
intent.getStringExtra(IntentExampleActivity.
PARAM1);
String str2 =
intent.getStringExtra(IntentExampleActivity.
PARAM2);
// Create the text view using the input values
setContentView(R.layout.main_c);
mInt1 = (TextView) findViewById(R.id.start1);
mInt1.setText(str1);
mInt2 = (TextView) findViewById(R.id.start2);
mInt2.setText(str2);
}
public void sendMessage(View view) {
// Do something in response to button
int v1 =
Integer.parseInt(mInt1.getText().toString());
int v2 =
Integer.parseInt(mInt2.getText().toString());
String result = Integer.toString(v1+v2);
Intent intent = new Intent();
intent.putExtra(STRVAL,result );
// Set result and finish this Activity
setResult(Activity.RESULT_OK, intent);
finish();
}
}
main_c.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent” android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView android:layout_width="fill_parent” android:layout_height="wrap_content"
android:text="Second Activity" />
<TextView
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:id="@+id/start1" />
<TextView
android:layout_width="fill_parent” android:layout_height="wrap_content"
android:id="@+id/start2" />
<Button android:layout_width="fill_parent“ android:layout_height="wrap_content"
android:text="Return Result“ android:onClick="sendMessage“ />
</LinearLayout>
Step 4 – button
press in Second
Activity
package cs499.examples.intentexample;
import
import
import
import
import
android.app.Activity;
android.content.Intent;
android.os.Bundle;
android.view.View;
android.widget.TextView;
public class ActivityA extends Activity {
public final static String RETVAL =
"cs499.examples.activitya.RETVAL";
public final static String PARAM1 =
"cs499.examples.activitya.P1";
public final static String PARAM2 =
"cs499.examples.activitya.P2";
private TextView mInt1, mInt2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get parameters from the calling activity
Intent intent = getIntent();
String str1 =
intent.getStringExtra(IntentExampleActivity.
PARAM1);
String str2 =
intent.getStringExtra(IntentExampleActivity.
PARAM2);
// Create the text view using the input values
setContentView(R.layout.main_c);
mInt1 = (TextView) findViewById(R.id.start1);
mInt1.setText(str1);
mInt2 = (TextView) findViewById(R.id.start2);
mInt2.setText(str2);
}
public void sendMessage(View view) {
// Do something in response to button
int v1 =
Integer.parseInt(mInt1.getText().toString());
int v2 =
Integer.parseInt(mInt2.getText().toString());
String result = Integer.toString(v1+v2);
Intent intent = new Intent();
intent.putExtra(STRVAL,result );
// Set result and finish this Activity
setResult(Activity.RESULT_OK, intent);
finish();
}
}
Step 5 – return to Main Activity
package cs499.examples.intentexample;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class IntentExampleActivity extends Activity {
// parameters for the new activity
public void sendMessage(View view) {
// Create an intent to send values in response
to button
Intent intent = new Intent(this,
ActivityA.class);
String s1 = mVal1.getText().toString();
if (s1.length() != 0)
intent.putExtra(ActivityA.PARAM1, s1);
else intent.putExtra(ActivityA.PARAM1,"0");
String s2 = mVal2.getText().toString();
if (s2.length() != 0)
intent.putExtra(ActivityA.PARAM2, s2);
else intent.putExtra(ActivityA.PARAM2,"0");
public final int ACTIVITY_RESULT = 1;
private TextView mResultText;
private EditText mVal1, mVal2;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mResultText=(TextView)findViewById(R.id.result);
mVal1 =(EditText)findViewById(R.id.input1);
mVal2=(EditText)findViewById(R.id.input2);
}
startActivityForResult(intent,ACTIVITY_RESULT);
}
@Override
protected void onActivityResult(int requestCode,
int resultCode, Intent data)
{
if (requestCode == ACTIVITY_RESULT) {
String address = data.getExtras().
getString(ActivityA.RETVAL);
mResultText.setText(address);
}
}
}
Implicit Intents
Often used to use components from existing applications:
•
Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
•
Uri webpage = Uri.parse("http://www.android.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
•
Intent calendarIntent = new Intent(Intent.ACTION_INSERT,
Events.CONTENT_URI);
Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7,
30);
Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME,
beginTime.getTimeInMillis());
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME,
endTime.getTimeInMillis());
calendarIntent.putExtra(Events.TITLE, "Ninja class");
calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
Intent Resolution
• When the activity to be activated is not
named, the system attempts to find activities
that match the intent
• Only matches on
– Action
– Data (both URI and mime data type)
– Category
Intent Actions
• String representing the operation
• Examples:
• new Intent(Intent.ACTION_VIEW)
• Intent newInt = new Intent();
newInt.setAction(Intent.ACTION_VIEW);
Intent Category
• Additional information about the components
to handle the intent
• Examples:
Intent Data
• Data associated with the Intent
– Formatted as a Uniform Resource Identifier (URI)
• Examples:
– Data to view on a map
• geo:0,0?q=1600+Pennsylvania+Ave+Washington+DC
– Number to dial on the phone
• tel:+15555555555
Intent Data
• Setting the Intent Data
• new Intent(Intent.ACTION_CALL,
Uri.parse(tel:+15555555555));
• Intent newInt = new Intent(Intent.ACTION_CALL);
newInt.setData(Uri.parse(tel:+15555555555));
• Additional information associated with the
intent
– Treated as a map (key-value pairs)
• Setting the Extra attribute
– Several forms depending on data type
• putExtra(String name, String value):
• putExtra(String name, float[] value);
•…
Intent Type
• Sets MIME type of the intent data
– for example, “image/*”
• If unspecified, Android will infer the type
• Intent.setType(String type)
• Intent.setDataAndType(Uri data, String type)
Implicit Intents
• Usually necessary to verify that there is at
least one component capable of handling the
intent:
•
Intent mapIntent = new Intent(Intent.ACTION_VIEW,
location);
PackageManager packageManager =
getPackageManager();
List<ResolveInfo> activities =
packageManager.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;
if (isIntentSafe) startActivity(mapIntent);
Related documents