Android手機多媒體

Android手機多媒體

一、通知的基本用法

無論是在哪裏創建通知,整體的步驟都是相同的。

首先需要一個 NotificationManager 來對通知進行管理,可以調用Context的 getSystemService() 方法獲取到。getSystemService()方法接收一個字符串參數用於確定獲取系統的哪個服務,這裏傳入Context.NOTIFICATION_SERVICE即可。

NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

接下來需要使用一個Builder構造器來創建Notification對象,幾乎Android系統的每一個版本都會對通知這部分功能進行或多或少的修改,API不穩定性問題在通知上面突顯得尤其嚴重。使用support庫中提供的兼容API能很好地解決這個問題。

Notification notification = new NotificationCompat.Builder(context).build();

上述代碼只是創建了一個空的Notification對象,並沒有什麼實際作用,我們可以在最終的build()方法之前連綴任意多的設置方法來創建一個豐富的Notification對象,

	Notification notification = new NotificationCompat.Builder(context)
				.setContentTitle("This is content title")
				.setContentText("This is content text")
				.setWhen(System.currentTimeMillis())
				.setSmallIcon(R.drawable.small_icon)
				.setLargeIcon(BitmapFactory.decodeResource(getResources(),
				R.drawable.large_icon))
				.build();

以上工作都完成之後,只需要調用NotificationManager的notify()方法就可以讓通知顯示出來了。notify()方法接收兩個參數:

  • 第一個參數是id,要保證爲每個通知所指定的id都是不同的。
  • 第二個參數則是Notification對象。
	manager.notify(1, notification);

要想實現通知的點擊效果,還需要在代碼中進行相應的設置,這就涉及了一個新的概念:PendingIntent。PendingIntent主要提供了幾個靜態方法用於獲取PendingIntent的實例,可以根據需求來選擇是使用getActivity()方法、getBroadcast()方法,還是getService()方法。這幾個方法所接收的參數都是相同的:

  • 第一個參數依舊是Context,不用多做解釋。
  • 第二個參數一般用不到,通常都是傳入0即可。
  • 第三個參數是一個Intent對象,我們可以通過這個對象構建出PendingIntent的“意圖”。
  • 第四個參數用於確定PendingIntent的行爲,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT這4種值可選,每種值的具體含義你可以查看文檔,通常情況下這個參數傳入0就可以了。

FLAG_CANCEL_CURRENT:如果NotificationManager管理的PendingIntent已經存在,那麼將會取消當前的PendingIntent,從而創建一個新的PendingIntent。
FLAG_UPDATE_CURRENT:如果NotificationManager管理的PendingIntent已經存在,可以讓新的Intent更新之前PendingIntent中的Intent對象數據,例如更新Intent中的Extras,另外,我們也可以在PendingIntent的原進程中調用PendingIntent的cancel ()把其從系統中移除掉。
FLAG_NO_CREATE:如果NotificationManager管理的PendingIntent已經存在,那麼將不進行任何操作,直接返回已經存在的PendingIntent,如果PendingIntent不存在了,那麼返回null。
FLAG_ONE_SHOT:相同的PendingIntent只能使用一次,且遇到相同的PendingIntent時不會去更新PendingIntent中封裝的Intent的extra部分的內容。

	Intent intent = new Intent(this, NotificationActivity.class);
	PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
	NotificationManager manager = (NotificationManager) getSystemService
	(NOTIFICATION_SERVICE);
	Notification notification = new NotificationCompat.Builder(this)
					.setContentTitle("This is content title")
					.setContentText("This is content text")
					.setWhen(System.currentTimeMillis())
					.setSmallIcon(R.mipmap.ic_launcher)
					.setLargeIcon(BitmapFactory.decodeResource(getResources(),
					R.mipmap.ic_launcher))
					.setContentIntent(pi)
					.build();
	manager.notify(1, notification);

