1. 程式人生 > >第一行程式碼——第八章:豐富你的程式——運用手機多媒體

第一行程式碼——第八章:豐富你的程式——運用手機多媒體

目錄:

8.1 將程式執行到手機上

8.2 使用通知

8.2.1 通知的基本用法

8.2.2 通知的進階技巧

8.2.3 通知的高階功能

8.3 呼叫攝像頭和相簿

8.3.1 呼叫攝像頭拍照

8.3.2 從相簿中選擇照片

8.4 播放多媒體檔案

8.4.1 播放音訊

8.4.2 播放視訊

8.5 小結與點評


知識點:

8.1 將程式執行到手機上

開啟手機開發者模式-USB 除錯 (有些手機還有通過USB安裝應用程式) 

在設定中找不到開發者模式的話 需要點選系統版本 開啟開發者

若仍然在AS中找不到手機,可能驅動未安裝成功

本人解決方法:使用360手機助手 搞定的。

8.2 使用通知

8.2.1 通知的基本用法

通知的用法靈活,既可以在活動裡建立,也可在廣播接收器裡建立,還可在服務裡建立。

Intent intent = new Intent(this, OtherNoticeActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//        manager.cancel(1);  退出指定通知
        //channelId  渠道id
        Notification notification = new NotificationCompat.Builder(this,"chat")
                .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))
                .setAutoCancel(true)
                .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")))
                //<uses-permission android:name="android.permission.VIBRATE" />
                .setVibrate(new long[]{0, 1000, 1000, 1000})//設定靜止震動時長  震動1秒 靜止1秒 在震動1秒
                .setLights(Color.GREEN, 1000, 1000)//燈光
//                .setDefaults(NotificationCompat.DEFAULT_ALL)//根據當前情況來決定播放什麼鈴聲,以及如何震動
                .setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(),R.mipmap.jelly_fish)))
                .setPriority(NotificationCompat.PRIORITY_HIGH)//顯示級別  橫幅
                .setContentIntent(pendingIntent)
//                .setFullScreenIntent(pendingIntent,true)//響應緊急事件 比如來電 直接跳轉
                .build();

        manager.notify(1,notification);

8.2.2 通知的進階技巧

上面提到了通知的基本用法,接下來介紹一些通知的其他技巧,比如:

在通知發出時播放一段音訊,呼叫 setSound() 方法:

Notification notification = new NotificationCompat.Builder(this)
        . . .
        .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg"))) // 在音訊目錄下選個音訊檔案
        .build();

在通知到來時讓手機振動,設定 vibrate 屬性:

Notification notification = new NotificationCompat.Builder(this)
        . . .
        .setVibrate(new long[]{0,1000,1000,1000}) // 陣列下標0表靜止的時長,下標1表振動的時長,下標2表靜止的時長,以此類推
        .build();

當然別忘了宣告振動許可權:

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

在通知到來時顯式手機 LED 燈,呼叫 setLights() 方法:

Notification notification = new NotificationCompat.Builder(this)
        . . .
        .setLights(Color.GREEN,1000,1000) // 三個引數:LED 燈的顏色、燈亮時長、燈暗時長
        .build();

當然也可直接使用預設效果,如下:

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

8.2.3 通知的高階功能

NotificationCompat.Builder 類中的 setStyle() 方法

setStyle() 方法接收一個 NotificationCompat.style 引數,這個引數用來構造具體的富文字資訊,如長文字、圖片等。

https://segmentfault.com/a/1190000008241257

8.3 呼叫攝像頭和相簿

8.3.1 呼叫攝像頭拍照

8.3.2 從相簿中選擇照片

呼叫攝像頭和相簿 是非常常用的功能,在這裡,我們不僅實現了掉用攝像頭和相簿,同時也對於Android 7.0 系統進行了適配,主要的一點就是 獲取Uri 相關連的程式碼,在返回結果的時候也是需要我們對於Uri進行解析,請看程式碼:

package com.dak.administrator.firstcode.multi_media;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.Image;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.Toast;

import com.dak.administrator.firstcode.R;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;

public class CameraAlbumActivity extends AppCompatActivity {

