Skip to content

Using Activities and Intents

jeremyd edited this page Aug 12, 2012 · 7 revisions

This page will explore the basics of using activities and intents in the context of a Ruboto app. Following the basics, you'll find an example using three activities for a camera app.

Prerequisites

  • You should have completed the Getting started with Ruboto tutorial.
  • To follow the camera example: A connected Android device with display and camera.

*New Activity Usage

  • Important Note! The sections below this document the old style of writing an Activity.
  • We have awesome new ways to use activities and intents and the best way to read about them is in Ruboto's test for them here: ruboto/test/activity/navigation_activity.rb.

RubotoActivity Basics

  • RubotoActivity is a subclass of Activity with special hooks for setting up and calling code within the JRuby script container.

  • ruboto gen app creates one subclass of RubotoActivity with the main purpose of loading the related script when the activity is fired.

  • You can create other RubotoActivity subclasses through ruboto gen class or use the generic RubotoActivity. Reuse RubotoActivity where possible to avoid the need to recompile your app.

  • You can continue to use the standard Android method of creating an Intent and calling startActivity or startActivityForResult. You will need to do this for any activities from other apps or activities from your app that are not subclasses of RubotoActivity.

  • The primary way of firing a RubotoActivity is through start_ruboto_activity. start_ruboto_activity is Ruboto's equivalent of Android's startActivity. It handles the creation of an Intent to launch a new RubotoActivity (or attaches to one that already exists)

    $activity.start_ruboto_activity("$my_demo") do
      ## Unique activity code
    end
  • The two required parameters to start_ruboto_activity are a string for the global reference to the new activity and a block to be executed once the new activity is created (i.e., self in the block is the new activity). The "on" methods defined inside the block become singleton methods attached to the equivalent methods of the activity.

    $activity.start_ruboto_activity("$my_demo") do
      def on_create(bundle)
        ## Set up the activity
      end
    
      ## Other unique activity code
    end
  • start_ruboto_activity has two optional arguments: the activity class to be created (defaults to RubotoActivity) and a theme (defaults to nil for the default theme). This is best seen through the start_ruboto_dialog method which just calls start_ruboto_activity with a subclass of RubotoActivity called RubotoDialog and a dialog theme.

    def start_ruboto_dialog(remote_variable, theme=Java::android.R.style::Theme_Dialog, &block)
      ruboto_import "org.ruboto.RubotoDialog"
      start_ruboto_activity(remote_variable, RubotoDialog, theme, &block)
    end
  • $activity is the global that all activities get assigned to (in addition to the unique global you specify). You can continue to use $activity, but you should not rely on it being the activity that you expect. $activity will always point to the last RubotoActivity launched (even if that activity no longer exists).

  • The main reason to generate your own subclass of RubotoActivity is when you need to specify some custom settings in the Manifest.

Sample Project

This is an example of using Activities and Intents within a Ruboto application. We will launch a main Activity, and then use an Intent to drive the Android camera Activity and return a result. Then, we will display the resulting image with a separate GraphicsView based Activity.

This sample highlights:

  • Generating a Ruboto app with a default activity
  • Building a UI using widgets
  • Handling basic Java Interfaces with Procs
  • Calling an Activity provided by another app using intents
  • Using startActivityForResult to know when the remote activity has finished
  • Launching a second RubotoActivity from within the main activity
  • Generating a subclass of android.view.View to render the camera image

Note: This example uses 'ruboto/generate' code. This code will be released soon. Until it's release, you can generate your own GraphicsView using:

ruboto gen subclass android.view.View --name GraphicsView --method_base on

And then import it using:

ruboto_import_widget :GraphicsView, "org.myname.example"

For this tutorial generate a new ruboto project generated called example:

ruboto gen app --name=example --target=android-8 --package=org.myname.example --activity=Example

Our main activity will be called Example.

example.rb

require 'ruboto/activity'
require 'ruboto/widget'
require 'ruboto/generate'

ruboto_import_widgets :TextView, :LinearLayout, :Button
ruboto_generate_widget("android.view.View" => "#{$package_name}.GraphicsView")

java_import 'android.content.Intent'
java_import "android.util.Log"
java_import 'android.provider.MediaStore'
java_import 'android.net.Uri'
java_import 'android.graphics.BitmapFactory'
java_import 'android.graphics.Rect'
java_import 'android.util.Log'

$activity.start_ruboto_activity("$activity_example") do
  def on_create(bundle)
    setTitle 'Image Capture'

    self.content_view = linear_layout(:orientation => :vertical) do
      @text_view = text_view :text => "Welcome"
      button :text => "Capture", :width => :wrap_content, :on_click_listener => @on_capture_click
      button :text => "Edit", :width => :wrap_content, :on_click_listener => @on_edit_click
    end
  end

  def on_activity_result(requestCode, resultCode, data)
    Log.i("EXAMPLE", "back from activity camera!")
    edit
  end
  
  @on_capture_click = proc do |view|
    capture_intent = Intent.new(MediaStore::ACTION_IMAGE_CAPTURE)
    capture_intent.putExtra(MediaStore::EXTRA_OUTPUT, Uri.fromFile(java.io.File.new("/sdcard/123.jpg")))
    startActivityForResult(capture_intent, 1)
  end

  @on_edit_click = proc do |view|
    edit
  end

  def edit
    start_ruboto_activity("$activity_example_edit") do
      def on_create(bundle)
        setTitle 'Edit'
    
        Log.i("EXAMPLE", "EDIT ACTIVITY STARTING")
        @surface_view = graphics_view
    
        @surface_view.initialize_ruboto_callbacks do
          def on_draw(canvas)
            mBitmap = BitmapFactory.decodeFile("/sdcard/123.jpg")
            mBitmap2 = android.graphics.Bitmap.createScaledBitmap(mBitmap, width, height, false)
            canvas.drawBitmap(mBitmap2, nil, Rect.new(0,0, width, height), nil)
          end
        end
    
        self.content_view = @surface_view
      end
    end
  end
end

We have setup this main activity to call two other activities. One is the Android provided MediaStore::ACTION_IMAGE_CAPTURE. The second opens the edit activity (a second RubotoActivity).

That's all! Install the application and try it out.

rake install start

NOTE: You may have difficulty running this on an Emulator because of bugs with the Emulator VS. the Android API's MediaStore::ACTION_IMAGE_CAPTURE. Run this on a real device and it won't crash.

Have fun!

Clone this wiki locally