如果沒有在代碼中對該通知進行取消,它就會一直顯示在系統的狀態欄上。解決的方法有兩種,一種是在NotificationCompat.Builder中再連綴一個setAutoCancel()方法,一種是顯式地調用NotificationManager的cancel()方法將它取消,兩種方法我們都學習一下。
第一種寫法:

	Notification notification = new NotificationCompat.Builder(this)
	...
	.setAutoCancel(true)
	.build();

第二種寫法:

	NotificationManager manager = (NotificationManager) getSystemService
	(NOTIFICATION_SERVICE);
	manager.cancel(1);

通知設置的id是1,如果想取消哪條通知,在cancel()方法中傳入該通知的id就行了。

NotificationCompat.Builder中的setSound()方法,它可以在通知發出的時候播放一段音頻。setSound()方法接收一個Uri參數,所以在指定音頻文件的時候還需要先獲取到音頻文件對應的URI。

	Notification notification = new NotificationCompat.Builder(this)
					...
					.setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")))
					.build();

讓手機進行振動,使用的是vibrate這個屬性。它是一個長整型的數組,用於設置手機靜止和振動的時長,以毫秒爲單位。下標爲0的值表示手機靜止的時長,下標爲1的值表示手機振動的時長,下標爲2的值又表示手機靜止的時 長,以此類推。所以,如果想要讓手機在通知到來的時候立刻振動1秒,然後靜止1秒,再振動1秒,

	Notification notification = new NotificationCompat.Builder(this)
					...
					.setVibrate(new long[] {0, 1000, 1000, 1000 })
					.build();

想要控制手機振動還需要聲明權限

	<uses-permission android:name="android.permission.VIBRATE" />

setLights()方法接收3個參數,

  • 第一個參數用於指定LED燈的顏色,
  • 第二個參數用於指定LED燈亮起的時長,以毫秒爲單位,
  • 第三個參數用於指定LED燈暗去的時長,也是以毫秒爲單位。
Notification notification = new NotificationCompat.Builder(this)
...
.setLights(Color.GREEN, 1000, 1000)
.build();

如果不想進行那麼多繁雜的設置,也可以直接使用通知的默認效果,它會根據當前手機的環境來決定播放什麼鈴
聲,以及如何振動,

	Notification notification = new NotificationCompat.Builder(this)
					...
					.setDefaults(NotificationCompat.DEFAULT_ALL)
					.build();

setStyle()這個方法允許構建出富文本的通知內容。setStyle()方法接收一個NotificationCompat.Style參數,這個參數就是用來構建具體的富文本信息的,如長文字、圖片等。

	Notification notification = new NotificationCompat.Builder(this)
					...
					.setStyle(new NotificationCompat.BigTextStyle().bigText("Learn how to build notifications, send and sync data, and use voice actions. Get the official Android IDE and developer tools to build apps for Android."))
					.build();

在setStyle()方法中創建了一個setStyle()NotificationCompat.BigTextStyle對象,這個對象就是用於封裝長文字信息的,調用它的setStyle()bigText()方法並將文字內容傳入就可以了。

除了顯示長文字之外,通知裏還可以顯示一張大圖片,具體用法也是基本相似的:

	Notification notification = new NotificationCompat.Builder(this)
					...
					.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.big_image)))
					.build();

調用的setStyle()方法,這次我們在參數中創建了一個NotificationCompat.BigPictureStyle對象,這個對象就是用於設置大圖片的,然後調用它的bigPicture()方法並將圖片傳入。通過BitmapFactory的decodeResource()方法將圖片解析成Bitmap對象,再傳入到bigPicture()方法中就可以了。

setPriority()方法,它可以用於設置通知的重要程度。setPriority()方法接收一個整型參數用於設置這條通知的重要程度,一共有5個常量值可選:

  • PRIORITY_DEFAULT:表示默認的重要程度,和不設置效果是一樣的;
  • PRIORITY_MIN:表示最低的重要程度,系統可能只會在特定的場景才顯示這條通知,比如用戶下拉狀態欄的時候;
  • PRIORITY_LOW:表示較低的重要程度,系統可能會將這類通知縮小,或改變其顯示的順序,將其排在更重要的通知之後;
  • PRIORITY_HIGH:表示較高的重要程度,系統可能會將這類通知放大,或改變其顯示的順序,將其排在比較靠前的位置;
  • PRIORITY_MAX:表示最高的重要程度,這類通知消息必須要讓用戶立刻看到,甚至需要用戶做出響應操作。
	Notification notification = new NotificationCompat.Builder(this)
					...
					.setPriority(NotificationCompat.PRIORITY_MAX)
					.build();

二、調用攝像頭和相冊

(一)調用攝像頭拍照

Button是用於打開攝像頭進行拍照的,而ImageView則是用於將拍到的圖片顯示出來。

	public class MainActivity extends AppCompatActivity {
		public static final int TAKE_PHOTO = 1;
		private ImageView picture;
		private Uri imageUri;
		@Override
		protected void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			setContentView(R.layout.activity_main);
			Button takePhoto = (Button) findViewById(R.id.take_photo);
			picture = (ImageView) findViewById(R.id.picture);
			takePhoto.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					// 創建File對象,用於存儲拍照後的圖片
					File outputImage = new File(getExternalCacheDir(),
					"output_image.jpg");
					try {
						if (outputImage.exists()) {
							outputImage.delete();
						}
						outputImage.createNewFile();
					} catch (IOException e) {
						e.printStackTrace();
					}
					if (Build.VERSION.SDK_INT >= 24) {
						imageUri = FileProvider.getUriForFile(MainActivity.this,
						"com.example.cameraalbumtest.fileprovider", outputImage);
					} else {
						imageUri = Uri.fromFile(outputImage);
					}
					// 啓動相機程序
					Intent intent = new Intent ("android.media.action.IMAGE_CAPTURE");
					intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
					startActivityForResult(intent, TAKE_PHOTO);
				}
			});
		}
		@Override
		protected void onActivityResult(int requestCode, int resultCode, Intent data) {
			switch (requestCode) {
				case TAKE_PHOTO:
					if (resultCode == RESULT_OK) {
						try {
							// 將拍攝的照片顯示出來
							Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
							picture.setImageBitmap(bitmap);
						} catch (FileNotFoundException e) {
							e.printStackTrace();
						}
					}
					break;
				default:
					break;
			}
		}
	}

通過Context.getExternalFilesDir()方法可以獲取到 SDCard/Android/data/你的應用的包名/files/ 目錄,一般放一些長時間保存的數據。
通過Context.getExternalCacheDir()方法可以獲取到 SDCard/Android/data/你的應用包名/cache/目錄,一般存放臨時緩存數據,如果使用上面的方法,當你的應用在被用戶卸載後,SDCard/Android/data/你的應用的包名/ 這個目錄下的所有文件都會被刪除,不會留下垃圾信息。
上面二個目錄分別對應 設置->應用->應用詳情裏面的”清除數據“與”清除緩存“選項,如果要保存下載的內容,就不要放在以上目錄下。

什麼叫作應用 關聯緩存目錄 呢?就是指SD卡中專門用於存放當前應用緩存數據的位置,調用getExternalCacheDir() 方法可以得到這個目錄,具體的路徑是/sdcard/Android/data//cache。那麼爲什麼要使用應用關聯緩目錄來存放圖片呢?因爲從Android 6.0系統開始,讀寫SD卡被列爲了危險權限,如果將圖片存放在SD卡的任何其他目錄,都要進行運行時權限處理纔行,而使用應用關聯目錄則可以跳過這一步。接着會進行一個判斷,如果運行設備的系統版本低於Android 7.0,就調用Uri的 fromFile() 方法將File對象轉換成Uri對象,這個Uri對象標識着output_image.jpg這張圖片的本地真實路徑。否則,就調用FileProvider的 getUriForFile() 方法將File對象轉換成一個封裝過的Uri對象。

getUriForFile()方法接收3個參數,

  • 第一個參數要求傳入Context對象,
  • 第二個參數可以是任意唯一的字符串,
  • 第三個參數則是我們剛剛創建的File對 象。

:之所以要進行這樣一層轉換,是因爲從Android 7.0系統開始,直接使用本地真實路徑的Uri被認爲是不安全的,會拋出一個FileUriExposedException異常。而FileProvider則是一種特殊的內容提供器,它使用了和內容提供器類似的機制來對數據進行保護,可以選擇性地將封裝過的Uri共享給外部,從而提高了應用的安全性

由於用到了內容提供器,那麼自然要在AndroidManifest.xml中對內容提供器進行註冊了

	<manifest xmlns:android="http://schemas.android.com/apk/res/android"
		package="com.example.cameraalbumtest">
		<application
			android:allowBackup="true"
			android:icon="@mipmap/ic_launcher"
			android:label="@string/app_name"
			android:supportsRtl="true"
			android:theme="@style/AppTheme">
			...
			<provider
				android:name="android.support.v4.content.FileProvider"
				android:authorities="com.example.cameraalbumtest.fileprovider"
				android:exported="false"
				android:grantUriPermissions="true">
				<meta-data
				android:name="android.support.FILE_PROVIDER_PATHS"
				android:resource="@xml/file_paths" />
			</provider>
		</application>
	</manifest>

android:name屬性的值是固定的。android:authorities屬性的值必須要和剛纔FileProvider.getUriForFile()方法中的第二個參數一致。這裏還在 <provider>標籤的內部使用 <metadata>來指定Uri的共享路徑,並引用了一個@xml/file_paths資源。當然,這個資源現在還是不存在的,下面我們就來創建它。

右擊res目錄→New→Directory,創建一個xml目錄,接着右擊xml目錄→New→File,創建一個file_paths.xml文件。

	<?xml version="1.0" encoding="utf-8"?>
	<paths xmlns:android="http://schemas.android.com/apk/res/android">
		<external-path name="my_images" path="" />
	</paths>

external-path 就是用來指定Uri共享的,name 屬性的值可以隨便填,path 屬性的值表示共享的具體路徑。這裏設置空值就表示將整個SD卡進行共享,當然你也可以僅共享我們存放output_image.jpg這張圖片的路徑。從4.4系統開始不再需要權限聲明。那麼我們爲了能夠兼容老版本系統的手機,還需要在AndroidManifest.xml中聲明一下訪問SD卡的權限:

	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