    private ImageView picture;
    private static final int TAKE_PHOTO = 1;
    private static final int CHOOSE_PHOTO = 2;
    private Uri imageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_album);

        picture = findViewById(R.id.picture);

        Button takePhoto = findViewById(R.id.take_photo);
        takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openCamera();
            }
        });

        Button fromAblum = findViewById(R.id.choose_from_album);
        fromAblum.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (ContextCompat.checkSelfPermission(CameraAlbumActivity.this,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(CameraAlbumActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                } else {
                    openAlbum();
                }

            }
        });
    }


    /**
     * 開啟相機
     */
    private void openCamera() {

        //建立用處儲存拍照後的圖片
        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(CameraAlbumActivity.this,
                    "com.dak.administrator.firstcode.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);
    }

    /**
     * 開啟相簿
     * gallery
     */
    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, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    openAlbum();
                } else {
                    Toast.makeText(this, "請獲取許可權", Toast.LENGTH_SHORT).show();
                }
                break;
        }

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case TAKE_PHOTO:
                if (resultCode == RESULT_OK) {
                    try {
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
//                        壓縮 迴圈 太慢
//                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
//                        int options = 100;
//                        while (baos.toByteArray().length / 1024 > 100) {//迴圈判斷如果壓縮後圖片是否大於100kb,大於繼續壓縮
//                            baos.reset();//重置baos即清空baos
//                            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
//                            options -= 10;//每次都減少10
//                        }
//                        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());//把壓縮後的資料baos存放到ByteArrayInputStream中
//                        Bitmap comBitmap = BitmapFactory.decodeStream(bais);
                        picture.setImageBitmap(bitmap);

                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case CHOOSE_PHOTO:
                if (resultCode == RESULT_OK) {
                    if (Build.VERSION.SDK_INT >= 19) {
                        //4.4及以上系統使用這個方法處理圖片
                        handleImageOnKitKat(data);
                    } else {
                        //4.4及以下系統使用這個方法處理圖片
                        handleImageBeforeKitKat(data);
                    }
                }
                break;
        }
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    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())) {
                //如果uri的authority是media格式 再次解析id 將字串分割取出後半部分才能得到真正的數字id
                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 String getImagePath(Uri externalContentUri, String selection) {
        String path = null;
        //通過Uri和selection來獲取真實圖片路徑
        Cursor cursor = getContentResolver().query(externalContentUri, 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();
        }

    }

    private void handleImageBeforeKitKat(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri, null);
        displayImage(imagePath);
    }


}

Xml頁面:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.dak.administrator.firstcode.multi_media.CameraAlbumActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Take Photo"
        android:id="@+id/take_photo"
        />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="開啟相簿"
        android:id="@+id/choose_from_album"
        />
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/picture"
        />



</LinearLayout>

在AndroidManifest.xml中配置Provider

 <!-- authorities 和FileProvider.getUriForFile第二個引數一致 -->
        <!-- name 使用自定義類 或者android.support.v4.content.FileProvider -->
        <!-- grantUriPermissions  允許你有給其賦予臨時訪問許可權的權力 -->
        <provider
            android:name=".provider"
            android:authorities="com.dak.administrator.firstcode.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">

            <!-- 指定uri共享路徑   name 固定 -->
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <paths>
        <!--指定Uri共享   name 隨便填 path標識共享的具體路徑 空值代表整個sd卡   也可以僅共享 某張圖片路徑
        path="images"
        -->

        <external-path
            name="my_images"
            path="" />

    </paths>
</resources>

當然也別忘了宣告訪問SD卡的許可權:

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

注意事項:在實際開發中最好根據專案的需求先對照片進行適當的壓縮,然後再載入到記憶體中。

8.4 播放多媒體檔案

  在安卓中播放音訊檔案一般用 MediaPlayer 類來實現,播放視訊檔案主要用 VideoView 類來實現。

MediaPlayer 常用方法:

MediaPlayer 構造方法
create 建立一個要播放的多媒體
getCurrentPosition 得到當前播放位置
getDuration 得到檔案的時間
getVideoHeight 得到視訊的高度
getVideoWidth 得到視訊的寬度
isLooping 是否迴圈播放
isPlaying 是否正在播放
pause 暫停
prepare 準備(同步)
prepareAsync 準備(非同步)
release 釋放MediaPlayer物件相關的資源
reset 重置MediaPlayer物件為剛剛建立的狀態
seekTo 指定播放的位置(以毫秒為單位的時間)
setAudioStreamType 設定流媒體的型別
setDataSource 設定多媒體資料來源(位置)
setDisplay 設定用SurfaceHolder來顯示多媒體
setLooping 設定是否迴圈播放
setOnButteringUpdateListener 網路流媒體的緩衝監聽
setOnErrorListener 設定錯誤資訊監聽
setOnVideoSizeChangedListener 視訊尺寸監聽
setScreenOnWhilePlaying 設定是否使用SurfaceHolder來保持螢幕顯示
setVolume 設定音量
start 開始播放
stop 停止播放

  VideoView和MediaPlaer也比較類似,主要有以下常用方法:

