Wednesday, March 7, 2012

Play media in Fragment, run on Android 3.0 Tablet.

It's direct port the last exercise "Play media on surfaceview using android.media.MediaPlayer" to Tablet running Android 3.0, without any alignment.

Play media in Fragment, run on Android 3.0 Tablet.

- Change target platform to Android 3.0, API level 11. Right click the project in Package Explorer, select Properties. Select Android tag, and change the Traget Name to Android 3.0, and click OK.

- Create a new PlayerFragment.java class extends Fragment implements SurfaceHolder.Callback. Functionally, it's equivalent to original PlayerActivity.java.
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.widget.Button;
import android.widget.TextView;
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;

TextView mediaUri;
Button buttonPlayVideo, buttonPauseVideo;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.playerlayout, container, false);
mediaUri = (TextView)view.findViewById(R.id.mediauri);
buttonPlayVideo = (Button)view.findViewById(R.id.playvideoplayer);
buttonPauseVideo = (Button)view.findViewById(R.id.pausevideoplayer);
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();


buttonPlayVideo.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {

if(targetUri != null){

pausing = false;

if(mediaPlayer.isPlaying()){
mediaPlayer.reset();
}

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();
}

mediaPlayer.start();
}

}});

buttonPauseVideo.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
if(targetUri != null){
if(pausing){
pausing = false;
mediaPlayer.start();
}
else{
pausing = true;
mediaPlayer.pause();
}
}
}});

return view;
}

@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){
targetUri = u;
mediaUri.setText(u.toString());
}

}


- playerlayout.xml keep no change, it will be used by PlayerFragment.java.
<?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" >

<TextView
android:id="@+id/mediauri"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/playvideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- PLAY Video -"/>
<Button
android:id="@+id/pausevideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- PAUSE Video -"/>
<SurfaceView
android:id="@+id/surfaceview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>

</LinearLayout>


- Implement VideoListFragment.java class extends ListFragment. Basically, move the function from original main activity to this class.
package com.exercise.AndroidListMedia;
import android.app.ListFragment;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class VideoListFragment extends ListFragment {

SimpleCursorAdapter adapter;
final Uri mediaSrc = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
Cursor cursor = adapter.getCursor();
cursor.moveToPosition(position);

String _id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media._ID));

Uri playableUri
= Uri.withAppendedPath(mediaSrc, _id);

AndroidListMediaActivity mainActivity = (AndroidListMediaActivity)getActivity();
mainActivity.myPlayerFragment.setTargetUri(playableUri);
}

@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
String[] from = {
MediaStore.MediaColumns.TITLE};
int[] to = {
android.R.id.text1};

Cursor cursor = getActivity().managedQuery(
mediaSrc,
null,
null,
null,
MediaStore.Audio.Media.TITLE);

adapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, cursor, from, to);
setListAdapter(adapter);
}

}


- Modify main activity and main layout, to include both VideoListFragment and PlayerFragment.
AndroidListMediaActivity.java:
package com.exercise.AndroidListMedia;

import android.app.Activity;
import android.app.FragmentManager;
import android.os.Bundle;

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);

}

}


main.xml:
<?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="horizontal" >

<fragment class="com.exercise.AndroidListMedia.VideoListFragment"
android:id="@+id/videolistfragment"
android:layout_height="match_parent"
android:layout_width="0px"
android:layout_weight="1"
/>

<fragment class="com.exercise.AndroidListMedia.PlayerFragment"
android:id="@+id/playerfragment"
android:layout_height="match_parent"
android:layout_width="0px"
android:layout_weight="3"
/>

</LinearLayout>


- Delete PlayerActivity.java and resume AndroidManifest.xml to remove PlayerActivity.

Download the files.


Next:
- MediaPlay on SurfaceView: correct aspect ratio

No comments: