Android MediaPlayer无法播放包含'#'使用Uri.parse(路径)的文件名中的字符

时间:2014-05-24 20:34:38

标签: java android uri

据我所知,我的代码中的Uri.parse导致我的MediaPlayer在文件名中包含特殊字符的音频文件上失败,如“#”和其他。我无法弄清楚如何解决这个问题。我希望能够在我的文件名中使用特殊字符。以下是我认为导致此问题的代码:

public void playAudio(int media) {
        try {
            switch (media) {
                case LOCAL_AUDIO:
                    /**
                     * TODO: Set the path variable to a local audio file path.
                     */
                   if (path == "") {
                        // Tell the user to provide an audio file URL.
                        Toast
                                .makeText(
                                        MediaPlayerDemo_Audio.mp,
                                        "Please edit MediaPlayer_Audio Activity, "
                                                + "and set the path variable to your audio file path."
                                                + " Your audio file must be stored on sdcard.",
                                        Toast.LENGTH_LONG).show();

                    }
                    mMediaPlayer = new MediaPlayer();
                    mMediaPlayer.setLooping(sound_loop);
                    mMediaPlayer.setDataSource(MediaPlayerDemo_Audio.mp, Uri.parse(path));
                    mMediaPlayer.prepare();
                    resetTimer();
                    startTimer();
                    mMediaPlayer.start();

                    Intent intent = new Intent(MediaPlayerDemo_Audio.PLAY_START);
                    sendBroadcast(intent);  


                    break;
                case RESOURCES_AUDIO:
                    /**
                     * TODO: Upload a audio file to res/raw folder and provide
                     * its resid in MediaPlayer.create() method.
                     */
                   // mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);
                    //mMediaPlayer.start();

            }
            //tx.setText(path);

        } catch (Exception e) {
            //Log.e(TAG, "error: " + e.getMessage(), e);
        }

    }

我正在使用MediaPlayerDemo_Audio.java播放声音。从上面的代码可以看出,mMediaPlayer.setDataSource(MediaPlayerDemo_Audio.mp,Uri.parse(path));我想是调用代码来检索文件和媒体播放器。我还没熟悉android代码。以下是MediaPlayerDemo_Audio.java的代码:

public class MediaPlayerDemo_Audio extends Activity {

public static String path;
private String fname;

private static Intent PlayerIntent;
public static String STOPED = "stoped";
public static String PLAY_START = "play_start";
public static String PAUSED = "paused";
public static String UPDATE_SEEKBAR = "update_seekbar";

public static boolean is_loop = false;
private static final int LOCAL_AUDIO=0;


private Button play_pause, stop;
private SeekBar seek_bar;

public static MediaPlayerDemo_Audio mp;
private AudioPlayerService mPlayerService;



@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.media_player_layout);
    //getWindow().setTitle("SoundPlayer");
    //getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, 
        //  android.R.drawable.ic_media_play);

    play_pause = (Button)findViewById(R.id.play_pause);
    play_pause.setOnClickListener(play_pause_clk);
    stop = (Button)findViewById(R.id.stop);
    stop.setOnClickListener(stop_clk);
    seek_bar = (SeekBar)findViewById(R.id.seekBar1);
    seek_bar.setMax(100);
    seek_bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        public void onStopTrackingTouch(SeekBar seekBar) {              
            if (mPlayerService!=null) {
                int seek_pos = (int) ((double)mPlayerService.getduration()*seekBar.getProgress()/100);
                mPlayerService.seek(seek_pos);                
            }
        }
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {


        }
    });

    play_pause.setText("Pause");
    stop.setText("Stop");        

    //int idx = path.lastIndexOf("/");
    //fname = path.substring(idx+1);
    //tx.setText(path);


    IntentFilter filter = new IntentFilter();
    filter.addAction(STOPED);
    filter.addAction(PAUSED);
    filter.addAction(PLAY_START);
    filter.addAction(UPDATE_SEEKBAR);

    registerReceiver(mPlayerReceiver, filter);

    PlayerIntent = new Intent(MediaPlayerDemo_Audio.this, AudioPlayerService.class);
    if (AudioPlayerService.path=="") AudioPlayerService.path=path;
    AudioPlayerService.sound_loop = is_loop;
    startService(PlayerIntent);
    bindService(PlayerIntent, mConnection, 0);  
    if (mPlayerService!=null && mPlayerService.is_pause==true) play_pause.setText("Play");
    mp = MediaPlayerDemo_Audio.this;

}

