Sans Pareil Technologies, Inc.

Key To Your Business

Lab 3: Intents

Explicit Intent

  • Copy the Lab2 project directory to a new directory named Lab3a.
  • Modify the NumberAdapter implementation and make it more like a true dynamic data adapter
    • Create a new class named Item.  An Item will represent a data entity that will provide the data that we wish to display in an individual grid cell.
      • Add a private final int field named index.
      • Let the IDE generate the constructor.
      • Right-click the field and use Refactor->Encapsulate Fields option to generate the "getter" method.
      • Use the Code->Override Methods menu to override the equals(), hashCode() and toString() methods.
      • Return 31 + ( 31 * index ) from the hashCode() method.
      • Add a method getTitle() that returns the String "Cell i" i is the index (or index + 1).
      • Make the overridden toString() method return getTitle().
      • Add a method getDescription() that returns the result of getTitle() repeated 100 times or so (separated by a space).
      • Implement equals() similar to return ( o instanceof Item ) && index == ( (Item) o ).index;
    • Create a new class of kind Singleton named Database.  This will serve as our Data Access Object (DAO) for this project.
      • Introduce a private final field of type Map<Integer,Item> named map and initialize it to a HashMap instance.  This will just cache Item instance we create to avoid re-creating the same Item entity multiple times as the user scrolls the grid view.
      • Create a new method named getItem that takes an int parameter and returns an Item.
        • Check the map instance for a key at specified parameter.
        • If an entry does not exist, insert a new entry.
        • Return the value stored in the map for the specified parameter.
      • Create a new method named getCount() that returns the number of items available in our database (100 for instance).
    • Use the Item class in NumberAdapter
      • Modify the getItem() method to use the getItem method in the Database singleton.
      • Modify the getCount() method to use the getCount method in the Database singleton.
      • Modify the getView() method to use the Object (Item instance) returned by getItem() to set the tag and text in the TextView.
        final Item item = (Item) getItem( position );
        textView.setTag( item );
        textView.setText( item.getTitle() );
  • Add a new blank activity named ItemView to the project (in the same package as other sources).  This will be used to display the details of a user selected Item from the grid view.
    • Edit the layout file for the activity and add two TextView's to it - title (for displaying item title) and description (for displaying item description).  Set the lines property for the description widget to 10 or so.
    • Edit the onCreate() method in the activity and retrieve the item index in the intent to set the text in the TextView.
      final int index = getIntent().getExtras().getInt( "index" );
      final Item item = Database.getInstance().getItem( index );
      ( (TextView) findViewById( R.id.title ) ).setText( item.getTitle() );
      ( ( TextView) findViewById( R.id.description ) ).setText( item.getDescription() );
  • Modify the ClickListener class that handles clicks on the grid cells to create a new intent and start the ItemView activity instead of displaying the Toast message.
    final TextView tv = (TextView) v;
    final Item item = (Item) tv.getTag();
    final Intent intent = new Intent( context, ItemView.class );
    intent.putExtra( "index", item.getIndex() );
    context.startActivity( intent );
  • Run and check the application.
  • Update the test suite to match the changes.  Edit the MainActivityTest source file
    • Remove the allCells method.
    • Modify the cell() method to use the Item instance for validation instead of the hard-coded string.
    • Modify the onClick() method to validate the title and description displayed in the ItemView activity after performing the click.
      sleep( 500 );
      onView( withId( R.id.title ) ).check( matches( withText( item.getTitle() ) ) );
      onView( withId( R.id.description ) ).check( matches( withText( item.getDescription() ) ) );

Implicit Intent

We will now make our ItemView activity available to be launched from other applications installed on the device/emulator.  To do so will add an intent-filter for the ItemView activity, and then create a new application that will use an implicit intent to launch the ItemView activity developed earlier.

  • Edit the manifest file and add intent filters to the ItemView activity.
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="mis142/item"/>
    </intent-filter>
  • Run the application to register the intent filter in Android.
  • Create a new empty activity project named Lab3b.  Remove the appcompat library support and set the instrumentation runner for testing.
  • Edit the layout file and add a button with text "Launch Item View".
  • Attach a click listener to the button which will launch the ItemView activity in the Lab3a application.
    final Button button = (Button) findViewById( R.id.button );
    button.setOnClickListener( new OnClickListener() {
      @Override
      public void onClick( View v )
      {
        final Intent intent = new Intent( Intent.ACTION_VIEW );
        intent.putExtra( "index", 10 );
        intent.setType( "mis142/item" );

        if ( intent.resolveActivity( getPackageManager() ) != null ) startActivity( intent );
        else Log.e( getClass().getName(), "Unable to resolve intent" );
      }
    } );
  • Run the Lab3b application and verify that the ItemView activity is loaded.
  • Create an automated test class as before, add a Rule and a test onClick method.  Sleep 500 milliseconds after performing the click action on the button and verify that a new View with specified title is loaded.
    assertNotNull( "View not found", onView( withText( "Cell 11" ) ) );