(二)從相冊中選擇照片

	public class MainActivity extends AppCompatActivity {
		...
		public static final int CHOOSE_PHOTO = 2;
			@Override
			protected void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			setContentView(R.layout.activity_main);
			Button takePhoto = (Button) findViewById(R.id.take_photo);
			Button chooseFromAlbum = (Button) findViewById(R.id.choose_from_album);
			...
			chooseFromAlbum.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
						ActivityCompat.requestPermissions(MainActivity.this, new
						String[]{ Manifest.permission. WRITE_EXTERNAL_STORAGE }, 1);
					} else {
						openAlbum();
					}
				}
			});
		}
		private void openAlbum() {
			Intent intent = new Intent("android.intent.action.GET_CONTENT");
			intent.setType("image/*");
			startActivityForResult(intent, CHOOSE_PHOTO); // 打開相冊
		}
		@Override
		public void onRequestPermissionsResult(int requestCode, String[] permissions,
		int[] grantResults) {
			switch (requestCode) {
				case 1:
					if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
						openAlbum();
					} else {
						Toast.makeText(this, "You denied the permission",
						Toast.LENGTH_SHORT).show();
					}
					break;
				default:
			}
		}
		@Override
		protected void onActivityResult(int requestCode, int resultCode, Intent data) {
			switch (requestCode) {
				...
				case CHOOSE_PHOTO:
					if (resultCode == RESULT_OK) {
						// 判斷手機系統版本號
						if (Build.VERSION.SDK_INT >= 19) {
							// 4.4及以上系統使用這個方法處理圖片
							handleImageOnKitKat(data);
						} else {
							// 4.4以下系統使用這個方法處理圖片
							handleImageBeforeKitKat(data);
						}
					}
					break;
				default:
					break;
			}
		}
		@TargetApi(19)
		private void handleImageOnKitKat(Intent data) {
			String imagePath = null;
			Uri uri = data.getData();
			if (DocumentsContract.isDocumentUri(this, uri)) {
				// 如果是document類型的Uri,則通過document id處理
				String docId = DocumentsContract.getDocumentId(uri);
				if("com.android.providers.media.documents".equals(uri.getAuthority())) {
					String id = docId.split(":")[1]; // 解析出數字格式的id
					String selection = MediaStore.Images.Media._ID + "=" + id;
					imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_
					CONTENT_URI, selection);
				} else if ("com.android.providers.downloads.documents".equals(uri.
				getAuthority())) {
					Uri contentUri = ContentUris.withAppendedId(Uri.parse("content:
					//downloads/public_downloads"), Long.valueOf(docId));
					imagePath = getImagePath(contentUri, null);
				}
			} else if ("content".equalsIgnoreCase(uri.getScheme())) {
				// 如果是content類型的Uri,則使用普通方式處理
				imagePath = getImagePath(uri, null);
			} else if ("file".equalsIgnoreCase(uri.getScheme())) {
				// 如果是file類型的Uri,直接獲取圖片路徑即可
				imagePath = uri.getPath();
			}
			displayImage(imagePath); // 根據圖片路徑顯示圖片
		}
			private void handleImageBeforeKitKat(Intent data) {
			Uri uri = data.getData();
			String imagePath = getImagePath(uri, null);
			displayImage(imagePath);
		}
		private String getImagePath(Uri uri, String selection) {
			String path = null;
			// 通過Uri和selection來獲取真實的圖片路徑
				Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
			if (cursor != null) {
				if (cursor.moveToFirst()) {
					path = cursor.getString(cursor.getColumnIndex(MediaStore.
					Images.Media.DATA));
				}
				cursor.close();
			}
			return path;
		}
		private void displayImage(String imagePath) {
			if (imagePath != null) {
				Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
				picture.setImageBitmap(bitmap);
			} else {
				Toast.makeText(this, "failed to get image", Toast.LENGTH_SHORT).show();
			}
		}
	}

三、播放多媒體文件

(一)播放音頻

在Android中播放音頻文件一般都是使用MediaPlayer類來實現的,下表列出了MediaPlayer類中一些較爲常用的控制方法。

方法名 功能描述
setDataSource() 設置要播放的音頻文件的位置
prepare() 在開始播放之前調用這個方法完成準備工作
start() 開始或繼續播放音頻
pause() 暫停播放音頻
reset() 將MediaPlayer對象重置到剛剛創建的狀態
seekTo() 從指定的位置開始播放音頻
stop() 停止播放音頻。調用這個方法後的MediaPlayer對象無法再播放音頻
release() 釋放掉與MediaPlayer對象相關的資源
isPlaying() 判斷當前MediaPlayer是否正在播放音頻
getDuration() 獲取載入的音頻文件的時長

MediaPlayer的工作流程:

  • 首先需要創建出一個MediaPlayer對象
  • 然後調用setDataSource()方法來設置音頻文件的路徑;
  • 調用prepare()方法使MediaPlayer進入到準備狀態;
  • 接下來調用start()方法就可以開始播放音頻;
  • 調用pause()方法就會暫停播放;
  • 調用reset()方法就會停止播放。
	public class MainActivity extends AppCompatActivity implements View.OnClickListener{
		private MediaPlayer mediaPlayer = new MediaPlayer();
		@Override
		protected void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			setContentView(R.layout.activity_main);
			Button play = (Button) findViewById(R.id.play);
			Button pause = (Button) findViewById(R.id.pause);
			Button stop = (Button) findViewById(R.id.stop);
			play.setOnClickListener(this);
			pause.setOnClickListener(this);
			stop.setOnClickListener(this);
			if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest. permission. WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
				ActivityCompat.requestPermissions(MainActivity.this, new String[]{
				Manifest.permission. WRITE_EXTERNAL_STORAGE }, 1);
			} else {
				initMediaPlayer(); // 初始化MediaPlayer
			}
		}
		private void initMediaPlayer() {
			try {
				File file = new File(Environment.getExternalStorageDirectory(),
				"music.mp3");
				mediaPlayer.setDataSource(file.getPath()); // 指定音頻文件的路徑
				mediaPlayer.prepare(); // 讓MediaPlayer進入到準備狀態
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		@Override
		public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
			switch (requestCode) {
				case 1:
					if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
						initMediaPlayer();
					} else {
						Toast.makeText(this, "拒絕權限將無法使用程序",
						Toast.LENGTH_SHORT).show();
						finish();
					}
					break;
				default:
			}
		}
		@Override
		public void onClick(View v) {
			switch (v.getId()) {
				case R.id.play:
					if (!mediaPlayer.isPlaying()) {
						mediaPlayer.start(); // 開始播放
					}
					break;
				case R.id.pause:
					if (mediaPlayer.isPlaying()) {
						mediaPlayer.pause(); // 暫停播放
					}
					break;
				case R.id.stop:
					if (mediaPlayer.isPlaying()) {
						mediaPlayer.reset(); // 停止播放
						initMediaPlayer();
					}
					break;
				default:
					break;
			}
		}
		@Override
		protected void onDestroy() {
			super.onDestroy();
			if (mediaPlayer != null) {
				mediaPlayer.stop();
				mediaPlayer.release();
			}
		}
	}

不要忘記在AndroidManifest.xml文件中聲明用到的權限

	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />	

(二)播放視頻

VideoView的用法和MediaPlayer也比較類似。

方法 功能描述
setVideoPath() 設置要播放的視頻文件的位置
start() 開始或繼續播放視頻
pause() 暫停播放視頻
resume() 將視頻重頭開始播放
seekTo() 從指定的位置開始播放視頻
isPlaying() 判斷當前是否正在播放視頻
getDuration() 獲取載入的視頻文件的時長
	public class MainActivity extends AppCompatActivity implements View.OnClickListener{
		private VideoView videoView;
		@Override
		protected void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			setContentView(R.layout.activity_main);
			videoView = (VideoView) findViewById(R.id.video_view);
			Button play = (Button) findViewById(R.id.play);
			Button pause = (Button) findViewById(R.id.pause);
			Button replay = (Button) findViewById(R.id.replay);
			play.setOnClickListener(this);
			pause.setOnClickListener(this);
			replay.setOnClickListener(this);
			if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
				ActivityCompat.requestPermissions(MainActivity.this, new String[]{
				Manifest.permission. WRITE_EXTERNAL_STORAGE }, 1);
			} else {
				initVideoPath(); // 初始化VideoView
			}
		}
		private void initVideoPath() {
			File file = new File(Environment.getExternalStorageDirectory(), "movie.mp4");
			videoView.setVideoPath(file.getPath()); // 指定視頻文件的路徑
		}
		@Override
		public void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults) {
			switch (requestCode) {
				case 1:
					if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
						initVideoPath();
					} else {
						Toast.makeText(this, "拒絕權限將無法使用程序", Toast.LENGTH_SHORT).
						show();
						finish();
					}
					break;
				default:
			}
		}
		@Override
		public void onClick(View v) {
			switch (v.getId()) {
				case R.id.play:
					if (!videoView.isPlaying()) {
					videoView.start(); // 開始播放
					}
					break;
				case R.id.pause:
					if (videoView.isPlaying()) {
					videoView.pause(); // 暫停播放
					}
					break;
				case R.id.replay:
					if (videoView.isPlaying()) {
					videoView.resume(); // 重新播放
					}
					break;
			}
		}
		@Override
		protected void onDestroy() {
			super.onDestroy();
			if (videoView != null) {
				videoView.suspend();
			}
		}
	}

要記得在AndroidManifest.xml文件中聲明用到的權限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


個人網站:分享客https://sharerdiary.com/
這個網站經常分享一些免費視頻、免費音樂、實用工具和各種福利,感興趣的朋友可以看看!

您的關注和點贊是我分享的動力,如有幫助請勿吝嗇!ヽ( ̄▽ ̄)ノ



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章