setVideoPath()

設定要播放的視訊檔案的位置。

start()

開始或繼續播放視訊。

pause()

暫停播放視訊。

resume()

將視訊重頭開始播放。

seekTo()

從指定的位置開始播放視訊。

isPlaying()

判斷當前是否正在播放視訊。

getDuration()

獲取載入的視訊檔案的時長。

8.4.1 播放音訊

package com.dak.administrator.firstcode.multi_media;

import android.Manifest;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.dak.administrator.firstcode.R;

import java.io.File;
import java.io.IOException;

public class MediaActivity extends AppCompatActivity implements View.OnClickListener {

    private MediaPlayer mediaPlayer = new MediaPlayer();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_media);

        Button play = findViewById(R.id.play);
        Button pause = findViewById(R.id.pause);
        Button stop = findViewById(R.id.stop);

        play.setOnClickListener(this);
        pause.setOnClickListener(this);
        stop.setOnClickListener(this);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }else {
            initMediaPlayer();
        }

    }

    private void initMediaPlayer() {
        try {
            File file = new File(Environment.getExternalStorageDirectory(), "music.mp3");//music.mp3不存在
            mediaPlayer.setDataSource(file.getPath());
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            initMediaPlayer();
        }else {
            Toast.makeText(this, "請獲取儲存許可權", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    @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;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }

    }
}

xml檔案:

​
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.dak.administrator.firstcode.multi_media.MediaActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/play"
        android:text="play"
        />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/pause"
        android:text="pause"
        />

    <Button
        android:id="@+id/stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="stop" />


</LinearLayout>

​

8.4.2 播放視訊

package com.dak.administrator.firstcode.multi_media;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.widget.VideoView;

import com.dak.administrator.firstcode.R;

import java.io.File;

public class VideoActivity extends AppCompatActivity implements View.OnClickListener {


    private VideoView videoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video);

        Button play = findViewById(R.id.play);
        Button pause = findViewById(R.id.pause);
        Button replay = findViewById(R.id.replay);

        videoView = findViewById(R.id.video_view);

        play.setOnClickListener(this);
        pause.setOnClickListener(this);
        replay.setOnClickListener(this);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }else {
            initVideoPath();
        }
    }

    private void initVideoPath() {
        File file = new File(Environment.getExternalStorageDirectory(), "movie.mp4");
        videoView.setVideoPath(file.getPath());

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            initVideoPath();
        }else {
            Toast.makeText(this, "請獲取儲存許可權", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    @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();//釋放資源
        }
    }
}

xml檔案:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/play"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="play" />

        <Button
            android:id="@+id/pause"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="pause" />

        <Button
            android:id="@+id/replay"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="replay" />

    </LinearLayout>

    <VideoView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/video_view"
        />
</LinearLayout>

8.5 小結與點評

郭霖總結:

本章我們主要對Android系統中的各種多媒體技術進行了學習,其中包括通知的使用校在模呼叫攝像頭拍照從相簿中選取照片, 以及播放香城和視訊檔案。由於所涉及的多媒體技術住快擬器上很難看得到效果,因此本章中還特意講解了在Android手機上除錯程式的方法。

又是充實飽滿的一章啊!現在多媒體方面的知識已經學得足夠多了,我希望你可以很好地將它們消化掉,尤其是與通知相關的內容,因為後面的學習當中還會用到它。目前我們所學的所有東西都僅僅是在本地上進行的,而實際上幾乎市場上的每個應用都會涉及網路互動的部分,所比下一章中我們將會學習一下Android網路程式設計方面的內容。

我的總結:

在呼叫攝像頭和相簿這一點,我也是學到了非常多的東西,平時因為用一些框架,很少回去研究這些東西,如今算是學到了這些我們必要的一些知識。

因為MediaPlayer 主要是在音樂相關的專案上用到,所以也多了一些印象,VideoView的話 他在視訊格式的支援以及播放效率方面都存在這較大的不足,所以建議我們只是用於播放一些遊戲的片頭動畫,或者某個應用的視訊宣傳等。。