Use Android Studio to develop a simple music player

Interface display system operation:
Login screen: Playlist: player interface:
first step is to put the songs lead into the simulator, when introduced into the simulator first obtain permission:

  • First, to obtain virtual equipment Root privileges.
  • Command-line tool, to switch to the "sdk directory" / platform-tools / (or the above-mentioned directories to the environment variable Path).
  • Run adb root
    Here Insert Picture Description
  • Then, open the ADB integration
  • Tools->Android->勾选Enable ADB Integration
    Here Insert Picture Description
  • Push the audio files to your phone:
  • Tools—Android—Android Device Monitor

Here Insert Picture Description
1 System Requirements Analysis
1.1 login module
to enter a user name and password (Initial username is admin, password is 123456), to achieve the user's entry and exit functions.
1.2 music list
shows all the artist name and song name, click a song to jump to playing interface, long press function achieve delete the song.
1.3 player interface
displays information about the song being played, such as song title, artist name corresponding to the current playing time, song total time, and can drag the progress bar to achieve fast forward, rewind and playback functions as well as single cycle circulation .

2 system design
overall configuration of the system 2.1

Here Insert Picture Description

2.2 Design of data storage
MediaStore class is a multimedia database system provides android, android multimedia information can be extracted from here. MediaStore multimedia database including all the information, including audio, video and images, android all the multimedia database interface package, all databases do not have to be created, direct calls to call ContentResolver use those interfaces can be encapsulated database of the operation. For example, the experimental use of ContentProvider (content providers) to call Android audio system comes with SQLite database, the path address MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, the results returned by the cursor result set of interfaces, this process is simple and convenient for this the design of the use.

3 detailed design
3.1 Log function
the user to enter account number and password to log in to achieve, and achieve access privileges on the system functions in this interface.
The key code is as follows:

public class LoginActivity extends AppCompatActivity {
    ...
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        if (ContextCompat.checkSelfPermission(LoginActivity.this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(LoginActivity.this,
                    new String[]{
                            Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
       ...
   login = (Button) findViewById(R.id.login);
       login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ...
                if (account.equals("admin") && password.equals("123456")) {
                    Intent intent = new Intent(LoginActivity.this, MusicListActivity.class);
                    startActivity(intent);
                } else {
                    Toast.makeText(LoginActivity.this, "用户名或密码错误,请重新输入!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                           int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] != PackageManager.
                        PERMISSION_GRANTED) {
                    Toast.makeText(this, "拒绝权限将无法使用程序",
                            Toast.LENGTH_SHORT).show();
                    finish();
                }
                break;
            default:
                break;
        }
    }

}

3.2 Music List function
the user can view the music list, select or remove a piece of music to play, click Play realize jump, long press to select whether to implement the delete function.
The key code is as follows:

//查询媒体数据库
    Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,
            null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
    //遍历数据库
    if (cursor.moveToFirst()) {
        while (!cursor.isAfterLast()) {
            //路径
            String uri = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
           ...     
File file = new File(uri);
            if (isMusic != 0 && file.exists()) {
                Music music = new Music(uri, musicName, artistName);
                musicList.add(music);
            }
        }
    }
   ...
    //短按实现跳转播放
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {
            Intent intent = new Intent(MusicListActivity.this, MusicPlayActivity.class);
            intent.putExtra("position", position);
            startActivity(intent);
        }
    });
    //长按选择是否删除歌曲
    listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view,
                                       final int position, long id) {
            final Music music = musicList.get(position);
            AlertDialog.Builder dialog = new AlertDialog.Builder(MusicListActivity.this);
            dialog.setTitle("提示:");
            dialog.setMessage("是否删除这首歌曲?");
            dialog.setCancelable(false);
            dialog.setPositiveButton("删除", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    //删除音乐文件
                    File file = new File(music.getUri());
                    file.delete();
                    //删除媒体数据库记录
                    getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                            MediaStore.Audio.Media.DATA + " LIKE ?", new String[]{music.getUri()});
                    musicList.remove(position);
                    adapter.notifyDataSetChanged();
                }
            });
            dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                }
            });
            dialog.show();
            return true;
        }
    });
}

3.3 player interface functions
a user may select different playback modes, such as single cycle or sequential play, and optionally one or played on the next piece of music, and music playback progress adjustment feature enables drag progress bar.
The key code is as follows:

public Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UPDATE_TEXT:
                    musicName.setText(songName);
                    artist.setText(artistName);
                    musicTime.setText(time.format(mediaPlayer.getCurrentPosition()));
                    musicTotal.setText(time.format(mediaPlayer.getDuration()));
                    seekBar.setMax(mediaPlayer.getDuration());
                    seekBar.setProgress(mediaPlayer.getCurrentPosition());
                    break;
                default:
                    break;
            }
        }
    };

      protected void onCreate(Bundle savedInstanceState) {
        ...
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            // 拖动条停止拖动的时候调用
            public void onStopTrackingTouch(SeekBar seekBar) {
                int progress = seekBar.getProgress();
                mediaPlayer.seekTo(progress);
            }
            ...
           );

        new Thread(new Runnable() {
            @Override
            public void run() {
                if (flag) {
                    Message message = new Message();
                    message.what = UPDATE_TEXT;
                    handler.sendMessage(message);
                    handler.postDelayed(this, 1000);
                }
            }
        }).start();
      }

    private void initMediaPlayer() {
        try {
            Music music = musicList.get(position);//得到当前播放音乐的路径
            artistName = music.getArtistName();//获得歌手名
            songName = music.getMusicName();//获得歌名
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);// 指定参数为音频文件
            mediaPlayer.setDataSource(music.getUri());//为多媒体对象设置播放路径
            mediaPlayer.prepare();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.prev://上一首
                position = position == 0 ? musicList.size() - 1 : position - 1;
                mediaPlayer.reset();
                initMediaPlayer();
                play.setText("■");
                musicName.setText(songName);
                artist.setText(artistName);
                mediaPlayer.start();
                break;
            case R.id.play://开始
                if (!mediaPlayer.isPlaying()) {
                    play.setText("■");
                    musicName.setText(songName);
                    artist.setText(artistName);
                    mediaPlayer.start();
                } else {//暂停
                    play.setText("▶");
                    mediaPlayer.pause();
                }
                break;
            case R.id.next://下一首
                position = position == musicList.size() - 1 ? 0 : position + 1;
                mediaPlayer.reset();
                initMediaPlayer();
                play.setText("■");
                musicName.setText(songName);
                artist.setText(artistName);
                mediaPlayer.start();
                break;
            default:
                break;
        }
    }

    //顺序播放或单曲循环
    public void automaticPlay() {

        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer arg0) {
                if (valid) {
                    position = position == musicList.size() - 1 ? 0 : position + 1;
                    mediaPlayer.reset();
                    initMediaPlayer();
                    play.setText("■");
                    musicName.setText(songName);
                    mediaPlayer.start();
                    //Log.d("valid", "true");
                } else {
                    mediaPlayer.reset();
                    initMediaPlayer();
                    mediaPlayer.start();
                    Log.d("valid", "false");
                }
            }
        });
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.sequential_play:
                valid = true;
                Toast.makeText(this, "顺序播放", Toast.LENGTH_SHORT).show();
                break;
            case R.id.single_play:
                valid = false;
                Toast.makeText(this, "单曲循环", Toast.LENGTH_SHORT).show();
                break;
            default:
        }
        return true;
    }
}

4 Conclusion and experiences
through each module debugging, basically realized the function of the system.

Guess you like

Origin blog.csdn.net/weixin_44997483/article/details/90475162