Wednesday, March 14, 2012

Implement ActionBar for our Media Player App

Further works on last exercise "Display video thumbnail on ListFragment with customized SimpleCursorAdapter", we are going to move the buttons to ActionBar, and use all the PlayerFragment for SurfaceView to play video.

Implement ActionBar for our Media Player App

- Make sure <uses-sdk android:minSdkVersion="11" /> is include in the AndroidManifest.xml. And also set android:screenOrientation="landscape" to use app in landscape.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exercise.AndroidListMedia"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="11" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".AndroidListMediaActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>


- Create /res/menu/menu.xml to define the ActionBar options.
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/itemid_playpause"
android:title="Play/Pause"
android:orderInCategory="0"
android:showAsAction="ifRoom|withText" />
<item
android:id="@+id/itemid_stop"
android:title="Stop"
android:orderInCategory="0"
android:showAsAction="ifRoom|withText" />
</menu>


- Modify AndroidListMediaActivity, to override the methods onCreateOptionsMenu(Menu menu) and onOptionsItemSelected(MenuItem item).
package com.exercise.AndroidListMedia;

import android.app.Activity;
import android.app.FragmentManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

public class AndroidListMediaActivity extends Activity {

PlayerFragment myPlayerFragment;
VideoListFragment myVideoListFragment;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager fragmentManager = getFragmentManager();
myPlayerFragment = (PlayerFragment)fragmentManager.findFragmentById(R.id.playerfragment);
myVideoListFragment = (VideoListFragment)fragmentManager.findFragmentById(R.id.videolistfragment);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu, menu);

return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch(item.getItemId()){
case R.id.itemid_playpause:
myPlayerFragment.doPlayPause();
return true;
case R.id.itemid_stop:
myPlayerFragment.doStop();
return true;
default:
return false;
}
}

}


- Modify playerlayout.xml to re-assign the layout. Use full fragment display area for the SurfaceView.
<?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" >

<SurfaceView
android:id="@+id/surfaceview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" />

</LinearLayout>


- Modify PlayerFragment.java accordingly. Also fix the bug of java.lang.IllegalStateException.
package com.exercise.AndroidListMedia;

import java.io.IOException;

import android.app.Fragment;
import android.graphics.PixelFormat;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.Toast;
import android.media.AudioManager;

public class PlayerFragment extends Fragment
implements SurfaceHolder.Callback {

Uri targetUri = null;

MediaPlayer mediaPlayer;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean pausing = false;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.playerlayout, container, false);
surfaceView = (SurfaceView)view.findViewById(R.id.surfaceview);

getActivity().getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setFixedSize(176, 144);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//mediaPlayer = new MediaPlayer();


return view;
}

public void doPlayPause(){
if (targetUri != null){
if(mediaPlayer.isPlaying()){
mediaPlayer.pause();
}else{
mediaPlayer.start();
}
}

}

public void doStop(){
if (targetUri != null){
mediaPlayer.stop();

try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
}

mediaPlayer.seekTo(0);

}
}

private void doPreSet(){

if(mediaPlayer != null){
mediaPlayer.stop();
mediaPlayer.release();
}

mediaPlayer = new MediaPlayer();

mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDisplay(surfaceHolder);

try {
mediaPlayer.setDataSource(getActivity().getApplicationContext(), targetUri);
mediaPlayer.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
} catch (IllegalStateException e) {
e.printStackTrace();
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
}

/*
* Handle aspect ratio
*/
int surfaceView_Width = surfaceView.getWidth();
int surfaceView_Height = surfaceView.getHeight();

float video_Width = mediaPlayer.getVideoWidth();
float video_Height = mediaPlayer.getVideoHeight();

float ratio_width = surfaceView_Width/video_Width;
float ratio_height = surfaceView_Height/video_Height;
float aspectratio = video_Width/video_Height;

LayoutParams layoutParams = surfaceView.getLayoutParams();

if (ratio_width > ratio_height){
layoutParams.width = (int) (surfaceView_Height * aspectratio);
layoutParams.height = surfaceView_Height;
}else{
layoutParams.width = surfaceView_Width;
layoutParams.height = (int) (surfaceView_Width / aspectratio);
}

surfaceView.setLayoutParams(layoutParams);

}

@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}

@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mediaPlayer.release();
}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub

}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub

}

public void setTargetUri(Uri u, int id){
targetUri = u;

getActivity().setTitle("ID: " + id + " / Uri: " + u.toString());

doPreSet();
mediaPlayer.start();
}

}


Download the files.

Next:
- Display video timeline, in ProgressBar

No comments: