关于直播的相关信息这里不做详解,我们对直播应该很熟悉,实现生活中有各种直播,他们如何实现的呢,其实开发一个简单不能简单的直播,只需要两个:1、直播地址 2、播放器,对于直播地址我们可以利用很多软件获取连接,播放器,现在开源的也有很多,最常见的就是ffmpeg,但是如果直接用ffmpeg开发工作量比较大,我们可以使用第三方的播放器库,例如vlc,vitamio等等,这里我使用的时vitamio库。
首先建立一个项目,命名为Live,项目建立好了以后我们需要配置vitamio需要的环境,网上有很多,这里就不写出了,添加了依赖库后添加一个主界面,这里我只添加了一个EditView和Button,配置如下:
[html]
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".Live" >
<EditText
android:id="@+id/live_url"
android:layout_width="match_parent"
android:layout_height="100dp" />
<Button
android:id="@+id/play"
android:layout_width="120dp"
android:layout_height="60dp"
android:layout_below="@id/live_url"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:text="Play" >
</Button>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".Live" >
<EditText
android:id="@+id/live_url"
android:layout_width="match_parent"
android:layout_height="100dp" />
<Button
android:id="@+id/play"
android:layout_width="120dp"
android:layout_height="60dp"
android:layout_below="@id/live_url"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:text="Play" >
</Button>
</RelativeLayout>
主界面的类:
[java]
package com.jwzhangjie.live;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class Live extends Activity {
public static final String DEFAULTPATH = "http://ipadlive.cntv.soooner.com/cctv_p2p_hdcctv6.m3u8";
EditText Live_Url;
Button PlayBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live);
Live_Url = (EditText)findViewById(R.id.live_url);
Live_Url.setText(DEFAULTPATH);
PlayBtn = (Button)findViewById(R.id.play);
PlayBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(Live.this, JieVideoPlayer.class);
String path = Live_Url.getText().toString();
if (path == null) {
path = DEFAULTPATH;
}
intent.putExtra("path", path);
startActivity(intent);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.live, menu);
return true;
}
}
package com.jwzhangjie.live;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class Live extends Activity {
public static final String DEFAULTPATH = "http://ipadlive.cntv.soooner.com/cctv_p2p_hdcctv6.m3u8";
EditText Live_Url;
Button PlayBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live);
Live_Url = (EditText)findViewById(R.id.live_url);
Live_Url.setText(DEFAULTPATH);
PlayBtn = (Button)findViewById(R.id.play);
PlayBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(Live.this, JieVideoPlayer.class);
String path = Live_Url.getText().toString();
if (path == null) {
path = DEFAULTPATH;
}
intent.putExtra("path", path);
startActivity(intent);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.live, menu);
return true;
}
}
播放界面的类:
[java]
package com.jwzhangjie.live;
import io.vov.vitamio.LibsChecker;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.MediaPlayer.OnCompletionListener;
import io.vov.vitamio.MediaPlayer.OnInfoListener;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoView;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
@SuppressLint("HandlerLeak")
public class JieVideoPlayer extends Activity implements OnCompletionListener, OnInfoListener {
private String mPath;
private String mTitle;
private VideoView mVideoView;
private View mVolumeBrightnessLayout;
private ImageView mOperationBg;
private ImageView mOperationPercent;
private AudioManager mAudioManager;
/** 声音 */
private int mMaxVolume;
/** 当前声音 */
private int mVolume = -1;
/** 当前亮度 */
private float mBrightness = -1f;
/** 当前缩放模式 */
private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;
private GestureDetector mGestureDetector;
private MediaController mMediaController;
private View mLoadingView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!LibsChecker.checkVitamioLibs(this))
return;
// ~~~ 获取播放地址和标
// ~~~ 绑定控件
setContentView(R.layout.videoview);
mPath = getIntent().getStringExtra("path");
mVideoView = (VideoView) findViewById(R.id.surface_view);
mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);
mOperationBg = (ImageView) findViewById(R.id.operation_bg);
mOperationPercent = (ImageView) findViewById(R.id.operation_percent);
mLoadingView = findViewById(R.id.video_loading);
// ~~~ 绑定事件
mVideoView.setOnCompletionListener(this);
mVideoView.setOnInfoListener(this);
// ~~~ 绑定数据
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
if (mPath.startsWith("http:")){
mVideoView.setVideoURI(Uri.parse(mPath));
}
else{
mVideoView.setVideoPath(mPath);
}
//设置显示名称
mMediaController = new MediaController(this);
mMediaController.setFileName(mTitle);
mVideoView.setMediaController(mMediaController);
mVideoView.requestFocus();
mGestureDetector = new GestureDetector(this, new MyGestureListener());
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
@Override
protected void onPause() {
super.onPause();
if (mVideoView != null)
mVideoView.pause();
}
@Override
protected void onResume() {
super.onResume();
if (mVideoView != null)
mVideoView.resume();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mVideoView != null)
mVideoView.stopPlayback();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mGestureDetector.onTouchEvent(event))
return true;
// 处理手势结束
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
endGesture();
break;
}
return super.onTouchEvent(event);
}
/** 手势结束 */
private void endGesture() {
mVolume = -1;
mBrightness = -1f;
// 隐藏
mDismissHandler.removeMessages(0);
mDismissHandler.sendEmptyMessageDelayed(0, 500);
}
private class MyGestureListener extends SimpleOnGestureListener {
/** 双击 */
@Override
public boolean onDoubleTap(MotionEvent e) {
if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)
mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;
else
mLayout++;
if (mVideoView != null)
mVideoView.setVideoLayout(mLayout, 0);
return true;
}
/** 滑动 */
@SuppressWarnings("deprecation")
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
float mOldX = e1.getX(), mOldY = e1.getY();
int y = (int) e2.getRawY();
Display disp = getWindowManager().getDefaultDisplay();
int windowWidth = disp.getWidth();
int windowHeight = disp.getHeight();
if (mOldX > windowWidth * 4.0 / 5)// 右边滑动
onVolumeSlide((mOldY - y) / windowHeight);
else if (mOldX < windowWidth / 5.0)// 左边滑动
onBrightnessSlide((mOldY - y) / windowHeight);
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
/** 定时隐藏 */
private Handler mDismissHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mVolumeBrightnessLayout.setVisibility(View.GONE);
}
};
/**
* 滑动改变声音大小
*
* @param percent
*/
private void onVolumeSlide(float percent) {
if (mVolume == -1) {
mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
if (mVolume < 0)
mVolume = 0;
// 显示
mOperationBg.setImageResource(R.drawable.video_volumn_bg);
mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
}
int index = (int) (percent * mMaxVolume) + mVolume;
if (index > mMaxVolume)
index = mMaxVolume;
else if (index < 0)
index = 0;
// 变更声音
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);
// 变更进度�?
ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
lp.width = findViewById(R.id.operation_full).getLayoutParams().width * index / mMaxVolume;
mOperationPercent.setLayoutParams(lp);
}
/**
* 滑动改变亮度
*
* @param percent
*/
private void onBrightnessSlide(float percent) {
if (mBrightness < 0) {
mBrightness = getWindow().getAttributes().screenBrightness;
if (mBrightness <= 0.00f)
mBrightness = 0.50f;
if (mBrightness < 0.01f)
mBrightness = 0.01f;
// 显示
mOperationBg.setImageResource(R.drawable.video_brightness_bg);
mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
}
WindowManager.LayoutParams lpa = getWindow().getAttributes();
lpa.screenBrightness = mBrightness + percent;
if (lpa.screenBrightness > 1.0f)
lpa.screenBrightness = 1.0f;
else if (lpa.screenBrightness < 0.01f)
lpa.screenBrightness = 0.01f;
getWindow().setAttributes(lpa);
ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);
mOperationPercent.setLayoutParams(lp);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (mVideoView != null)
mVideoView.setVideoLayout(mLayout, 0);
super.onConfigurationChanged(newConfig);
}
@Override
public void onCompletion(MediaPlayer player) {
Log.e("tet", "播放完成");
}
private void stopPlayer() {
if (mVideoView != null)
mVideoView.pause();
}
private void startPlayer() {
if (mVideoView != null)
mVideoView.start();
}
private boolean isPlaying() {
return mVideoView != null && mVideoView.isPlaying();
}
/** 是否�?��自动恢复播放,用于自动暂停,恢复播放 */
private boolean needResume;
@Override
public boolean onInfo(MediaPlayer arg0, int arg1, int down_rate) {
switch (arg1) {
case MediaPlayer.MEDIA_INFO_BUFFERING_START:
//�?��缓存,暂停播�?
if (isPlaying()) {
stopPlayer();
needResume = true;
}
mLoadingView.setVisibility(View.VISIBLE);
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_END:
//缓存完成,继续播�?
if (needResume)
startPlayer();
mLoadingView.setVisibility(View.GONE);
break;
case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
//显示 下载速度
Log.e("test","download rate:" + down_rate);
// mLoadingPerce.setText("正在缓冲�?.."+"缓冲完成�?+down_rate);
//mListener.onDownloadRateChanged(arg2);
break;
}
return true;
}
}
package com.jwzhangjie.live;
import io.vov.vitamio.LibsChecker;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.MediaPlayer.OnCompletionListener;
import io.vov.vitamio.MediaPlayer.OnInfoListener;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoView;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
@SuppressLint("HandlerLeak")
public class JieVideoPlayer extends Activity implements OnCompletionListener, OnInfoListener {
private String mPath;
private String mTitle;
private VideoView mVideoView;
private View mVolumeBrightnessLayout;
private ImageView mOperationBg;
private ImageView mOperationPercent;
private AudioManager mAudioManager;
/** 声音 */
private int mMaxVolume;
/** 当前声音 */
private int mVolume = -1;
/** 当前亮度 */
private float mBrightness = -1f;
/** 当前缩放模式 */
private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;
private GestureDetector mGestureDetector;
private MediaController mMediaController;
private View mLoadingView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!LibsChecker.checkVitamioLibs(this))
return;
// ~~~ 获取播放地址和标
// ~~~ 绑定控件
setContentView(R.layout.videoview);
mPath = getIntent().getStringExtra("path");
mVideoView = (VideoView) findViewById(R.id.surface_view);
mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);
mOperationBg = (ImageView) findViewById(R.id.operation_bg);
mOperationPercent = (ImageView) findViewById(R.id.operation_percent);
mLoadingView = findViewById(R.id.video_loading);
// ~~~ 绑定事件
mVideoView.setOnCompletionListener(this);
mVideoView.setOnInfoListener(this);
// ~~~ 绑定数据
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
if (mPath.startsWith("http:")){
mVideoView.setVideoURI(Uri.parse(mPath));
}
else{
mVideoView.setVideoPath(mPath);
}
//设置显示名称
mMediaController = new MediaController(this);
mMediaController.setFileName(mTitle);
mVideoView.setMediaController(mMediaController);
mVideoView.requestFocus();
mGestureDetector = new GestureDetector(this, new MyGestureListener());
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
@Override
protected void onPause() {
super.onPause();
if (mVideoView != null)
mVideoView.pause();
}
@Override
protected void onResume() {
super.onResume();
if (mVideoView != null)
mVideoView.resume();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mVideoView != null)
mVideoView.stopPlayback();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mGestureDetector.onTouchEvent(event))
return true;
// 处理手势结束
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
endGesture();
break;
}
return super.onTouchEvent(event);
}
/** 手势结束 */
private void endGesture() {
mVolume = -1;
mBrightness = -1f;
// 隐藏
mDismissHandler.removeMessages(0);
mDismissHandler.sendEmptyMessageDelayed(0, 500);
}
private class MyGestureListener extends SimpleOnGestureListener {
/** 双击 */
@Override
public boolean onDoubleTap(MotionEvent e) {
if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)
mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;
else
mLayout++;
if (mVideoView != null)
mVideoView.setVideoLayout(mLayout, 0);
return true;
}
/** 滑动 */
@SuppressWarnings("deprecation")
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
float mOldX = e1.getX(), mOldY = e1.getY();
int y = (int) e2.getRawY();
Display disp = getWindowManager().getDefaultDisplay();
int windowWidth = disp.getWidth();
int windowHeight = disp.getHeight();
if (mOldX > windowWidth * 4.0 / 5)// 右边滑动
onVolumeSlide((mOldY - y) / windowHeight);
else if (mOldX < windowWidth / 5.0)// 左边滑动
onBrightnessSlide((mOldY - y) / windowHeight);
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
/** 定时隐藏 */
private Handler mDismissHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mVolumeBrightnessLayout.setVisibility(View.GONE);
}
};
/**
* 滑动改变声音大小
*
* @param percent
*/
private void onVolumeSlide(float percent) {
if (mVolume == -1) {
mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
if (mVolume < 0)
mVolume = 0;
// 显示
mOperationBg.setImageResource(R.drawable.video_volumn_bg);
mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
}
int index = (int) (percent * mMaxVolume) + mVolume;
if (index > mMaxVolume)
index = mMaxVolume;
else if (index < 0)
index = 0;
// 变更声音
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);
// 变更进度�?
ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
lp.width = findViewById(R.id.operation_full).getLayoutParams().width * index / mMaxVolume;
mOperationPercent.setLayoutParams(lp);
}
/**
* 滑动改变亮度
*
* @param percent
*/
private void onBrightnessSlide(float percent) {
if (mBrightness < 0) {
mBrightness = getWindow().getAttributes().screenBrightness;
if (mBrightness <= 0.00f)
mBrightness = 0.50f;
if (mBrightness < 0.01f)
mBrightness = 0.01f;
// 显示
mOperationBg.setImageResource(R.drawable.video_brightness_bg);
mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
}
WindowManager.LayoutParams lpa = getWindow().getAttributes();
lpa.screenBrightness = mBrightness + percent;
if (lpa.screenBrightness > 1.0f)
lpa.screenBrightness = 1.0f;
else if (lpa.screenBrightness < 0.01f)
lpa.screenBrightness = 0.01f;
getWindow().setAttributes(lpa);
ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);
mOperationPercent.setLayoutParams(lp);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (mVideoView != null)
mVideoView.setVideoLayout(mLayout, 0);
super.onConfigurationChanged(newConfig);
}
@Override
public void onCompletion(MediaPlayer player) {
Log.e("tet", "播放完成");
}
private void stopPlayer() {
if (mVideoView != null)
mVideoView.pause();
}
private void startPlayer() {
if (mVideoView != null)
mVideoView.start();
}
private boolean isPlaying() {
return mVideoView != null && mVideoView.isPlaying();
}
/** 是否�?��自动恢复播放,用于自动暂停,恢复播放 */
private boolean needResume;
@Override
public boolean onInfo(MediaPlayer arg0, int arg1, int down_rate) {
switch (arg1) {
case MediaPlayer.MEDIA_INFO_BUFFERING_START:
//�?��缓存,暂停播�?
if (isPlaying()) {
stopPlayer();
needResume = true;
}
mLoadingView.setVisibility(View.VISIBLE);
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_END:
//缓存完成,继续播�?
if (needResume)
startPlayer();
mLoadingView.setVisibility(View.GONE);
break;
case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
//显示 下载速度
Log.e("test","download rate:" + down_rate);
// mLoadingPerce.setText("正在缓冲�?.."+"缓冲完成�?+down_rate);
//mListener.onDownloadRateChanged(arg2);
break;
}
return true;
}
}
播放界面的配置:
[html]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<io.vov.vitamio.widget.VideoView
android:id="@+id/surface_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<LinearLayout
android:id="@+id/video_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_vertical" >
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/video_loading_perce"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="7.0dip"
android:text="@string/video_layout_loading"
android:textColor="@color/white"
android:textSize="20.0sp" />
</LinearLayout>
<FrameLayout
android:id="@+id/operation_volume_brightness"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#00000000"
android:orientation="horizontal"
android:padding="0dip"
android:visibility="invisible" >
<ImageView
android:id="@+id/operation_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/video_volumn_bg" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:paddingBottom="25dip" >
<ImageView
android:id="@+id/operation_full"
android:layout_width="94dip"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:src="@drawable/video_num_bg" />
<ImageView
android:id="@+id/operation_percent"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:scaleType="matrix"
android:src="@drawable/video_num_front" />
</FrameLayout>
</FrameLayout>
</RelativeLayout>