安卓筆記(視訊播放器)
阿新 • • 發佈:2018-12-15
利用Android Studio進行簡單的視訊播放應用(是一個橫向播放的視訊播放器)
因為剛開始學,只會一些簡單的控制元件,可見上圖我只用了五個控制元件,可見是一個十分容易上手的例項。
清楚控制元件後,對於控制元件的佈局,我選擇的是FrameLayout佈局,這是我所用的佈局介面
首先是對控制元件的名稱分別新增ID,十分重要
然後對安卓上方的標題欄進行隱藏,否則影響整體的外觀樣式,
在res/values/styles檔案中新增:
<style name="AppTheme.NoActionBar"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style>
並在Androidmanifest中將theme更改為:
android:theme="@style/AppTheme.NoActionBar">
播放器的View控制元件單獨存在於FrameLayout 佈局下,而播放器的下方的功能欄則單獨存在於LinearLayout佈局中間的控制元件的padding以及background等設定需要自己調整
以上做完後,算是把框架搭好了,接下來是對控制元件的引用,以及許可權的宣告
首先講一下外部呼叫的Androidmanifest許可權宣告,只需在activity新增:
<intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="video/*"/>
並在onCreate中接受呼叫
由於程式碼功能過於繁瑣,我先將兩個主要的函式列出,其中播放器的播放拖拽控制,暫停播放的轉換,外部呼叫(你開啟一個視訊可以用該軟體),全屏顯示,控制板的隱藏,新增外部視訊的這些功能,我決定分開來寫。
先是Main函式
public class MainActivity extends AppCompatActivity { final String TAG = "測試PlayerActivity"; final int REQ_OPEN_FILE = 101; VideoView videoView;//提出播放器控制元件 SeekBar seekBar;//可拖放控制元件 View controlBar;//可播放的面板 Handler msgHandler; Timer timer; TimerTask timerTask; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);//隱藏標題 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//設定全屏 setContentView(R.layout.activity_main); //許可權申請 Permissions.check(this); //初始化介面 videoView = (VideoView)findViewById(R.id.id_videoView); seekBar = (SeekBar)findViewById(R.id.id_seekBar); seekBar.setMax(100); //訊息支援(可以寫成內部類,用內部類的話onCreate也點長) msgHandler = new MyHandler(); //播放設定(暫停,繼承) final ImageButton imageButton = (ImageButton)findViewById(R.id.id_play_pause); imageButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //此處可優化(事先將兩個圖示載入好,不再每次現載入) if (videoView.isPlaying()) { Log.d(TAG,"正在播放,現在暫停。。。"); videoView.pause(); imageButton.setImageDrawable(getDrawable(R.drawable.ic_play)); } else { Log.d(TAG,"不再播放,現在繼續。。。"); videoView.start(); imageButton.setImageDrawable(getDrawable(R.drawable.ic_pause)); } } }); //播放控制(進度拖放) seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { //控制視訊到跳轉位置 if (videoView.isPlaying()) { int progress = seekBar.getProgress(); int position = progress * videoView.getDuration()/100; videoView.seekTo(position); } } }); //控制面板得顯示和隱藏 controlBar = findViewById(R.id.id_contral_Bar); videoView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { Log.d(TAG,"點中畫畫.."); if(controlBar.getVisibility() == View.GONE) { controlBar.setVisibility(View.VISIBLE); Log.d(TAG,"顯示播放控制面板.."); } else { controlBar.setVisibility(View.GONE); Log.d(TAG,"隱藏播放控制面板.."); } return false; } }); //接受外部呼叫 Intent intent = getIntent(); Uri mediaUri = intent.getData(); if (mediaUri != null) { videoView.setVideoURI(mediaUri); videoView.start(); } } @Override protected void onStart() { if (getRequestedOrientation()!= ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } super.onStart(); if (timer == null) { //啟動定時器(間隔500ms) timerTask = new MyTimeTask(); timer = new Timer(); timer.schedule(timerTask,500,500); } } @Override protected void onStop() { super.onStop(); if (timer != null) { //本介面已經隱藏,要停止定時器(因為本介面已經隱藏,如果繼續重新整理將毫無意義,白白耗費CPU) timer.cancel(); timer = null; } super.onStop(); } //點選“按鈕” public void openFile(View view) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("video/*"); startActivityForResult(intent,REQ_OPEN_FILE); } //從媒體管理器返回 protected void onActivityResult(int requestCode,int resultCode,Intent data) { if (requestCode == REQ_OPEN_FILE) { if (resultCode == RESULT_OK) { Uri mediaUri = data.getData(); videoView.setVideoURI(mediaUri); videoView.start(); } } } //當視訊停止時, // 更新顯示進度:duration總時長,position 當前播放位置 public void showProgess(int duration,int position) { //轉化百分比 int percent = position * 100 / duration; seekBar.setProgress(percent); } ////////////////訊息支援///////////////// private class MyHandler extends Handler { @Override public void handleMessage(Message msg) { if (msg.what == 1) { //從訊息裡取出進度資料,然後更新UI int duration = msg.arg1; int position = msg.arg2; showProgess(duration,position); } super.handleMessage(msg); } } ////////////////定時器的任務//////////////////// private class MyTimeTask extends TimerTask { @Override public void run() { //如果當前VideoView並不在播放中,就不在做什麼 if (!videoView.isPlaying())return; //取得當前播放進度 int duration = videoView.getDuration();//單位 毫秒(ms) int position = videoView.getCurrentPosition();//單位 毫秒(ms) //在工作執行緒不能直接更新UI,必須發訊息給UI執行緒,然後再Handler裡處理 //發執行緒給UI執行緒 Message msg = new Message(); msg.what = 1;//訊息型別 msg.arg1 = duration;//- msg.arg2 = position; msgHandler.sendMessage(msg); } } }
然後是Permissions檔案
public class Permissions
{
// 檢查和申請許可權
static final int PERMISSION_REQ_CODE = 1;
public static void check(Activity activity)
{
// 要申請的許可權列表
final String[] permissions = {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.INTERNET,
Manifest.permission.CAMERA
};
// 檢查本應用是否有了 WRITE_EXTERNAL_STORAGE 許可權
if (ContextCompat.checkSelfPermission(activity, permissions[0])
!= PackageManager.PERMISSION_GRANTED)
{
// 系統將彈出一個對話方塊,詢問使用者是否授權
ActivityCompat.requestPermissions(activity, permissions, PERMISSION_REQ_CODE);
}
}
}
以上就是組成播放器的主要程式碼
寫的不好請指正。