編輯:關於Android編程
public class MusicService extends Service {
private MediaPlayer mediaPlayer;
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
@Override
public void onCreate() {
//1 初始化 mediaplayer
mediaPlayer = new MediaPlayer();
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
/**
* 音樂播放暫停的方法
*/
public void pause(){
//暫停
mediaPlayer.pause();
}
/**
* 音樂播放的方法
*/
public void play(){
//重置
mediaPlayer.reset();
//2 設置您播放的資源
try {
mediaPlayer.setDataSource("/mnt/sdcard/xpg.mp3");
//開始准備播放 ,異步准備,不會阻塞
mediaPlayer.prepareAsync(); //mediaPlayer.prepare();//同步准備,會阻塞
//設置medialpayer 准備完成的監聽mediaPlayer.setOnPreparedListener(new OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {//開始播放mediaPlayer.start();// 同步 seekbar 的進度 addSeekBar();}});} catch (Exception e) {e.printStackTrace();}}/**
* 音樂繼續播放的方法 */public void resume(){System.out.println("音樂繼續播放");mediaPlayer.start(); //繼續播放 }//同步seekbar的狀態 public void addSeekBar(){//1獲取到 播放 小蘋果的總的時長 final int duration = mediaPlayer.getDuration();//定時器 Timer timer = new Timer();//要執行的任務TimerTask task =
new TimerTask() {@Overridepublic void run() {//2獲取到當前播放位置 int currentPosition = mediaPlayer.getCurrentPosition();//3 拿著handler 發送消息 Message msg = Message.obtain();//4把 duration 和 currentPosition 存到 msg裡 Bundle bundle = new Bundle(); //創建一個bundle 對象 類似map 集合bundle.putInt("duration",
duration);bundle.putInt("currentPosition", currentPosition);msg.setData(bundle);MainActivity.handler.sendMessage(msg);}}; //50毫秒之後執行 task period 每隔多長時間再次執行tasktimer.schedule(task, 50, 1000);}//改變播放的進度public void seekTo(int progress){mediaPlayer.seekTo(progress);}/**
* 定義一個類 繼承 Binder 對象 定義一個中間人對象 * */private class MyBinder extends Binder implements Iservice{@Overridepublic void callPause() {pause();}@Overridepublic void callPlay() {play();}@Overridepublic void callResume() {resume();}@Overridepublic void callSeekTo(int
progress) {//調用改變進度的方法seekTo(progress);}}}
public class MainActivity extends Activity {
private Iservice iservice; //中間人對象
private MyConn conn;
private static SeekBar sb; //進度條
public static Handler handler = new android.os.Handler(){
public void handleMessage(android.os.Message msg) {
//獲取發送的消息
Bundle data = msg.getData();
int duration = data.getInt("duration");
int currentPosition = data.getInt("currentPosition");
//更新seekbar 的進度
sb.setMax(duration);
sb.setProgress(currentPosition);
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到seekbar
sb = (SeekBar) findViewById(R.id.sb);
//1 我要通過startservice 方法 開啟服務 目的是 為了讓這個服務長期在後台運行
Intent intent = new Intent(MainActivity.this,MusicService.class);
//2開啟服務
startService(intent);
//3 因為我想調用服務裡面的方法 、 通過綁定服務服務 來獲取 中間人對象 間接的調用服務裡面的方法
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);
//設置sb拖動的監聽
sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
//當seekbar 停止拖動
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//肯定服務裡面還要有一個 改變進度的方法
int progress = seekBar.getProgress(); //拿到seekbar 當前的位置 傳給服務裡面的某個方法
iservice.callSeekTo(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
});
}
/**
* 播放音樂
* @param v
*/
public void play(View v){
iservice.callPlay();
}
/**
* 暫停播放音樂
* @param v
*/
public void pause(View v){
iservice.callPause();
}
/**
* 繼續播放播放音樂
* @param v
*/
public void resume(View v){
iservice.callResume();
}
//定義綁定服務的接口
private class MyConn implements ServiceConnection{
//當服務被成功綁定的時候調用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iservice = (Iservice) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
MediaPlayer播放視頻到surfaceview
surfaceview控件
surfaceview表面視圖
雙緩沖區:使用兩個線程協調工作;
surfaceview 重量級空間,當畫面可見時,雙緩沖器被創建,占用較高的cpu和內存資源。
當界面不可見時,雙緩沖器占用釋放。
surfaceview 是一個雙緩沖的機制 提供一共一個表面 內部維護了2個線程
* surfaceview 它也可以在子線程更新ui
* surfaceview 他是一個重量級控件
* 普通的view都是 ondraw()的方法畫出來的
代碼
public class MainActivity extends Activity {
private MediaPlayer mediaPlayer;
private int currentPosition; // 保存進度條當前位置
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
// 得到surfaceview
SurfaceView sfvView = (SurfaceView) findViewById(R.id.sfv);
// SurfaceView使用SurfaceHolder將數據加載到緩沖區
// 通過SurfaceView得到holder
SurfaceHolder holder = sfvView.getHolder();
//推送緩沖數據,api 13之前的版本上必須執行這行代碼,13版本之後,播放器可以自動把
//數據加載到緩沖區
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Suiface被銷毀時調用
currentPosition = mediaPlayer.getCurrentPosition();
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop(); //停止播放
mediaPlayer.release(); // 釋放資源
}
}
// SurfaceView創建完成調用
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 1 創建 MediaPlayer
try {
mediaPlayer = new MediaPlayer();
mediaPlayer
.setDataSource("http://192.168.0.107:8080/M2U05023.MPG");
// 異步准備
mediaPlayer.prepareAsync();
mediaPlayer.setDisplay(holder);//設置顯示到holder
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start(); // 播放
mediaPlayer.seekTo(currentPosition);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
videoview播放視頻
videoview繼承了SurfaceView,封裝了播放視頻的方法,使播放視頻簡單了許多,但surfaceview和videoview只支持3gp和mp4格式
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
VideoView vv = (VideoView) findViewById(R.id.vv);
vv.setVideoPath("http://192.168.12.36:8080/haha.avi");
vv.start();
}
}
使用vitamio框架播放視頻
vitamio 支持大多數格式解碼操作 vitamio 就是對VideoView的封裝 ,是一個類庫
使用ffmpeg解碼
步驟
1 引入vitamio框架,(vitamio是一個類庫,先導入到eclipse,然後再需要使用的項目中右鍵屬性,android標簽下add類庫增加)
2 在布局中定義VideoView(vitamio中的VideoView)
3 mainactivity代碼
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 1 在使用vitamio框架之前 要先初始化vitamio 框架 初始viamio化框架
if (!LibsChecker.checkVitamioLibs(this)) {
return;
}
VideoView vv = (VideoView) findViewById(R.id.vv);
vv.setVideoPath("http://192.168.12.36:8080/haha.avi");
vv.start();
vv.setMediaController(new MediaController(this));
}
}
4 一定要在清單文件初始化InitActivity
照相機照相
直接調用系統相機照相
public class MainActivity extends Activity {
private File file;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//拍照
public void click(View v){
//1 開啟意圖
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
file = new File(Environment.getExternalStorageDirectory().getPath(),"paizhao.png");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); //把圖片保存到sd卡
startActivityForResult(intent, 2);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Toast.makeText(getApplicationContext(), file.getAbsolutePath(), 1).show();
super.onActivityResult(requestCode, resultCode, data);
}
}
錄像機錄像
直接調用系統相機錄像
public class MainActivity extends Activity {
private File file;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//拍照
public void click(View v){
//1 開啟意圖
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);
file = new File(Environment.getExternalStorageDirectory().getPath(),"luxiang.3gp");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); //把圖片保存到sd卡
startActivityForResult(intent, 2);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Toast.makeText(getApplicationContext(), file.getAbsolutePath(), 1).show();
super.onActivityResult(requestCode, resultCode, data);
}
}
Android歷史與版本變遷
0 史前階段: Android操作系統最早的一個版本是2007年11月5日發布的Android beta,作為一個面向開發者的軟件開發
Android手把手教你集成高德定位
關於定位,相信大家都不陌生。現在很多App基本都少不了定位的功能,Android本身也提供了定位的功能(LocationManager),但是由於Google牆太厚了,所
Android aidl Binder框架淺析
1、概述Binder能干什麼?Binder可以提供系統中任何程序都可以訪問的全局服務。這個功能當然是任何系統都應該提供的,下面我們簡單看一下Android的Binder的
Android SlidingMenu使用和示例詳解
很多APP都有側滑菜單的功能,部分APP左右都是側滑菜單~SlidingMenu 這個開源項目可以很好幫助我們實現側滑功能,如果對SlidingMenu 還不是很了解的童