zoukankan      html  css  js  c++  java
  • 8.Media and Camera/Media Playback

    1.Media Palyback

      The Android multimedia framework includes support for playing variety of common media types, so that you can easily integrate audio, video

        and images into your applications.

      You can play audio or video from media files stored in your application's resources (raw resources), from standalone files in the filesystem,

        or from a data stream arriving over a network connection, all using MediaPlayer APIs.

    2. The Basic

      MediaPlayer ---> Primary API for Playing sound and video

      AudioManager ---> managers audio sources and audio output on a device

    3. Manifest Declarations

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

      <uses-permission android:name="android.permission.WAKE_LOCK" /> : keep the screen from dimming or the processor from sleeping

    4. Using MediaPalyer

      An object of this class can fetch, decode, and play both audio and video with minimal setup. It supports several different media sources

        such as:

        <1>Local resources

          Here is an simple example of how to play audio

          <i> place a local resources saved in res/raw/ directory

          <ii>

    MediaPlayer mediaPlayer = MediaPlayer.create(getApplication(),R.raw.beatiful_girl);
            mediaPlayer.start();

        <2>Internal URIs, such as one you might obtain from a Content Resolver

    Uri myUri = ....; // initialize Uri here, obtained through Content Resolver
    MediaPlayer mediaPlayer = new MediaPlayer();
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mediaPlayer.setDataSource(getApplicationContext(), myUri);
    mediaPlayer.prepare();
    mediaPlayer.start();

        <3>External URLs(streaming)

    String url = "http://........"; // your URL here
    MediaPlayer mediaPlayer = new MediaPlayer();
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mediaPlayer.setDataSource(url);
    mediaPlayer.prepare(); // might take long! (for buffering, etc)
    mediaPlayer.start();

      4.1 Asynchronous Preparation

        important to keep in mind:

        <1> the call to prepare() can take a long time to excute, because it might involve fetching and decoding media data.

             So, never call it from application`s UI thread. 

        <2> framework supplies a convinient way to accomplish this task by using prepareAsync() method

           When the media is done preparing, the onPrepared() method of the MediaPlayer.OnPreparedListener, configured through

            setOnPreparedListener() is called.

      4.2 Managing State

        

      4.3 Releasing the MediaPlayer

        A MediaPlayer can consume valuable system resources. Therefore, you should call release() to make sure any  system resources

          allocated toit are properly released 

    mediaPlayer.release();
    mediaPlayer = null;

        As an example, consider the problems that could happen if you forgot to release the MediaPlayer when your activity is stopped, but

          create a new one when the activity starts again. As you may know, when the user changes the screen orientation (or changes the

          device configuration in another way), the system handles that by restarting the activity (by default), so you might quickly consume

          all of the system resources as the user rotates the device back and forth between portrait and landscape, because at each

          orientation change, you create a new MediaPlayer that you never release.

    5. Using a Service with MediaPlayer

      If you want your media to play in the background even when your application is not onscreen—that is, you want it to continue playing

        while the user is interacting with other applications—then you must start a Service and control the MediaPlayer instance from there.

      5.1 Running asynchronousyly

        First of all, like an Activity, all work in a Service is done in a single thread by default. 

        if you are running an activity and a service from the same application("main thread") by default,

        Therefore, services needs to process incoming intents quickly and never perform lengthly computatipons when responding to them.

        If any heavy work or blocking calls are expected, you must do those tasks asynchronously:

          either from another thread you implement yourself, or using the framework's many facilities for asynchronous processing.

    public class MediaPalyBack extends Activity {
    
        private Button button_Play;
        private Button button_Stop;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_media_paly_back);
            
            button_Play = (Button)findViewById(R.id.btn_play);
            button_Stop = (Button)findViewById(R.id.btn_stop);
            
            button_Play.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(MediaPalyBack.this, MyService.class);
                    startService(intent);
                }
            });
        }
    }
    public class MyService extends Service implements OnPreparedListener{
        
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            
            MediaPlayer mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            try {
                Uri uri = Uri.parse("android.resource://" + getPackageName()+ "/" + R.raw.secret); //get res/raw/ resources
                mMediaPlayer.setDataSource(getApplication(), uri);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.prepareAsync();
            return startId;
        }
    
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    }
     <service android:name=".MyService"></service>

      5.2 Handling asynchronous errors

        On synchronous operations, errors would normally be signaled with an exception or an error code,

          but whenever you use asynchronous resources, you should make sure your application is notified of errors appropriately.

    public class MyService extends Service implements MediaPlayer.OnErrorListener {
        MediaPlayer mMediaPlayer;
    
        public void initMediaPlayer() {
            // ...initialize the MediaPlayer here...
    
            mMediaPlayer.setOnErrorListener(this);
        }
    
        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            // ... react appropriately ...
            // The MediaPlayer has moved to the Error state, must be reset!
        }
    }

      5.3 using wake locks

        A wake lock is a way to singal to the system that your application is using some feature that should stay avialable even if the phone

          is idle

    mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);

        If you are streaming media over the network and you are using Wi-Fi, you probably want to hold a WifiLocks as well

    WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
        .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
    wifiLock.acquire();

        When you pause or stop your media, or when you no longer need the network, you should release the lock:

    wifiLock.release();

      5.4 Running as a "foreground service"

        When running in the foreground, the service also must provide a status bar notification to ensure that users are aware of the running

          service and allow them to open an activity that can interact with the service.

    Builder mBuilder = new Notification.Builder(this)
                                                        .setContentTitle("Mirro music")
                                                        .setContentText("Palying:" + "secret.mp3")
                                                        .setTicker("music")
                                                        .setSmallIcon(R.drawable.apple)
                                                        .setOngoing(true);
            //mBuilder.bulid() returns notification
            NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
            mNotificationManager.notify(0,mBuilder.build());

      5.5 Handling audio focus

        when a user is listening to music and another application needs to notify the user of something very important, the user might not hear

          the notification tone due to the loud music.

        Starting with Android 2.2, the platform offers a way for applications to negotiate their use of the device's audio output. This mechanism

          is called Audio Focus.

        When your application needs to output audio such as music or a notification, you should always request audio focus. Once it has focus,

          it can use the sound output freely, but it should always listen for focus changes. If it is notified that it has lost the audio focus, it

          should immediately either kill the audio or lower it to a quiet level (known as "ducking"—there is a flag that indicates which one is

          appropriate) and only resume loud playback after it receives focus again.

    6. Handling the AUDIO_BECOMING_NOISY intent

      Many well-written applications that play audio automatically stop playback when an event occurs that causes the audio to become noisy

        (ouput through external speakers). For instance, this might happen when a user is listening to music through headphones and

        accidentally disconnects the headphones(头戴式耳机) from the device. However, this behavior does not happen automatically. If you

        don't implement this feature, audio plays out of the device's external speakers(外放耳机), which might not be what the user wants.

      You can ensure your app stops playing music in these situations by handling the ACTION_AUDIO_BECOMINGS_NOISY intent, for which you

        can register a receiver by adding the following to your manifest:

    <receiver android:name=".MusicIntentReceiver">
       <intent-filter>
          <action android:name="android.media.AUDIO_BECOMING_NOISY" />
       </intent-filter>
    </receiver>

      This registers the MusicIntentReceiver class as a broadcast receiver for that intent. You should then implement this class:

    public class MusicIntentReceiver extends android.content.BroadcastReceiver {
       @Override
       public void onReceive(Context ctx, Intent intent) {
          if (intent.getAction().equals(
                        android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
              // signal your service to stop playback
              // (via an Intent, for instance)
          }
       }
    }

    7. Retrieving Media from a Content Resolver

      add a button to show the media in the EXTERNAL_CONTENT

    button_Show.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    ContentResolver contentReslover = getContentResolver();
                    Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    Cursor cursor = contentReslover.query(uri, null, null, null, null);
                    if(cursor == null)
                        Log.d("Mirror","no cursor");
                    else{
                //Informations for a song
    int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE); int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID); int albumColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.ALBUM); int artistColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.ARTIST); int durationColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.DURATION); int sizeColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.SIZE); while(cursor.moveToNext()){ long thisId = cursor.getLong(idColumn); String thisTitle = cursor.getString(titleColumn); Log.d("Mirror","Id--->" + thisId + ", Title--->" + thisTitle); }; } } });

      This infromation for a song can be added in detail in a listView

      

      to play a certain song,

    //id=3417 refers to SunBoy.mp3 in according to the catlog output above 
    Uri contentUri = ContentUris.withAppendedId( android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 3417); mMediaPlayer = new MediaPlayer(); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.setDataSource(getApplicationContext(), contentUri);
  • 相关阅读:
    [转]SQL Server 索引结构及其使用一
    平台无关的RICHTEXT实现
    谈谈时间管理陶哲轩
    BigNumCalculator
    关于构造和析构的几点拟人化思考
    ScaleForm十六戒言
    VAX对多种格式增加支持
    关于知识,经验,能力
    AutoTidyMyFiles
    王石语摘
  • 原文地址:https://www.cnblogs.com/iMirror/p/4082447.html
Copyright © 2011-2022 走看看