1 mobile computing arrays copyright 2014 by janson industries assg1assg1 extracredit1extracredit1...
TRANSCRIPT
1
Mobile Computing
Arrays
Copyright 2014 by Janson Industries
Assg1 ExtraCredit1Assg2 ExtraCredit2
Copyright 2014 by Janson Industries2
Topics▀ Arrays
▀ Looping/Iteration
▀ More GUI
▀ Timers
▀ Random numbers
▀ Touch listeners
▀ Media players
Copyright 2014 by Janson Industries3
Tic Tac Toe▀ Last piece of our app requires
the extensive use of arrays
▀ An array is a programming data structure that holds multiple values
Think of it as a single row of storage spaces
Copyright 2014 by Janson Industries4
Array▀ An array’s values
Must all be of the same type
Are referred to by an index (aka a subscript)
► The index begins at 0
Can be constant► Fixed values for program use
• Discount rates, zip codes, state abbrs
Can be changed► Multiple user or file input values
• Shopping cart items
Copyright 2014 by Janson Industries5
Array▀ Arrays are fixed in length
i.e. Arrays have a size - the max number of values they can hold
▀ An array is assigned to a variable
Copyright 2014 by Janson Industries6
Array▀ When creating an array
Specify the type of values it will hold
Specify the maximum number of values it will hold
Create and assign the array to a variable
▀ Syntax to create an array new arrayType[size]
► new String[3];► new int[6];
Copyright 2014 by Janson Industries7
Using Arrays In Java▀ To use or access the array, must
assign to a variable
arrayType[ ] varName = new arrayType[size]
►String[] zipCodes = new String[3];
► int[] qtys = new int[6];
Copyright 2014 by Janson Industries8
Array▀ String[] stateAbbrs = new String[4]; results in:
▀ To refer to a particular value, use the array variable name and index number in brackets
▀ stateAbbrs[2] = "FL"; results in
Index 0 1 2 3
Index 0 1 2 3
FL
Copyright 2014 by Janson Industries9
Array▀ Let's be clear:
stateAbbrs[2] = "FL“; results in data being put into the third position of the array
stateAbbrs[4] = "GA" results in?Index 0 1 2 3
FL
An out of bounds error!
Copyright 2014 by Janson Industries10
Looping▀ WHILE and DO WHILE allow
looping based on a condition
▀ FOR allows looping for a set number of iterations based on a
Starting value
Increment value
Ending value
Copyright 2014 by Janson Industries11
Looping▀ WHILE allows looping based on a
condition
▀ FOR allows a certain number of iterations
while (eof == 0) {
statements to be repeated;
}
for (int j = 0; j < 10; j++) {
statements to be repeated;
}
Copyright 2014 by Janson Industries12
Looping▀ DO WHILE checks the condition
after the statements are executed
Therefore, the loop will be executed at least once
do {
statements to be repeated;
} while (eof == 0)
Copyright 2014 by Janson Industries13
Looping▀ BREAK and CONTINUE
provide exits from a loop
▀ Results in: j = 0
j = 1
for (int j = 0; j < 5; j++) {
if (j == 2) {
break;
}
System.out.println("j = " + j);
}
Copyright 2014 by Janson Industries14
Looping
▀ Results in:
for (int j = 0; j < 5; j++) {
if (j == 2) {
continue;}
System.out.println(“j = “ + j);
}
j = 0
j = 1
j = 3
j = 4
Copyright 2014 by Janson Industries15
Loops and Arrays▀ Loops very good way to process
arrays
▀ For example we could easily initialize an array with a for loop
String[] arrayOfStrings = new String[5];
for (int i=0; i<arrayOfStrings.length; i++) {
arrayOfStrings[i] =
new String("This string has the value " + i);
}
Copyright 2014 by Janson Industries16
Loops and Arrays▀ Could display the array’s
contents with this
▀ Ewwwwww…
System.out.println(arrayOfStrings[0]);
System.out.println(arrayOfStrings[1]);
System.out.println(arrayOfStrings[2]);
System.out.println(arrayOfStrings[3]);
System.out.println(arrayOfStrings[4]);
Copyright 2014 by Janson Industries17
Loops and Arrays▀ Much more elegantly
▀ Results in:
for (int i = 0; i < arrayOfStrings.length; i++) {
System.out.println(arrayOfStrings[i]);
}
This string has the value 0This string has the value 1This string has the value 2This string has the value 3This string has the value 4
Copyright 2014 by Janson Industries18
Nested Loops▀ Sometimes loops within loops
needed
▀ What do you think would be the output of this
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i);
}
}
122333444455555
Copyright 2014 by Janson Industries19
Nested Loops▀ How about this
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i);
}
System.out.println("");
}
122333444455555
Copyright 2014 by Janson Industries20
Tic Tac Toe▀ Need a playing board
New XML layout: TableLayout
▀ Each square will have a button
When clicked, button text changed to X or O and button disabled
Need a click handler method
▀ Will have a text view at bottom to give players info
Copyright 2014 by Janson Industries21
Will take the numbers off later
Copyright 2014 by Janson Industries22
tttboard XML▀ New layout (TableLayout) and a
couple new attributes:
Gravity controls both vertical and horizontal alignment
dp stands for density independent pixels ► Buttons will size correctly for different
screen resolutions
layout_marginTop controls space between title bar and layout
Copyright 2014 by Janson Industries23
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"android:layout_height="fill_parent" android:gravity="center_horizontal"android:background="#000000"><TableLayout android:id="@+id/play_grid"
android:layout_width="fill_parent" android:layout_height="wrap_content"android:layout_marginTop="5dp">
<TableRow android:gravity="center_horizontal"><Button android:id="@+id/one" android:layout_width="100dp"
android:layout_height="100dp" android:text="1" android:textSize="70dp" android:onClick="clickHandler"/>
<Button android:id="@+id/two" android:layout_width="100dp"android:layout_height="100dp" android:text="2"android:textSize="70dp" android:onClick="clickHandler" />
<Button android:id="@+id/three" android:layout_width="100dp"android:layout_height="100dp" android:text="3"android:textSize="70dp" android:onClick="clickHandler"/>
</TableRow>
tttboard XML
Copyright 2014 by Janson Industries24
<TableRow android:gravity="center_horizontal"><Button android:id="@+id/four" android:layout_width="100dp"
android:layout_height="100dp" android:text="4" android:textSize="70dp" android:onClick="clickHandler"/>
<Button android:id="@+id/five" android:layout_width="100dp"android:layout_height="100dp" android:text="5"android:textSize="70dp" android:onClick="clickHandler"/>
<Button android:id="@+id/six" android:layout_width="100dp"android:layout_height="100dp" android:text="6" android:textSize="70dp" android:onClick="clickHandler"/>
</TableRow>
<TableRow android:gravity="center_horizontal"><Button android:id="@+id/seven" android:layout_width="100dp"
android:layout_height="100dp" android:text="7" android:textSize="70dp" android:onClick="clickHandler"/>
<Button android:id="@+id/eight" android:layout_width="100dp"android:layout_height="100dp" android:text="8" android:textSize="70dp" android:onClick="clickHandler"/>
<Button android:id="@+id/nine" android:layout_width="100dp"android:layout_height="100dp" android:text="9" android:textSize="70dp" android:onClick="clickHandler"/>
</TableRow></TableLayout>
Copyright 2014 by Janson Industries
tttboard XML
25
<TextView android:id="@+id/information" android:layout_width="fill_parent"android:layout_height="wrap_content" android:text="info"android:gravity="center_horizontal" android:layout_marginTop="20dp"android:textSize="20dp" android:textColor="#ffffff" />
</LinearLayout>
▀ Need a new activity called TTTActivity
▀ TTTActivity needs variables for An array of Buttons TextView
Copyright 2014 by Janson Industries
package my.first.pkg;
import android.app.Activity;import android.os.Bundle;import android.widget.Button;import android.widget.TextView;
public class TTTActivity extends Activity {private Button tttButtons[];private TextView infoTV;private int boardSize = 9;public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tttboard); tttButtons = new Button[boardSize]; tttButtons[0] = (Button) findViewById(R.id.one); tttButtons[1] = (Button) findViewById(R.id.two); tttButtons[2] = (Button) findViewById(R.id.three); tttButtons[3] = (Button) findViewById(R.id.four); tttButtons[4] = (Button) findViewById(R.id.five); tttButtons[5] = (Button) findViewById(R.id.six); tttButtons[6] = (Button) findViewById(R.id.seven); tttButtons[7] = (Button) findViewById(R.id.eight); tttButtons[8] = (Button) findViewById(R.id.nine); infoTV = (TextView) findViewById(R.id.information); }
} 26
Get the buttonsAnd text view
Copyright 2014 by Janson Industries27
Tic Tac Toe▀ Need to initialize the board
Take the numbers off
Enable the buttons
Prompt the players to start
▀ Will create a new method called start to do this
Copyright 2014 by Janson Industries28
Copyright 2014 by Janson Industries29
TTTActivity▀ Need to code click handler to
Change button text to correct symbol
Disable the clicked button
Prompt the other player to go►Must have a new class level variable to
keep track of who’s turn it is
►start() must initialize to Xprivate String whosTurn;
whosTurn = "X";
Copyright 2014 by Janson Industries30
import android.view.View;import android.graphics.Color; : : : :private String whosTurn;
: : : : public void clickHandler(View target){ for (int i = 0; i < tttButtons.length; i++) { if (target == tttButtons[i]){ tttButtons[i].setEnabled(false); tttButtons[i].setText(whosTurn); if (whosTurn == "X"){ tttButtons[i].setTextColor(Color.GREEN); whosTurn = "O"; } else { tttButtons[i].setTextColor(Color.RED); whosTurn = "X";} infoTV.setText("It's " + whosTurn + "'s turn now." ); break; } } }
Click Handler
Copyright 2014 by Janson Industries31
public boolean onOptionsItemSelected(MenuItem item) {if (item.getItemId() == R.id.browser) {
Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://fscj.edu"));startActivity(intent);
} else {if (item.getItemId() == R.id.order) {
Intent intent = new Intent("my.first.pkg.ShowOrder");startActivity(intent);
} else {if (item.getItemId() == R.id.end) {
finish();} else {
String actionName = "my.first.pkg.TTTActivity";Intent intent = new Intent(actionName);startActivity(intent);
}}
}return true;
}
Tic Tac Toe▀ Modify HowdyActivity to run it
Copyright 2014 by Janson Industries32
Tic Tac Toe▀ Add Tic Tac Toe activity to the
AndroidManifest.xml
▀ Run app, display menu, choose Play Tic Tac Toe
<activity android:name="TTTActivity" android:label="Tic Tac Toe" > <intent-filter> <action android:name="my.first.pkg.TTTActivity" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter></activity>
Copyright 2014 by Janson Industries33
Copyright 2014 by Janson Industries34
Copyright 2014 by Janson Industries35
Copyright 2014 by Janson Industries36
Graded Assg 1
▀ Create a method called checkForGameOver that
Checks for a winner and ties►Use loops to check for winners
Displays the messages►X won►O won►It’s a tie
Copyright 2014 by Janson Industries37
Graded Assg 1
▀ Have the program keep track of how many wins for X and O and how many ties
▀ Add a textview beneath the message to display the number of wins for X and O and ties
Copyright 2014 by Janson Industries38
Graded Assg 1▀ Add a menu and
function, so that the user can start a new game
▀ Store menu definition in a file called new_game.xml
Copyright 2014 by Janson Industries39
Copyright 2014 by Janson Industries40
Example after 5 games
Copyright 2014 by Janson Industries41
Whack a Square▀ Program will randomly display a
square on the screen for a second
▀ If user touches square, they get a point
▀ Will need a timer and random number generator to move the square around
▀ Game lasts 30 seconds
Copyright 2014 by Janson Industries42
Will keep score & display a timer to count down the time left to play
Copyright 2014 by Janson Industries43
Created new project, package, activity and layout. Changed layout to above.
Copyright 2014 by Janson Industries44
WhackaSquare Activity
▀ For displaying, can draw a View on the screen (aka canvas) from within the program
▀ Instead of xml layout
▀ Create a class that is a View
▀ Then draw the view on the screen
Copyright 2014 by Janson Industries45
WhackaSquare
▀ Create a new View class called SquareCtrl to display the square, sense hits, keep score
▀ Make its superclass View
▀ Implement OnTouchListener
▀ Generate inherited abstract methods
Copyright 2014 by Janson Industries46
Will have an error
Hover over red squiggly, select first suggested fix to insert constructor
Copyright 2014 by Janson Industries47
Should look like this
Copyright 2014 by Janson Industries48
Whack a Square▀ SquareCtrl needs class level variables for
▀ X and Y location coordinates for the square
▀ Number of clicks, hits, success percentage
▀ Have Eclipse generate getters and setters▀ Select the code, ALT+SHIFT+S, Generate Getters and
Setters
private int xCord, yCord;private double attempts, score, percentage;
Copyright 2014 by Janson Industries49
WhackaSquare▀ SquareCtrl needs a new method called move which will
▀ Generate random numbers to be used to calculate the x and y coordinates
▀ Do this by▀ Getting the current width and height of the screen▀ Multiplying them by the random number (a decimal value between 0
and 1)
Copyright 2014 by Janson Industries50
Random Number Generators▀ Not really random
▀ Complicated algorithm to imitate randomness
▀ Random method needs a “seed” number
▀ Traditionally use the current time’s milliseconds
Copyright 2014 by Janson Industries51
X and Y Coordinates▀ When specified for location of square, indicates
the upper left location of the square
▀ So can’t have coords at bottom or rightmost of screen because part of square would be off screen
▀ Also need to not put square in score area at bottom
Copyright 2014 by Janson Industries52
import java.util.Random; : : :protected void move(){
Random randomNumGenerator = new Random();randomNumGenerator.setSeed(System.currentTimeMillis());int w = this.getWidth()-20;int h = this.getHeight()-40;float randomNum = randomNumGenerator.nextFloat();this.setxCord((int)(randomNum * w));randomNum = randomNumGenerator.nextFloat();this.setyCord((int)(randomNum * h));
}
SquareCtrl - move()
Copyright 2014 by Janson Industries53
SquareCtrl - onDraw()▀ When component is placed on
screen, its onDraw() invoked
▀ Override onDraw() and change to:
▀ Call move()
▀ Set background color to black
▀ Draw a 20x20 pixel red square at the random location
▀ Display score, percentage, time left
Copyright 2014 by Janson Industries
▀ Need to import graphics.*
▀ Need class level variables to calculate time
▀ In constructor, attach the listener to the view and set start time
import android.graphics.*; : : :int elapsedTime, startTime, timeLeft;String timeLeftString;
54
SquareCtrl - onDraw()
this.setOnTouchListener(this);startTime = (int)System.currentTimeMillis()/1000;
Copyright 2014 by Janson Industries
protected void onDraw(Canvas canvas) {super.onDraw(canvas);move();canvas.drawColor(Color.BLACK);Paint squareColor = new Paint();squareColor.setColor(Color.RED);canvas.drawRect(xCord, yCord, xCord+20, yCord+20, squareColor);Paint scoreColor = new Paint();scoreColor.setColor(Color.WHITE);scoreColor.setTextSize(20);canvas.drawText("Score: " + (int)score + " Attempts: " +
(int)attempts + " Percentage: " + (int)percentage + "%", 10, this.getHeight()- 5, scoreColor);
elapsedTime = (int)System.currentTimeMillis()/1000 - startTime ;timeLeft = 30 - elapsedTime;if (timeLeft <= 0){timeLeft = 0;} //so negative time not showntimeLeftString = String.valueOf(timeLeft);canvas.drawText(timeLeftString, this.getWidth()-25, this.getHeight()- 5, scoreColor);
}55
SquareCtrl - onDraw()
Copyright 2014 by Janson Industries56
SquareCtrl - detectHit(int x, int y)▀ When screen touched, will invoke detectHit
▀ Supply location of touch
▀ Must calculate if touch within square boundary
▀ See if location is within the width and height of square location
Copyright 2014 by Janson Industries57
SquareCtrl - detectHit(int x, int y)
protected boolean detectHit(int x, int y) {if ((x >= xCord && x <= xCord + 20) && (y >= yCord && y <= yCord + 20)) {
return true;} else {
return false;}
}
Copyright 2014 by Janson Industries58
SquareCtrl - onTouch()▀ When screen touched, the
onTouchListener’s onTouch method is invoked
▀ Must extract location of touch from event object and invoke detectHit
Copyright 2014 by Janson Industries59
SquareCtrl - onTouch()
public boolean onTouch(View v, MotionEvent event) {attempts = attempts + 1; // calc number of touchesif(detectHit((int)event.getX(), (int)event.getY())){
score = score + 1;}percentage = (score/attempts) * 100;return false;
}
▀ Change onTouch to this
Copyright 2014 by Janson Industries60
Timers▀ Classes that enable you to schedule “tasks”
▀ Schedule means that a task can be:
▀ Set to run at a particular day and time (one shot timer)
▀ To be run repeatedly at some interval
Copyright 2014 by Janson Industries61
Timers & Tasks
TaskCreates
task
Invokes schedule() passing task &
interval
Creates
timer
App
Invokesrun()
1
2
Timer
Copyright 2014 by Janson Industries62
Timers▀ To create and use a Timer
▀Code a TimerTask subclass to perform the task
▀Create a TimerTask subclass variable and object (passing what it needs to perform the task– a SquareCtrl variable/object) and assign the TimerTask object to the variable
▀Create a Timer variable, a Timer object and assign the object to the variable
▀Using the Timer objects schedule method, specify the TimerTask subclass and timing
Copyright 2014 by Janson Industries63
Timers▀ Our app will need two Timers and two
TimerTasks
▀ One Timer (timer) to run WaSqTimerTask, which invokes the SquareCtrl’s move method every second
▀ One Timer (endOfGameTimer) to run the EndGame TimerTask, which cancels the first Timer (timer), after approx 30 seconds
Copyright 2014 by Janson Industries64
TimerTasks▀ Create a subclass of TimerTask
▀ WaSqTimerTask
▀ Create a method called run (that will be invoked by the timer)
▀ WaSqTimerTask needs a SquareCtrl object and, in run, executes its move function
▀ Will also invoke postInvalidate to force the view to be redrawn
Copyright 2014 by Janson Industries65
WhackaSquare
Invokesmove()
SquareControl
sq
WaSqTimerTask
Creates
sq
Creates
task
Invokes schedule() passing task &
interval
Creates
timer
WaSq
Invokesrun()
1
2
3
Timer
Copyright 2014 by Janson Industries66
WaSqTimerTaskpackage com.mygames.www;
import java.util.TimerTask;
public class WaSqTimerTask extends TimerTask {SquareCtrl sc;public WaSqTimerTask(SquareCtrl s){
sc = s;} public void run() {
sc.move(); //execute the move methodsc.postInvalidate(); //forces a draw
}
}
Copyright 2014 by Janson Industries67
EndGame TimerTask
▀ Will need the original Timer object - timer (created to run the game and change the square location )
▀ Will invoke that timers cancel method to end the game
Copyright 2014 by Janson Industries68
EndGame TimerTaskpackage com.mygames.www;
import java.util.Timer;import java.util.TimerTask;
public class EndGame extends TimerTask { Timer gameTimer;
public EndGame(Timer t){gameTimer = t;
}
public void run() {gameTimer.cancel();
}}
Copyright 2014 by Janson Industries69
Pulling It All Together▀ WhackaSquare activity needs to create
▀ The initial SquareCtrl View and put it in on the screen
▀ The timer to run WaSqTimerTask every second
▀ The timer to run EndGame after 30.5 seconds
Copyright 2014 by Janson Industries70
WhackaSquarepackage com.mygames.www;
import java.util.Date;import java.util.Timer;import android.app.Activity;import android.os.Bundle;
public class WhackaSquare extends Activity {private SquareCtrl sq;private Timer timer, endOfGameTimer;private WaSqTimerTask task; private EndGame endGameTask;
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setTitle("Whack a Square"); sq = new SquareCtrl(this.getBaseContext()); setContentView(sq); //puts SquareCtrl on screen
Copyright 2014 by Janson Industries71
Timer Schedule Method▀ Must specify the task to be
performed
▀ For recurring execution: must specify when to invoke the task’s run method and how often thereafter to call the run method
▀ In milliseconds
Copyright 2014 by Janson Industries72
Timer Schedule Method▀ For one time execution must
specify
▀ The task to be performed
▀ The date/time to execute the task
▀ We will retrieve the current date/time and add 30.5 seconds to it
▀ Extra half a second to let SquareCtrl start up
Copyright 2014 by Janson Industries73
WhackaSquare task = new WaSqTimerTask(sq); // creates timer task
timer = new Timer(); // creates timer timer.schedule(task, 0, 1000); // timer set to 1 second
endOfGameTimer = new Timer(); // creates 2nd timer endGameTask = new EndGame(timer); // sends 1st timer
// end time set to 30.5 seconds from now Date endTime = new Date(System.currentTimeMillis() + 30500);
// timer set to execute 30.5 seconds from now endOfGameTimer.schedule(endGameTask, endTime);}
}
Copyright 2014 by Janson Industries74
▀ Run to test
Copyright 2014 by Janson Industries75
App Probs – Extra Credit 1▀ Have to change source code to
rerun and can’t end game
▀ Add a menu with options to play a new game or exit the application
▀ If new game need to reset score and time
▀ Add options to change speed and size of square
Copyright 2014 by Janson Industries76
New menu
Copyright 2014 by Janson Industries77
App Probs – Extra Credit 1▀ If set to easy, make square 25%
bigger and move every 1.25 seconds
▀ If set to hard, make square 25% smaller and move every .75 seconds
Copyright 2014 by Janson Industries78
MusicPlayer▀ New app will have an initial
splash screen controlled by a handler
▀ Then display a list of songs, images and buttons
▀ When song button pressed, song will play
Copyright 2014 by Janson Industries79
Initial splash screen displayed for 5 seconds
Copyright 2014 by Janson Industries80
Then main screen with song images, text and play/pause buttons
Copyright 2014 by Janson Industries81
Create a new projectClick Next for next 3 screens
Copyright 2014 by Janson Industries82
Add a new activity
Copyright 2014 by Janson Industries83
MusicPlayer
▀ Need to copy/import the splash image (from class website) into the drawable-hdpi folder in the res folder
▀ Then create a new xml layout file called splash in the layout folder in res
Copyright 2014 by Janson Industries84
Right click layout folder, New, Android XML File
Specify the file name, make sure LinearLayout is selected, click Finish
Copyright 2014 by Janson Industries85
MusicPlayer▀ Add a TextView that:
▀ Fills the layout▀ Has the splash image specified for the
background▀ Text centered horizontally at the bottom
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >
<TextView android:id="@+id/textView1" android:layout_width="fill_parent"android:layout_height="fill_parent" android:background="@drawable/splashimage" android:text="My Homemade Music Player"android:gravity="bottom|center_horizontal" android:textSize="35sp">
</TextView></LinearLayout>
Copyright 2014 by Janson Industries86
MusicPlayer▀ Need to change MusicPlayerMain
to display the splash pagepackage my.musicproj.com;
import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.MenuItem;import android.support.v4.app.NavUtils;
public class MusicPlayerMain extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.splash); } public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.music_player_main, menu); return true; }}
Copyright 2014 by Janson Industries87
Run to test
Copyright 2014 by Janson Industries88
MusicPlayer▀ Only want the splash page to be
displayed for 5 seconds
▀ Will use a Handler to delay the display of the main screen
▀ Alternative to a timer
▀ A Handlers postDelayed method lets you specify a time delay and a Runnable object to be executed
Copyright 2014 by Janson Industries89
Handlers
▀ The Handler will execute the Runnable object’s run method
▀ In run, create a new intent to display the main screen
▀ Have MusicPlayerMain invoke a Handlers postDelayed method and create and pass a Runnable object
Copyright 2014 by Janson Industries90
Handlers▀ New concept: an object’s method(s)
can be overridden
▀ Just like an object’s property values can be set, method(s) can be defined when an object is created
▀ After the keyword new and class name, in {} specify the new method
new Handler().postDelayed(new Runnable(){ public void run() {
String actionName = "my.musicproj.com.Player";Intent intent = new Intent(actionName);startActivity(intent);
} }, 5000);
Copyright 2014 by Janson Industries91
Handlers▀ This statement creates Handler and
Runnable objects
▀ Does not assign the objects to variables
▀ When Runnable object created, run method defined
▀ And passed to the postDelayed method with time delay in milliseconds
new Handler().postDelayed(new Runnable(){ public void run() {
String actionName = "my.musicproj.com.Player";Intent intent = new Intent(actionName);startActivity(intent);
} }, 5000);
Copyright 2014 by Janson Industries92
MusicPlayerMainpackage my.musicproj.com;
: : : :import android.content.Intent;import android.os.Handler;
: : : :public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.splash); new Handler().postDelayed(new Runnable(){ public void run() {
String actionName = "my.musicproj.com.Player";Intent intent = new Intent(actionName);startActivity(intent);
} }, 5000); }
: : : :
Copyright 2014 by Janson Industries93
Music Player▀ Need the new activity defined
in the manifest file
▀ Have to create Player class to display main layout
<activity android:name="Player" android:label="Play Music" > <intent-filter> <action android:name="my.musicproj.com.Player" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter></activity>
Copyright 2014 by Janson Industries94
Player▀ Simply displays the main screen
for the music player
package my.musicproj.com;
import android.app.Activity;import android.os.Bundle;
public class Player extends Activity {
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.setContentView(R.layout.main);
}
}
Copyright 2014 by Janson Industries95
MusicPlayer▀ Run to test
▀ Splash should be displayed for 5 seconds
▀ Then Hello world screen (generated by Eclipse) will be displayed
▀ Want to change generic main to list songs that can be played and look like this…
Copyright 2014 by Janson Industries96
Main screen
Copyright 2014 by Janson Industries97
Themes▀ Predefined colors and
components
▀ Used instead of specifying individual component properties
▀ layout background color▀ text color
▀ In the Activity definition (in the Manifest) specify the theme
<activity android:name="Player" android:label="Play Music" android:theme="@android:style/Theme.Black">
Copyright 2014 by Janson Industries98
Black background, white text
Copyright 2014 by Janson Industries99
MusicPlayer
▀ Need to copy artist images into the drawable-hdpi folder in the res folder
Copyright 2014 by Janson Industries100
main.xml▀ For each song, show:
▀ A picture of the artist
▀ Name of the song
▀ A play button
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"android:layout_height="fill_parent"><LinearLayout
android:orientation="horizontal" android:layout_width="wrap_content"android:layout_height="wrap_content"><ImageView android:id="@+id/artist1" android:src="@drawable/artist1"
android:layout_width="90dip" android:layout_height="90dip" />
Copyright 2014 by Janson Industries101
Main Screen<Button android:id="@+id/one" android:layout_width= "80dp"
android:onClick="clickHandler" android:layout_height="45dp"android:text="Play" android:textSize="20dp" android:layout_gravity="center_vertical"android:gravity="center_vertical|center_horizontal" />
</LinearLayout><TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="Afraid To Fail"android:layout_gravity="center_horizontal" />
<LinearLayout android:orientation="horizontal" android:layout_width="wrap_content"android:layout_height="wrap_content"><ImageView android:id="@+id/artist2"
android:layout_width="90dip" android:layout_height="90dip"android:src="@drawable/artist2" />
<Button android:id="@+id/two" android:layout_width= "80dp"android:onClick="clickHandler" android:layout_height="45dp"android:text="Play" android:textSize="20dp" android:layout_gravity="center_vertical"android:gravity="center_vertical|center_horizontal" />
</LinearLayout><TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="Crazy About You"android:layout_gravity="center_horizontal" />
</LinearLayout>
Copyright 2014 by Janson Industries102
MusicPlayer
▀ Time to test
▀ Takes a lot longer to load because of the image files
▀ Splash screen displayed
▀ Then 5 seconds later...
Copyright 2014 by Janson Industries103
Main screen displayed
Copyright 2014 by Janson Industries104
Music Files▀ Traditionally stored in res
folder in a subfolder called raw
▀ Need to create the raw folder then copy/import the mp3 files into it
Copyright 2014 by Janson Industries105
Player▀ Have to add function to play songs
after button clicked
▀ Will need variables for the buttons and two media players
▀ Must add OnClickListeners to the buttons and create an onClick method
▀ onClick determines which button was clicked and plays song
Copyright 2014 by Janson Industries106
Variables
import android.media.MediaPlayer;import android.widget.Button;
public class Player extends Activity {
Button oneBtn, twoBtn;MediaPlayer oneMP, twoMP;
: : :
▀ MediaPlayers are objects that will allow music to be played
Copyright 2014 by Janson Industries
package my.musicproj.com;
import android.app.Activity;import android.os.Bundle;import android.media.MediaPlayer;import android.widget.Button;import android.view.View;import android.view.View.OnClickListener;
public class Player extends Activity implements OnClickListener {Button oneBtn, twoBtn;MediaPlayer oneMP, twoMP;
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.setContentView(R.layout.main);oneBtn = (Button)this.findViewById(R.id.one);twoBtn = (Button)this.findViewById(R.id.two);oneBtn.setOnClickListener(this);twoBtn.setOnClickListener(this);
}
public void onClick(View v){}} 107
Buttons
Copyright 2014 by Janson Industries108
MediaPlayers▀ Create the MediaPlayer object
with the static MediaPlayer method create()
▀ And specify the song file to tie to the media player
: : : protected void onCreate(Bundle savedInstanceState) {
: : : twoBtn.setOnClickListener(this); oneMP = MediaPlayer.create(this, R.raw.song1); twoMP = MediaPlayer.create(this, R.raw.song2);}
Copyright 2014 by Janson Industries109
MediaPlayers▀ Three methods to control
the music
▀ start()
▀ pause()
▀ stop()▀ To use MediaPlayer after it is
stopped, must invoke prepare()
Copyright 2014 by Janson Industries110
onClick▀ When first button is pushed,
start the first media player
▀ When second button is pushed start the second media player
public void onClick(View v){if (oneBtn == (Button) v) {
oneMP.start();} else {
twoMP.start();}
}
Copyright 2014 by Janson Industries111
App Problems
▀ If you click the first button and then the second both songs play
▀ No way to stop song once started
Copyright 2014 by Janson Industries112
Graded Assg 2 ▀ When play button clicked change
text on button to pause
▀ When play button clicked, check to see if other song is playing (use MP’s isPlaying()), if it is, pause it and change that buttons text to play
▀ When pause btn clicked, pause the song, change text to play
Copyright 2014 by Janson Industries113
Assg 2
▀ Initial display
▀ First button clicked▀ First song played▀ Text changed to Pause
Copyright 2014 by Janson Industries114
Assg 2▀ First button clicked again
▀ First song paused ▀ Text changed to Play
▀ First button clicked again▀ First song resumed▀ Text changed to Pause
Copyright 2014 by Janson Industries
▀ First button clicked▀ Second song paused▀ Second button text changed to Play▀ First song played▀ First button text changed to Pause
115
▀ Second button clicked▀ First song paused▀ First button text changed to Play▀ Second song played▀ Second button text changed to Pause
Copyright 2014 by Janson Industries116
Extra Credit Assg 2
▀ In Whack A Square, add sounds for hits and misses
Copyright 2014 by Janson Industries
package my.other.music;
import java.io.IOException;import android.app.Activity;import android.media.MediaPlayer;import android.os.Bundle;
public class Main extends Activity { MediaPlayer urlMP; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); urlMP = new MediaPlayer(); try {
urlMP.setDataSource("http://web.fscj.edu/Janson/CIS2930/sample.mp3"); urlMP.prepare();
} catch (IllegalArgumentException e) {e.printStackTrace();
} catch (IllegalStateException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
} urlMP.start(); }}
117
Other Options▀ Can run music from a URL
▀ You’ll notice how much faster the app loads/installs
Copyright 2014 by Janson Industries118
Must add <uses-permission android:name="android.permission.INTERNET" />
to Manifest
Copyright 2014 by Janson Industries119
Other Options▀ Run music from the phone’s SD card▀ We defined SD card earlier when we created the emulator
▀ But if you didn’t, you can change
Copyright 2014 by Janson Industries120
Other Options
▀ Specify 100 (MB)
Copyright 2014 by Janson Industries121
Go to DDMS perspective, click File Explorer, then sdcard
Copyright 2014 by Janson Industries122
To move a file onto SD Card, click the Push file onto device button
Copyright 2014 by Janson Industries123
Select file, click Open
Copyright 2014 by Janson Industries124
sdcard folder wont look any different
Indictes the folder to expand, in this case storage
Copyright 2014 by Janson Industries125
Scroll down and expand storage and then sdcard folder and you’ll see the
uploaded file
Copyright 2014 by Janson Industries
package my.other.music;
import java.io.IOException;import android.app.Activity;import android.media.MediaPlayer;import android.os.Bundle;
public class Main extends Activity { MediaPlayer urlMP; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); urlMP = new MediaPlayer(); try {
urlMP.setDataSource("/sdcard/sample.mp3"); urlMP.prepare();
} catch (IllegalArgumentException e) {e.printStackTrace();
} catch (IllegalStateException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
} urlMP.start(); }}
126
Other Options▀ Run music
from SD card
▀ Also will load & install faster
Copyright 2014 by Janson Industries127
MediaPlayer▀ When finished with MP, execute its release method
▀ Frees up memory
▀ But more importantly, failure to release▀ May lead to continuous battery consumption ▀ Playback failure for other applications
Copyright 2014 by Janson Industries128
MediaPlayer▀ For example, Player's onPause()
could have the releases
▀ Then move all the media player creations to onRestart()
▀ Also, should have a menu or button to close app that calls onDestroy()
▀ In onDestroy(), call finish() which release all resources