name: inverse layout: true class: center, middle, inverse --- # Activities and Intents, Revisited Lauren Bricker CSE 340 Winter 23 --- layout: false ## Review: Activity From our first class: [`android.app.Activity`](https://developer.android.com/reference/android/app/Activity) - Represents a single interface - Example: Activities for Gmail App - Inbox, Message Compose, Spam Folder, etc. - Activities can be started by other applications, if desired - E.g., sharing a photo by email starts Gmail's Message Compose activity --- ## Activity Lifecycle .left-column40[ ![:img Android Activity Lifecycle which shows when the operating system starts; pauses and kills android processes, 100%, width](../wk01/img/first-app/activity_lifecycle.png) ] .right-column60[ Recall where we have seen these states of our application ] -- .right-column60[ How do we switch between them? ] -- .right-column60[ Intents! ] --- # In class exercise: To motivate learning about using `Intent` we've created an exercise:
"Fake" - a fake log in system. Do this now - Clone the [CSE340 Intent Practice](https://gitlab.cs.washington.edu/cse340/exercises/cse340-intent-practice) repo - Make sure you're on the `main` branch - There is a `solution` branch but don't look yet. - Look through the repo - what do you see? .footnote[Special thanks to Davin Win Kyi who came up with the idea for this app] --- # Fake Layout Wireframes ![:img Fake layout wireframes for three activities, 70%,width](img/intents/fake-layout-wireframe.png) --- # Fake Interactor Hierarchies ![:img Fake interactor hierarchies for three activities, 100%,width](img/intents/fake-interactor-hierarchy.png) --- # Fake Navigation Flow ![:img Fake application navigation flow, 80%,width](img/intents/fake-navigation-flow.png) --- # Fake Screens |Main Activity | User List | Welcome Page | Web Page | | :--: | :--: | :--: | :--: | |![:img Fake Main Activity Screen,45%,width](img/intents/fake-main-activity.png) ![:img Error on the login screen, 45%,width](img/intents/fake-error-login.png)|![:img Fake users list, 50%,width](img/intents/fake-create-new-user.png)![:img Fake users list, 50%,width](img/intents/fake-many-users.png)|![:img Fake welcome page, 70%,width](img/intents/fake-welcome-page.png)|![:img CSE340 web page shown on mobile, 90%,width](img/intents/fake-web-page.png)| --- # Coding it up What we know * how to create Layouts using the Layout Manager and Code. * how to dynamically change text on the screen * how to use the values in our `.xml` files for good code quality * how to hook up click listeners to the buttons But do we know how to switch from one activity to another? -- count: false Sort of. We saw it in all of the other apps, just kind of overlooked it. --- # Intent "An intent is an abstract description of an operation to be performed." - A passive data structure for holding data - Used for launching activities - Provides a late runtime binding between the code in different applications --- # Intent Primary pieces of information in an `Intent` - **action** -- The general action to be performed, such as ACTION_VIEW, ACTION_EDIT, ACTION_MAIN, etc. - **data** -- The data to operate on, such as a person record in the contacts database, expressed as a Uri. --- # Intent Constructors ```java Intent() // Create an empty intent Intent(Intent o) // Copy constructor Intent(String action) // Create an intent with a given action Intent(String action, Uri uri) // Create an intent with a given action and // for a given data url Intent(Context packageContext, // Create an intent for a specific component Class> cls) // Intent(String action, Uri uri, // Create an intent for a specific component Context packageContext, // with a specified action and data Class> cls) // ``` --- # Examples: switching screens Let's say enters a new user name and password in the fields, then clicks the "Create New User" button. * set up the `onClickListener` * create an intent to go from `MainActivity.this` to `WelcomeActivity.this` ```java Button buttonCreate = findViewById(R.id.mainNewUsername); buttonCreate.setOnClickListener(v-> { // Create the intent to go from one screen to another. Intent intent = new Intent(MainActivity.this, UserListActivity.class); ... // switch to the new the activity startActivity(intent); ``` Do this every time you want to go from one `Activity` to another --- # Getting an intent from the Activity Each activity has an `Intent` object associated with it. So you simply can call `getIntent()` ```java public class MainActivity extends IntentActivity { ... protected void onCreate(Bundle savedInstanceState) { ... Intent myIntent = getIntent(); ... ``` --- # Transferring data Often you need data to transfer from one `Activity` to another as you switch * `Intent` objects can hold "extra" information in key value pairs * These are actually `Bundle` objects... * There are MANY methods to put extra information into the `Intent` extra, examples: ```java putExtra(String key, boolean value) putExtra(String key, char value) putExtra(String key, int value) // or long putExtra(String key, float value) // or double putExtra(String key, String value) // or anything Parceable putExtra(String key, int[] value) // or other array types ``` --- # Examples: putting data into the Intent An example of this is in `IntentActivity.java` ```java // Keys for adding to the Intent Extras public static final String COUNT_KEY = "count"; public static final String USER_KEY = "userinfo"; ... int count = /* count is initialized...*/ newIntent.putExtra(COUNT_KEY, count); ``` --- # Getting data from the Intent There are two ways to get the information back out from the Intent. 1. Ask the `Intent` for the "extras" (`Bundle`) and then use `Bundle` methods ```java String userInfo = getIntent().getExtras().getString(USER_KEY + i); ``` 2. Get the information using a method on the `Intent` directly ```java String userInfo = getIntent().getStringExtra(USER_KEY + i); ``` For `int` values you can specify a default value if the key/value pair does not exist such as `int count = getIntent().getIntExtra(COUNT_KEY, 0);` --- # Your job: Fill in the TODOs! 1. Start with `IntentActivity.java` and filli in the `copyIntentData` method that is used elsewhere in the project. 2. Then finish code in `MainActivity` to handle the two button listeners (one for going to the `UserListActivity`, the other to go to the `WelcomeActivity`) 3. Do the same for the click listener in `UserListActivity` and `WelcomeActivity` to go back to the `MainActivity` 4. Finally, follow the instructions in the `WelcomeActivity` to open up our CSE 340 web page in a browser by using an `Intent` --- # Helpful resources - Android [`Intent`](https://developer.android.com/reference/android/content/Intent) - For saving and getting data in intents [Stackoverflow](https://stackoverflow.com/questions/5265913/how-to-use-putextra-and-getextra-for-string-data) - How to use Intents [video](https://www.youtube.com/watch?v=OoPQnCgVM_A) - How to use a link in an intent on [Stackoverflow](https://stackoverflow.com/questions/3004515/sending-an-intent-to-browser-to-open-specific-url#:~:text=To%20open%20a%20URL%2Fwebsite,ACTION_VIEW)