private BroadcastReceiver mPlayerReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String act = intent.getAction();
        if (act.equalsIgnoreCase(UPDATE_SEEKBAR)){
            int val = intent.getIntExtra("seek_pos", 0);
            seek_bar.setProgress(val);
            TextView counter = (TextView) findViewById(R.id.time_view);
            counter.setText(DateUtils.formatElapsedTime((long) (intent.getLongExtra("time", 0)/16.666)));
            //tx.setText(fname);
        }
        else if (act.equalsIgnoreCase(STOPED)) {
            play_pause.setText("Play");             
            seek_bar.setProgress(0);
            stopService(PlayerIntent);
            unbindService(mConnection);
            mPlayerService = null;
            TextView counter = (TextView) findViewById(R.id.time_view);
            counter.setText(DateUtils.formatElapsedTime(0));
        }
        else if (act.equalsIgnoreCase(PLAY_START)){
            play_pause.setText("Pause");
        }
        else if (act.equalsIgnoreCase(PAUSED)){
            play_pause.setText("Play");
        }

    }
};
private ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName arg0, IBinder arg1) {
        mPlayerService = ((AudioPlayerService.LocalBinder)arg1).getService();
        if (mPlayerService.is_pause==true) {
            play_pause.setText("Play");
            seek_bar.setProgress(mPlayerService.seek_pos);
        }
        if (mPlayerService.mTime!=0) {
            TextView counter = (TextView) findViewById(R.id.time_view);
            counter.setText(DateUtils.formatElapsedTime((long) (mPlayerService.mTime/16.666)));
        }
        if (path.equalsIgnoreCase(AudioPlayerService.path)==false){
            AudioPlayerService.path = path;
            mPlayerService.restart();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        // TODO Auto-generated method stub
        mPlayerService = null;
    }
};
private OnClickListener play_pause_clk = new OnClickListener() {

    @Override
    public void onClick(View arg0) {
        if (mPlayerService!=null)
            mPlayerService.play_pause();
        else{
            AudioPlayerService.path=path;
            startService(PlayerIntent);
            bindService(PlayerIntent, mConnection, 0);
        }
    }

};
private OnClickListener stop_clk = new OnClickListener() {

    @Override
    public void onClick(View arg0) {
        if (mPlayerService==null) return;
        mPlayerService.Stop();          
    }

};

@Override
protected void onDestroy() {
    super.onDestroy();
    // TODO Auto-generated method stub


}

}

如何解决此问题,以便可以使用特殊字符解析文件并在MediaPlayer中正确播放?我错过了什么吗?

也许有助于显示我的AudioPlayerService的整个代码:

