乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Android多媒體

       杰出天下 2013-08-16

      Android多媒體

      通過調(diào)用Android的API,可以實現(xiàn)相冊,播放器,錄音和攝像等功能。這一章需要掌握如下功能:

      q      多媒體的ContentProvider的調(diào)用

      q      Camera

      q      AudioRecord和AudioTrack

      q      MediaPlayer

        11.1  獲取多媒體信息

      多媒體信息?在pc中的音樂播放器總是很容易的顯示歌手名、歌曲名、專輯名、年代。在Android中應(yīng)該如何獲取這些信息呢?

      11.1.1  查看多媒體ContentProvider

      前面我們學(xué)習(xí)了ContentProvider來保存和檢索數(shù)據(jù),Android為常用的數(shù)據(jù)類型(如:音視頻、圖片和聯(lián)系方式等)提供了大量的ContentProvider,它們被定義在android.provider包下。那么我們?nèi)绾潍@取多媒體的ContentProvider呢。

      (1)       在Eclipse中添加Android自帶的FileExplorer視圖:

      菜單欄->window->show view->other->Android->FileExplorer

      (2)       開啟模擬器,在FileExplorer中查看data/data/com.android.providers.media/databases/(如圖11.1)

      (3)       將external.db文件 pull到pc上,用sqlite工具(可以使用火狐插件SQliteManager)查看:(如圖11.2)

      (4)       查看表結(jié)構(gòu):

      audio_meta:管理sd卡中的音頻資源。(如圖11.3)

      video:管理sd卡中的視頻資源。(如圖11.4)

      images:管理sd卡中的圖片。(如圖11.5)

       

       

      圖11.1  多媒體數(shù)據(jù)庫所在包

       

      圖11.2  多媒體數(shù)據(jù)庫表

       

       

      圖11.3  音頻表結(jié)構(gòu)(audio_meta)

       

      圖11.4  視頻表結(jié)構(gòu)(video)

       

      圖11.5  圖片表結(jié)構(gòu)(images)

      可能大家看到這里會不明白為什么講多媒體先要介紹這些。筆者這里給大家列舉一個音樂播放器的需求:

      1)      獲得音樂文件列表及路徑

      2)      獲得音樂文件屬性(歌曲名、歌手名、專輯、年代。。)

      3)      手動刪除內(nèi)存卡中音樂文件,如何能同步更新文件列表

      如果是沒有Android經(jīng)驗,大家可能會這樣分析:

             文件路徑嘛,我調(diào)用file.listFile()就可以得到音樂文件列表。如果內(nèi)存卡里有很多文件,那么這個將會特別的耗時,如果讓用戶等上10秒去掃描存儲卡,用戶很有可能將你的應(yīng)用卸載掉。

             音樂文件屬性一般保存在音樂文件中,有的放在文件頭,有的放在文件尾,必須讀出該文件相關(guān)字節(jié)中的內(nèi)容才可以獲取音樂文件信息。OK,有個開源的項目,可以解析MP3文件中的文件信息。但是它同樣也是耗時的操作。而且學(xué)會調(diào)用這個開源項目還需要一周的時間。做一個項目沒那么難吧?

             在文件管理器中手動刪除或添加一個音樂文件,這個時候如何把它更新到音樂列表中呢,當(dāng)你選擇一首歌播放的時候,很有可能已經(jīng)被刪掉了。總不能讓它時刻去調(diào)用file.listFile()去維護吧?

             那么我們到底應(yīng)該怎么做呢?你要始終相信Android是強大的,它早已為我們提供了這些功能,我們只需要調(diào)用Android提供的API,就可以解決上述的需求。

             現(xiàn)在我們先看個圖,圖11.6為模擬器開機時,在log中打印的日志。

       

      圖11.6  開機時的log

      大家會看到,系統(tǒng)會調(diào)用MediaScanner去掃描Internal和External Volume。原來,在開機時,系統(tǒng)會在后臺掃描內(nèi)存和外存設(shè)備,將多媒體數(shù)據(jù)更新到數(shù)據(jù)庫中。同時也會掃描文件信息,這樣,我們不費吹灰之力就解決了問題。

      小插曲:之前由于筆者還不知道這個方法,在摸索中讓同事去研究解析MP3文件信息,花了他一個星期時間,當(dāng)他做出來了,我花了十分鐘找到了這個方法。真是罪過罪過。

      那么我們?nèi)绾蔚玫蕉嗝襟w數(shù)據(jù)呢,請看下面的例子:

      /**

            * 讀取sd卡中的音樂文件

            * @return

            * @throws Exception

            */

           public static ArrayList<Song> readDataFromSD(Context context,int component){

      //       Log.i(TAG, "scanFile");

               Cursor cursor = context.getContentResolver().query(

                         MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,

                         new String[] { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.YEAR, MediaStore.Audio.Media.MIME_TYPE, MediaStore.Audio.Media.SIZE, MediaStore.Audio.Media.DATA}

                         , MediaStore.Audio.Media.MIME_TYPE+"=? or " + MediaStore.Audio.Media.MIME_TYPE+"=?", new String[]{"audio/mpeg","audio/x-ms-wma"},null);

               ArrayList<Song> songs = null;

               if (cursor.moveToFirst()) {

                    songs = SongInfoUtil.getList(cursor, context, component);

               }

               return songs;

           }

       

       

      /**

       * @author stayzhang 封裝信息至Song

       */

      public class SongInfoUtil {

      //   private static final String TAG = "ListUtils";

           public static ArrayList<Song> getList(Cursor cursor, Context mContext, int component) {

               Song song = null;

               do {

      //            Log.i(TAG, "getList");

                    song = new Song();

                    song.setFilename(cursor.getString(1));//文件名

                    song.setTitle(cursor.getString(2));//歌曲名

                    song.setDuration(cursor.getInt(3));//時長

                    song.setSinger(cursor.getString(4));//歌手名

                    song.setAlbum(cursor.getString(5));//專輯名

                    if (cursor.getString(6) != null) {//年代

                         song.setYear(cursor.getString(6));

                    } else {

                         song.setYear("未知");

                    }

                    if ("audio/mpeg".equals(cursor.getString(7).trim())) {//歌曲格式

                         song.setType("mp3");

                    } else if ("audio/x-ms-wma".equals(cursor.getString(7).trim())) {

                         song.setType("wma");

                    }

                    if (cursor.getString(8) != null) {//文件大小

                         float temp = cursor.getInt(8) / 1024f / 1024f;

                         String sizeStr = (temp + "").substring(0, 4);

                         song.setSize(sizeStr + "M");

                    } else {

                         song.setSize("未知");

                    }

                    if (cursor.getString(9) != null) {//文件路徑

                         song.setFileUrl(cursor.getString(9));

                    }

               } while (cursor.moveToNext());

               cursor.close();

               return dbService.query(component, null, null);

           }

      }

      同理,圖片還有視頻文件也可以這樣獲得,不再贅述。

      這樣第一個和第二個需求我們已經(jīng)解決,那第三個需求呢。

      當(dāng)我們手動的刪除或添加多媒體文件到存儲卡中時,Android會自動掃描這些文件并將其更新到數(shù)據(jù)庫嗎?

      答案是不會,那么我們?nèi)绾螌?shù)據(jù)實時更新到數(shù)據(jù)庫中呢。還記得logcat中打印出來的MediaScanner嗎?我們也可以調(diào)用MediaScanner這個類去掃描存儲卡。但是不能直接調(diào)用這個類,只能以廣播的形式通知系統(tǒng),讓系統(tǒng)去掃描存儲卡指定的URI,掃描完后,再通過ContentProvider查詢數(shù)據(jù)庫。

      方法如下:

      /**

                * 調(diào)用系統(tǒng)api掃描sd卡

                */

               private void scanSdCard() {

                         IntentFilter intentFilter = new IntentFilter(

                                           Intent.ACTION_MEDIA_SCANNER_STARTED);

                         intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);

                         intentFilter.addDataScheme("file");

                         scanReceiver = new ScanSdFilesReceiver();

                         registerReceiver(scanReceiver, intentFilter);

                         sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,

                                           Uri.parse("file://" + getExternalStorageDirectory().getAbsolutePath)));

               }

       

               /**

                * @author stayzhang 注冊掃描開始/完成的廣播

                */

               private class ScanSdFilesReceiver extends BroadcastReceiver {

                         public void onReceive(Context context, Intent intent) {

                                  String action = intent.getAction();

                                  if (Intent.ACTION_MEDIA_SCANNER_STARTED.equals(action)) {

      //當(dāng)系統(tǒng)開始掃描sd卡時,為了用戶體驗,可以加上一個等待框

                                           scanHandler.sendEmptyMessage(STARTED);

                                  }

                                  if (Intent.ACTION_MEDIA_SCANNER_FINISHED.equals(action)) {

                                  //當(dāng)系統(tǒng)掃描完畢時,停止顯示等待框,并重新查詢ContentProvider

                                           scanHandler.sendEmptyMessage(FINISHED);

                                  }

                         }

               }

      OK,關(guān)于多媒體的ContentProvider的知識告一段落,下面就是如何調(diào)用Android API來使用這些多媒體文件。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多