android 应用开发-实现简单的音乐播放功能

  结合百度搜到的,自己再优化深入,终于实现,结合网上搜的其他大神写的地址找不到了敲打

----------一些细节没有做,主要看大功能咯----------

逻辑思路:

1.书写aidl接口

2.绑定service服务

3.activity实现业务逻辑

上干货不废话:


IServicePlayer.aidl


interface IServicePlayer {
  void play();
  void pause();
  void stop();
  int getDuration();
  int getCurrentPosition();
  void seekTo(int current);
  boolean setLoop(boolean loop);
  void reset();
  void setDataSource(String path);
  void prepare();
  void release();
  boolean isPlaying();
  void prepareAsync();
  void setPlayingFinish();

}


MusicService.java


public class MusicService extends Service {

    public static MediaPlayer mPlayer;

    IServicePlayer.Stub stub = new IServicePlayer.Stub() {

        @Override
        public void play() throws RemoteException {
            mPlayer.start();
        }

        @Override
        public void pause() throws RemoteException {
            mPlayer.pause();
        }

        @Override
        public void stop() throws RemoteException {
            mPlayer.stop();
        }

        @Override
        public int getDuration() throws RemoteException {
            return mPlayer.getDuration();
        }

        @Override
        public int getCurrentPosition() throws RemoteException {
            return mPlayer.getCurrentPosition();
        }

        @Override
        public void seekTo(int current) throws RemoteException {
            mPlayer.seekTo(current);
        }

        @Override
        public boolean setLoop(boolean loop) throws RemoteException {
            return false;
        }

        @Override
        public void reset() throws RemoteException {
            mPlayer.reset();
        }

        @Override
        public void setDataSource(String path) throws RemoteException {
            try {
                mPlayer.setDataSource(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void prepare() throws RemoteException {
            try {
                mPlayer.prepare();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void release() throws RemoteException {
            mPlayer.release();
        }

        @Override
        public boolean isPlaying() throws RemoteException {

            return mPlayer.isPlaying();
        }

        @Override
        public void prepareAsync() throws RemoteException {
            mPlayer.prepareAsync();
        }

        @Override
        public void setPlayingFinish() throws RemoteException {
            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    Log.d(Content.TAG,"play finish--------------");
                   Intent intent = new Intent();
                    intent.setAction(Content.ACTION_FINISH);
                    sendBroadcast(intent);
                }
            });
        }


    };


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return stub;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(Content.TAG, "------onCreate------");
        mPlayer = new MediaPlayer();

    }





}


   MusicActivity.java


public class MusicActivity extends Activity implements View.OnClickListener,
        SeekBar.OnSeekBarChangeListener, AdapterView.OnItemClickListener{

    private final static String TAG = "MusicActivity";
    protected static final int SEARCH_MUSIC_SUCCESS = 0;// 搜索成功标记
    private SeekBar music_progress;
    private ImageView pre;
    private ImageView play;
    private ImageView next;
    private ListView music_listview;
    private MusicListAdapter mMusicListAdapter;
    private TextView total_time, play_time, music_title;
    private int currIndex = 0;// 表示前播放的音索引
    // 义当前播放器的状态״̬
    private static final int IDLE = 0;
    private static final int PAUSE = 1;
    private static final int START = 2;
    private static final int CURR_TIME_VALUE = 1;

    private int currState = IDLE; // 前播放器的状态
    private boolean flag = true;//控制条线标记
    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/memoryCat/";
    //义线程池(同只能有一个线行)
    ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
    List<String> list = new ArrayList<>();
    IServicePlayer iPlayer;

    private MyBroadcast mMyBroadcast;

    private   Handler hander  = new Handler() {
                public void handleMessage(android.os.Message msg) {
                    switch (msg.what) {
                        case SEARCH_MUSIC_SUCCESS:
                            //搜索音文件                            mMusicListAdapter = new MusicListAdapter();
                            music_listview.setAdapter(mMusicListAdapter);

                            break;
                        case CURR_TIME_VALUE:
                            //时间
                            play_time.setText(msg.obj.toString());

                            try {
                                music_progress.setProgress(iPlayer.getCurrentPosition());
                                music_progress.setMax(iPlayer.getDuration());
                                total_time.setText(toTime(iPlayer.getDuration()));
                            } catch (RemoteException e) {
                                e.printStackTrace();
                            }
                            break;

                        default:
                            break;
                    }
                }
            };


    ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "-----onServiceConnected-----");
            iPlayer = IServicePlayer.Stub.asInterface(service);
            try {
                if (iPlayer != null &&iPlayer.isPlaying()){

                    music_progress.setMax(iPlayer.getDuration());
                    music_progress.setProgress(iPlayer.getCurrentPosition());

                    play_time.setText(toTime(iPlayer.getCurrentPosition()));
                    total_time.setText(toTime(iPlayer.getDuration()));
                    play.setImageResource(R.drawable.pause);
                    mExecutorService.execute(new Runnable() {
                        @Override
                        public void run() {
                            runSeekBar();
                        }
                    });


                }
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };



    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        Log.d(Content.TAG,"onCreate");
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setContentView(R.layout.activity_music);