public class AudioPlayerService extends Service {
public MediaPlayer mMediaPlayer;
protected long mStart;
public long mTime;
public int seek_pos=0;
public static boolean sound_loop = false;
public boolean is_play, is_pause;
public static String path="";
private static final int LOCAL_AUDIO=0;
private static final int RESOURCES_AUDIO=1;    

private int not_icon;
private Notification notification;
private NotificationManager nm;
private PendingIntent pendingIntent;
private Intent intent;

@SuppressWarnings("deprecation")
@Override
public void onCreate() {
    playAudio(LOCAL_AUDIO);
    mTime=0;

    is_play = true;
    is_pause = false;

    CharSequence ticker = "Touch to return to app";
    long now = System.currentTimeMillis();
    not_icon = R.drawable.play_notification;
    notification = new Notification(not_icon, ticker, now);

    nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

    Context context = getApplicationContext();   
    intent = new Intent(this, MediaPlayerDemo_Audio.class);
    pendingIntent = PendingIntent.getActivity(context, 0,intent, 0);


    PhoneStateListener phoneStateListener = new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            if (state == TelephonyManager.CALL_STATE_RINGING) {
                //INCOMING call
                //do all necessary action to pause the audio
               if (is_play==true && is_pause==false){
                   play_pause();
               }

            } else if(state == TelephonyManager.CALL_STATE_IDLE) {
                //Not IN CALL
                //do anything if the phone-state is idle
            } else if(state == TelephonyManager.CALL_STATE_OFFHOOK) {
                //A call is dialing, active or on hold
                //do all necessary action to pause the audio
                //do something here
                 if (is_play==true && is_pause==false){
                    play_pause();
                 }
            }
            super.onCallStateChanged(state, incomingNumber);
        }
    };//end PhoneStateListener

    TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    if(mgr != null) {
        mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    OnAudioFocusChangeListener myaudiochangelistener = new OnAudioFocusChangeListener(){

        @Override
        public void onAudioFocusChange(int arg0) {
            //if (arg0 ==AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK){
                 if (is_play==true && is_pause==false){
                    play_pause();
                 }
            //}

        }

    };

    AudioManager amr = (AudioManager)getSystemService(AUDIO_SERVICE);
    amr.requestAudioFocus(myaudiochangelistener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
}
@SuppressWarnings("deprecation")
@Override
 public int onStartCommand(Intent intent, int flags, int startId) {
    Context context = getApplicationContext();   
    String title = "VoiceRecorder App";
    CharSequence message = "Playing..";
    notification.setLatestEventInfo(context, title, message,pendingIntent);
    nm.notify(101, notification);
     return START_STICKY;
 }
public class LocalBinder extends Binder {
    AudioPlayerService getService() {
        return AudioPlayerService.this;
    }
}
public void restart(){
    mMediaPlayer.stop();
    playAudio(LOCAL_AUDIO);
    mTime=0;

    is_play = true;
    is_pause = false;
}
@Override
public IBinder onBind(Intent arg0) {

    return mBinder;
}
 private final IBinder mBinder = new LocalBinder();

 public void Stop()
 {          
    mMediaPlayer.stop();
    Intent intent1 = new Intent(MediaPlayerDemo_Audio.STOPED);
    sendBroadcast(intent1); 

    resetTimer();

    is_play=false;
    is_pause=false;
 }
 public void play_pause()
 {
     if (is_play==false){
        try {
             mMediaPlayer.start();         
             startTimer();       

             is_play=true;
             is_pause = false;
        } catch (Exception e) {
            //Log.e(TAG, "error: " + e.getMessage(), e);
        }

        Intent intent = new Intent(MediaPlayerDemo_Audio.PLAY_START);
        sendBroadcast(intent);  
    }
    else{
        mMediaPlayer.pause();
        stopTimer();
        Intent intent1 = new Intent(MediaPlayerDemo_Audio.PAUSED);
        sendBroadcast(intent1); 

        is_play = false;
        is_pause = true;
    }

 }
 public int getduration()
 {
     return mMediaPlayer.getDuration(); 
 }

 public void seek(int seek_pos)
 {
     mMediaPlayer.seekTo(seek_pos);
     mTime = seek_pos;
 }
  public void playAudio(int media) {
        try {
            switch (media) {
                case LOCAL_AUDIO:
                    /**
                     * TODO: Set the path variable to a local audio file path.
                     */
                   if (path == "") {
                        // Tell the user to provide an audio file URL.
                        Toast
                                .makeText(
                                        MediaPlayerDemo_Audio.mp,
                                        "Please edit MediaPlayer_Audio Activity, "
                                                + "and set the path variable to your audio file path."
                                                + " Your audio file must be stored on sdcard.",
                                        Toast.LENGTH_LONG).show();

                    }
                    mMediaPlayer = new MediaPlayer();
                    mMediaPlayer.setLooping(sound_loop);
                    mMediaPlayer.setDataSource(MediaPlayerDemo_Audio.mp, Uri.parse(path));
                    mMediaPlayer.prepare();
                    resetTimer();
                    startTimer();
                    mMediaPlayer.start();

                    Intent intent = new Intent(MediaPlayerDemo_Audio.PLAY_START);
                    sendBroadcast(intent);  


                    break;
                case RESOURCES_AUDIO:
                    /**
                     * TODO: Upload a audio file to res/raw folder and provide
                     * its resid in MediaPlayer.create() method.
                     */
                   // mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);
                    //mMediaPlayer.start();

            }
            //tx.setText(path);

        } catch (Exception e) {
            //Log.e(TAG, "error: " + e.getMessage(), e);
        }

    }

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            long curTime = System.currentTimeMillis();
            mTime += curTime-mStart;
            mStart = curTime;

            int pos = (int) ((double)mMediaPlayer.getCurrentPosition()*100/mMediaPlayer.getDuration());
            seek_pos = pos;
            Intent intent1 = new Intent(MediaPlayerDemo_Audio.UPDATE_SEEKBAR);
            if (mMediaPlayer.isLooping()) intent1.putExtra("time", (long)mMediaPlayer.getCurrentPosition());
            else intent1.putExtra("time", mTime);
            intent1.putExtra("seek_pos", pos);      
            sendBroadcast(intent1);

            if (mMediaPlayer.isPlaying()==false && mMediaPlayer.isLooping()==false){                
                mMediaPlayer.stop();
                resetTimer();
                Intent intent2 = new Intent(MediaPlayerDemo_Audio.STOPED);
                sendBroadcast(intent2);
                is_play=false;
            }           
            if (mTime > 0) mHandler.sendEmptyMessageDelayed(0, 10);
        };
    };
    private void startTimer() {
        mStart = System.currentTimeMillis();
        mHandler.removeMessages(0);
        mHandler.sendEmptyMessage(0);

    }

    private void stopTimer() {
        mHandler.removeMessages(0);

    }

    private void resetTimer() {
        stopTimer();
        mTime = 0;
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        // TODO Auto-generated method stub
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        nm.cancel(101);
    }

}

1 个答案:

答案 0 :(得分:5)

对于本地文件,请勿使用Uri.parse()。使用Uri.fromFile(),传入指向相关文件的File对象。这应该适当地转义#等特殊字符。