        mMyBroadcast = new MyBroadcast();
        IntentFilter mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(Content.ACTION_FINISH);
        registerReceiver(mMyBroadcast,mIntentFilter);

        init();
        list.clear();

        //是否有外部存储设备
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            new Thread(new Runnable() {
                String[] ext = {".mp3"};

                File file = new File(path);

                public void run() {
                    search(file, ext);
                    hander.sendEmptyMessage(SEARCH_MUSIC_SUCCESS);
                }
            }).start();

        } else {
            Toast.makeText(this, "插入外部存储设备..", Toast.LENGTH_LONG).show();
        }
    }


    private void init() {
        music_progress = (SeekBar) findViewById(R.id.music_progress);
        play = (ImageView) findViewById(R.id.play);
        pre = (ImageView) findViewById(R.id.pre);
        next = (ImageView) findViewById(R.id.next);
        music_listview = (ListView) findViewById(R.id.music_list);
        total_time = (TextView) findViewById(R.id.total_time);
        play_time = (TextView) findViewById(R.id.play_time);
        music_title = (TextView) findViewById(R.id.music_title);
//        setPlayingFinish
        bindService(new Intent(this, MusicService.class), conn, Context.BIND_AUTO_CREATE);
        startService(new Intent(MusicActivity.this, MusicService.class));


        music_progress.setOnSeekBarChangeListener(this);
        pre.setOnClickListener(this);
        next.setOnClickListener(this);
        play.setOnClickListener(this);
        music_listview.setOnItemClickListener(this);
    }

    private String toTime(int time) {
        int minute = time / 1000 / 60;
        int s = time / 1000 % 60;
        String mm = null;
        String ss = null;
        if (minute < 10) mm = "0" + minute;
        else mm = minute + "";

        if (s < 10) ss = "0" + s;
        else ss = "" + s;

        return mm + ":" + ss;
    }




    @Override
    public void onClick(View v) {
        try {
            iPlayer.setPlayingFinish();

        } catch (RemoteException e) {
            e.printStackTrace();
        }
        switch (v.getId()) {
            case R.id.play:
                try {
                    play();

                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            case R.id.pre:
                previous();

                break;
            case R.id.next:
                next();
                break;


        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        try {
            if (fromUser) {
                iPlayer.seekTo(progress);
            }

        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        currIndex = position;
        start();
    }



    private void runSeekBar() {
        flag = true;
        while (flag) {
            try {
                if (iPlayer.getCurrentPosition() < music_progress.getMax()) {
                    music_progress.setProgress(iPlayer.getCurrentPosition());
                    Message msg = hander.obtainMessage(CURR_TIME_VALUE, toTime(iPlayer.getCurrentPosition()));
                    hander.sendMessage(msg);
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    flag = false;
                }
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }


    class MusicListAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = getLayoutInflater().inflate(R.layout.musiclist_item,
                        null);
            }
            TextView tv_music_name = (TextView) convertView.findViewById(R.id.title);

            ViewGroup item_bg = (ViewGroup) convertView.findViewById(R.id.item_bg);

            if (list.get(currIndex).replace(path, "").replace(".mp3", "") .equals(list.get(position).replace(path, "").replace(".mp3", "")))
            {
                item_bg.setBackgroundResource(R.drawable.item_bg);
            }else {
                item_bg.setBackground(null);
            }
            tv_music_name.setText(list.get(position).replace(path, "").replace(".mp3", ""));
            return convertView;
        }


    }

    private void play() throws Exception {
        switch (currState) {
            case IDLE:
                play.setImageResource(R.drawable.pause);
                start();
                break;
            case PAUSE:
                iPlayer.pause();
                play.setImageResource(R.drawable.play);
                currState = START;
                break;
            case START:
                iPlayer.play();
                play.setImageResource(R.drawable.pause);
                currState = PAUSE;
        }
    }

    //上一首
    private void previous() {
        if ((currIndex - 1) >= 0) {
            currIndex--;
            start();
            mMusicListAdapter.notifyDataSetChanged();
        } else {
            Toast.makeText(this, "前已是第一首歌曲了", Toast.LENGTH_SHORT).show();
        }
    }

    //下一首
    private void next() {
        if (currIndex + 1 < list.size()) {
            currIndex++;
            start();
            mMusicListAdapter.notifyDataSetChanged();
        } else {
            currIndex = 0;
            start();
            Toast.makeText(this, "前已是最后一首歌曲了", Toast.LENGTH_SHORT).show();
        }
    }

    //始播放
    private void start() {
        if (list.size() > 0 && currIndex < list.size()) {
            String SongPath = list.get(currIndex);
            try {
                iPlayer.reset();

                iPlayer.setDataSource(SongPath);
                iPlayer.prepare();
                iPlayer.play();
                mExecutorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        runSeekBar();
                    }
                });
                music_title.setText(list.get(currIndex).replace(path, "").replace(".mp3", ""));
                mMusicListAdapter.notifyDataSetChanged();
                 /*
                btnPlay.setImageResource(R.drawable.ic_media_pause);*/
                currState = PAUSE;
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "播放列表", Toast.LENGTH_SHORT).show();
        }
    }


    // 搜索音文件
    private void search(final File file, final String[] ext) {
        if (file != null) {
            if (file.isDirectory()) {
                File[] listFile = file.listFiles();
                if (listFile != null) {
                    for (int i = 0; i < listFile.length; i++) {
                        search(listFile[i], ext);
                    }
                }
            } else {
                String filename = file.getAbsolutePath();
                for (int i = 0; i < ext.length; i++) {
                    if (filename.endsWith(ext[i])) {
                        list.add(filename);
                        break;
                    }
                }
            }
        }
    }


    @Override
    protected void onDestroy() {
        mExecutorService.shutdownNow();
        super.onDestroy();
    }

    public class MyBroadcast extends  BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            next();
        }
    }

}


  MusicActivity加载的布局 :

    activity_music.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_music">

    <RelativeLayout
        android:id="@+id/music_title_layout"
        android:layout_width="302dp"
        android:layout_height="133dp"
        android:layout_marginLeft="12dp"
        android:layout_marginTop="15dp"
        android:background="@drawable/bg_music_title"
        android:orientation="vertical">

        <TextView
            android:id="@+id/music_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="@string/music_title"
            android:textSize="14sp"
            android:textColor="#FFF57711"
            android:layout_marginTop="60dp"/>

        <LinearLayout
            android:layout_below="@+id/music_title"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal"
        >

            <TextView
                android:id="@+id/play_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:text="00:00"
                android:textSize="14sp"
                android:layout_marginLeft="20dp"
                android:textColor="#FF00984F"/>

            <SeekBar
                android:id="@+id/music_progress"
                android:layout_marginTop="7dp"
                android:layout_width="180dp"
                android:layout_marginLeft="5dp"
                android:progressDrawable="@drawable/po_seekbar"
                android:thumb="@null"
                android:layout_height="6dp"
                android:gravity="center_vertical" />

            <TextView
                android:id="@+id/total_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:text="00:00"
                android:textSize="14sp"
                android:layout_marginLeft="5dp"
                android:textColor="#FF00984F"/>
        </LinearLayout>
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/play_control_layout"
        android:layout_width="250dp"
        android:layout_height="100dp"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="15dp"
        android:layout_marginLeft="40dp">
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

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

                <ImageView
                    android:id="@+id/pre"
                    android:layout_gravity="center"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:src="@drawable/pre"
                    android:scaleType="centerInside"
                    android:background="@drawable/button_bg"/>
                    <View
                        android:layout_width="100dp"
                        android:layout_height="70dp" />
                <ImageView
                    android:id="@+id/next"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:src="@drawable/next"
                    android:scaleType="centerInside"
                    android:background="@drawable/button_bg"/>
            </LinearLayout>
            <ImageView
                android:id="@+id/play"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:src="@drawable/play"
                android:layout_gravity="center"
                android:scaleType="centerInside"
                android:background="@drawable/button_bg"/>

        </FrameLayout>


    </RelativeLayout>

    <FrameLayout
        android:layout_alignTop="@id/music_title_layout"
        android:layout_alignParentRight="true"
        android:layout_marginRight="12dp"
        android:layout_width="196dp"
        android:layout_height="295dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="295dp"
        android:orientation="vertical"
        android:background="@drawable/bg_music_list">
        <TextView
            android:id="@+id/music_list_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:gravity="center_horizontal"
            android:text="@string/music_list_title"
            android:textSize="16sp"
            android:textColor="#FF00984F" />

        <ListView
            android:id="@+id/music_list"
            android:paddingTop="10dp"
            android:paddingBottom="30dp"
            android:paddingLeft="30dp"
            android:paddingRight="30dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></ListView>
    </LinearLayout>
        <View
            android:background="#FF00984F"
            android:layout_gravity="center_horizontal"
            android:layout_width="150dp"
            android:layout_marginTop="50dp"
            android:layout_height="1dp" ></View>
    </FrameLayout>

</RelativeLayout>


public class Content {
    public final static String TAG = "WPTAG";
    public final static String ACTION_FINISH = "com.along.memorycat.FINISH";

}


主布局文件:

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

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen">

    <activity
        android:name=".MainActivity"
        android:screenOrientation="landscape">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity
        android:name=".MusicActivity"
        android:screenOrientation="landscape" />
    <service android:name=".MusicService"  android:enabled="true"
        android:exported="true" />
</application>


   





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值