Perkembangan zaman yang semakin maju menghasilkan berbagai produk berupa software yang dapat digunakan untuk mempermudah dan meringankan suatu pekerja pengguna. Dan perangkat yang paling laris saat ini adalah perangkat mobile yaitu android. Banyak aplikasi android baru yang diciptakan setiap harinya. Aplikasi yang paling banyak diminati oleh pengguna smartphone adalah aplikasi yang menyediakan fasilitas multimedia, seperti aplikasi pengambil dan pengubah gambar, serta aplikasi yang berhubungan dengan audio dan video. Kebanyakan aplikasi audio yang telah ada sebelumnya, merupakan aplikasi pemutar audio atau musik yang telah tersimpan didalam penyimpanan smartphone.
Penggunaan pemutar musik sering ditemui di kalangan pendengar musik baik berupa aplikasi yang berjalan dengan jaringan internet maupun yang offline. Terdapat banyak aplikasi pemutar musik yang disediakan oleh google play store sehingga pengguna dapat menentukan pilihannya.
Semakin berkembang zaman pemutar musik yang biasa digunakan untuk menghibur pengguna sekarang mulai berkembangan untuk mempermudah penggunaannya. Pembuatan aplikasi pemutar musik otomatis menjadi salah satu perkembangannya yang kemudian membuat pengguna memilih aplikasi yang simple dalam kinerja aplikasinya. Pemutar dengan tambahan fitur perintah suara dapat menarik minat dari pengguna karena terdapat perintah dalam bahasa inggris untuk menjalankan aplikasi ini. Penggunaan fitur ini berjalan ketika menggunakan headset. Sehingga pengguna hanya perlu mengaktifkan perintah voice dan aplikasi akan menjalankan perintahnya.
Baca Juga : Rahasia JavaScript Terungkap! Kehebatannya dan Tips Optimalisasi Super Praktis
Langkah-langkah Membuat Pemutar Musik Dengan Perintah Voice
Untuk membuat aplikasi ini terdapat beberapa tahap sehingga tidak bingung nantinya. Ada beberapa hal yang perlu disiapkan seperti aplikasi pengembangan android. Saya menggunakan android studio namun masih ada pilihan lain seperti Eclipse , NetBeans dan Unity.
Membuat Usecase
Terlebih dahulu kita akan membuat alur berjalannya aplikasi yang akan kita dalam bentuk usecase sehingga mudah dipahami berikut adalah usecase yang telah saya buat:
Untuk membuat usecase kalian dapat menggunakan aplikasi Star UML untuk membuat usecase. Dari usecase diatas kita dapat menyimpulkan bahwa dalam membuat pemutar musik kita butuh permission untuk membaca data penyimpanan dan audio record . Jadi untuk perintah voice kita akan merekam perintah kemudian baru menjalankannya.
Mengumpulkan Gambar
Untuk tampilan kita butuh gambar untuk mempercantik tampilan pemutar musik yang akan dibuat seperti untuk bagian tampilan splash, icon aplikasi, background pada daftar musik, background ketika musik dijalankan dan tombol pembantu untuk memutar musik.
Membuat Aplikasi Pemutar Musik
Sebelum memulai pembuatan kita buka android studio dan buat project baru. Masukan semua gambar tadi kedalam drawable. Kalian dapat drag & drop kedalam drawable. Kemudian membuat layout baru dengan cara masuk pada bagian res→layout dilanjutkan klik kanan dan pilih new→ layout resource file kemudian di beri nama "activity_splash.xml".
Kita baru saja menambahkan sebuah tampilan baru sebagai tampilan splash berikut souce code kalian masukan:
activity_splash.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/backsplash"
tools:context=".SplashActivity">
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:background="@drawable/splash" />
<LinearLayout
android:layout_width="match_parent"
android:layout_marginTop="450dp"
android:layout_height="50dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Kefbiv Music"
android:textSize="40dp"
android:fontFamily="@font/kauhan"
android:textAlignment="center"/>
</LinearLayout>
</RelativeLayout>
Tampilan splash saya membuatnya menggunakan ImageView dan TextView. Untuk memperbesar ukuran gambar kalian dapat merubah bagian android:layout_width dan android:layout_height.
Selanjutnya kita membuat tampilan daftar musik. Tampilan daftar musik kita akan buat pada activity_main.xml untuk tampilan daftar musik saya menggunakan TextView sebagai judul dan ListView sebagai daftar seluruh lagu.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/backmain"
tools:context=".MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="Daftar Musik"
android:textStyle="bold"
android:textAllCaps="true"
android:textSize="30dp"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:background="@color/blackPanther"/>
<ListView
android:id="@+id/songList"
android:layout_width="402dp"
android:layout_height="693dp"
android:padding="10dp"
android:layout_alignParentTop="true"
android:layout_marginTop="29dp">
</ListView>
</RelativeLayout>
Tampilan terakhir yang kita buat adalah tampilan home atau tampilan pemutar musik . Fungsi yang dimasukan hampir sama dengan sebelumnya saya menggunakan ImageView, TextView dan button.
activity_home.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/parentRelativeLayout"
android:background="@drawable/back"
tools:context=".Home">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Kefbiv Music"
android:fontFamily="@font/kauhan"
android:textAlignment="center"
android:textSize="40dp"
android:layout_marginTop="525dp"
android:textColor="@color/blackPanther"
/>
<RelativeLayout
android:id="@+id/upper"
android:layout_width="match_parent"
android:layout_height="480dp">
<ImageView
android:id="@+id/logo"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="180dp"
android:layout_marginLeft="100dp"/>
<TextView
android:id="@+id/songName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/logo"
android:textSize="25dp"
android:textStyle="italic"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="@android:color/primary_text_dark"
android:layout_margin="7dp"
android:singleLine="true"
android:marqueeRepeatLimit="marquee_forever"
android:ellipsize="marquee"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/lower"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/upper"
android:visibility="gone"
android:gravity="center">
<ImageView
android:id="@+id/previous_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/previous"
android:layout_marginRight="30dp" />
<ImageView
android:id="@+id/play_pause_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pause"
android:layout_toEndOf="@+id/previous_btn"
android:layout_marginRight="30dp"
android:layout_toRightOf="@+id/previous_btn" />
<ImageView
android:id="@+id/next_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/next"
android:layout_toEndOf="@+id/play_pause_btn"
android:layout_toRightOf="@+id/play_pause_btn" />
</RelativeLayout>
<Button
android:id="@+id/voice_enable"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginTop="600dp"
android:background="@color/blackPanther"
android:text="Voice Enable MODE - ON"
android:textAllCaps="false"
android:textColor="@android:color/white"
android:textSize="16dp"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
Setelah tampilan selesai kita masuk pada bagian java untuk deklarasi dan inisialisasi. Buka java dan buat home.java dan splashActivity.java.
Untuk splashActivity .java kita akan membuat durasi munculnya tampilan splash dan perpindahan antara tampilan splash ke tampilan daftar musik. Untuk durasi tampilan splash saya membuat 3 detik.
splashAcrivity.java
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
Thread thread = new Thread(){
public void run(){
try {
sleep(3000);
}catch (InterruptedException e){
e.printStackTrace();
}finally {
startActivity(new Intent(SplashActivity.this, MainActivity.class));
finish();
}
}
};
thread.start();
}
}
Perpindahan tampilan daftar musik akan diikuti dengan permission untuk membaca penyimpanan dan permission audio record. Setelah permission diperoleh maka aplikasi akan menampilkan data audio dalam daftar musik berdasarkan jenis yang telah kita tentukan seperti .mp3 , .aac dan .wav. Musik ini akan dimasukan kedalam array dan ditampilkan kedalam ListView.
activity_main.java
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
import java.io.File;
import java.util.ArrayList;
import static android.os.Environment.getExternalStorageDirectory;
public class MainActivity extends AppCompatActivity {
private String[] itemsAll;
private ListView mSongsList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSongsList =findViewById(R.id.songList);
appExternalStorageStoragePermisision();
}
public void appExternalStorageStoragePermisision() {
Dexter.withActivity(this)
.withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
.withListener(new PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
display();
}
@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}
}).check();
}
public ArrayList<File> readData(File file){
ArrayList<File> arrayList = new ArrayList<>();
File[] allFiles =file.listFiles();
for (File individualFile : allFiles)
{
if(individualFile.isDirectory() && !individualFile.isHidden())
{
arrayList.addAll(readData(individualFile));
}
else
{
if (individualFile.getName().endsWith(".aac") || individualFile.getName().endsWith(".wav")|| individualFile.getName().endsWith(".mp3"))
{
arrayList.add(individualFile);
}
}
}
return arrayList;
}
private void display()
{
final ArrayList<File> audio = readData(getExternalStorageDirectory());
itemsAll = new String[audio.size()];
for (int songCounter=0;songCounter<audio.size();songCounter++){
itemsAll[songCounter]=audio.get(songCounter).getName();
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(MainActivity.this, R.layout.row, itemsAll);
mSongsList.setAdapter(arrayAdapter);
mSongsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int i, long l)
{
String songName = mSongsList.getItemAtPosition(i).toString();
Intent intent = new Intent(MainActivity.this, Home.class);
intent.putExtra("song", audio );
intent.putExtra("name", songName);
intent.putExtra("posisi", i);
startActivity(intent);
}
});
}
}
Selanjutnya kita kan membuat bagian home.java yang berisi fungsi button play, next, previous dan tombol perintah voice. Ketika tombol perintah voice dijalankan button lain akan dihilangankan.
home.java
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.Locale;
public class Home extends AppCompatActivity {
private RelativeLayout pareRelativeLayout;
private SpeechRecognizer speechRecognizer;
private Intent speechRecognizerIntent;
private String keeper = "";
private ImageView pausePlayBtn, nextBtn, preBtn;
private TextView songNameTxt;
private ImageView imageView;
private RelativeLayout lowerRelativeLayout;
private Button voiceEnableBtn;
private String mode = "ON";
private int posisi;
private ArrayList<File> musik;
private String mSongname;
private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
checkVoiceCommandPermission();
pausePlayBtn = findViewById(R.id.play_pause_btn);
nextBtn = findViewById(R.id.next_btn);
preBtn = findViewById(R.id.previous_btn);
imageView = findViewById(R.id.logo);
lowerRelativeLayout = findViewById(R.id.lower);
voiceEnableBtn = findViewById(R.id.voice_enable);
songNameTxt = findViewById(R.id.songName);
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(Home.this);
speechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
pareRelativeLayout = findViewById(R.id.parentRelativeLayout);
imageView.setBackgroundResource(R.drawable.logo);
validasi();
voiceEnableBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mode.equals("ON")) {
mode = "OFF";
voiceEnableBtn.setText("Voice Enable MODE - OFF");
lowerRelativeLayout.setVisibility(View.VISIBLE);
} else {
mode = "ON";
voiceEnableBtn.setText("Voice Enable MODE - ON");
lowerRelativeLayout.setVisibility(View.GONE);
}
}
});
speechRecognizer.setRecognitionListener(new RecognitionListener() {
@Override
public void onReadyForSpeech(Bundle params) {
}
@Override
public void onBeginningOfSpeech() {
}
@Override
public void onRmsChanged(float rmsdB) {
}
@Override
public void onBufferReceived(byte[] buffer) {
}
@Override
public void onEndOfSpeech() {
}
@Override
public void onError(int error) {
}
@Override
public void onResults(Bundle bundle) {
ArrayList<String> matchesFound = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if (matchesFound != null) {
if (mode.equals("ON")) {
keeper = matchesFound.get(0);
Toast.makeText(Home.this, "Commad: " + keeper, Toast.LENGTH_LONG).show();
if (keeper.equals("pause the song")) {
playpuasemusik();
} else if (keeper.equals("Play the song")) {
playpuasemusik();
} else if (keeper.equals("play next song")) {
playNext();
} else if (keeper.equals("play previous song")) {
playprevoius();
}
}
}
}
@Override
public void onPartialResults(Bundle partialResults) {
}
@Override
public void onEvent(int eventType, Bundle params) {
}
});
pareRelativeLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
speechRecognizer.startListening(speechRecognizerIntent);
keeper = "";
break;
case MotionEvent.ACTION_UP:
speechRecognizer.stopListening();
break;
}
return false;
}
});
pausePlayBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playpuasemusik();
}
});
preBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaPlayer.getCurrentPosition()>0)
{
playprevoius();
}
}
});
nextBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaPlayer.getCurrentPosition()>0)
{
playNext();
}
}
});
}
private void validasi ()
{
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
musik = (ArrayList) bundle.getParcelableArrayList("song");
mSongname = musik.get(posisi).getName();
String songName = intent.getStringExtra("name");
songNameTxt.setText(songName);
songNameTxt.setSelected(true);
posisi = bundle.getInt("posisi", 0);
Uri uri = Uri.parse(musik.get(posisi).toString());
mediaPlayer = MediaPlayer.create(Home.this, uri);
mediaPlayer.start();
}
private void checkVoiceCommandPermission () {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!(ContextCompat.checkSelfPermission(Home.this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED)) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
startActivity(intent);
finish();
}
}
}
private void playpuasemusik()
{
imageView.setBackgroundResource(R.drawable.four);
if(mediaPlayer.isPlaying())
{
pausePlayBtn.setImageResource(R.drawable.play);
mediaPlayer.pause();
}
else
{
pausePlayBtn.setImageResource(R.drawable.pause);
mediaPlayer.start();
imageView.setImageResource(R.drawable.five);
}
}
private void playNext()
{
mediaPlayer.pause();
mediaPlayer.stop();
mediaPlayer.release();
posisi=((posisi+1)&musik.size());
Uri uri = Uri.parse(musik.get(posisi).toString());
mediaPlayer = MediaPlayer.create(Home.this, uri);
mSongname=musik.get(posisi).toString();
songNameTxt.setText(mSongname);
mediaPlayer.start();
imageView.setBackgroundResource(R.drawable.three);
if(mediaPlayer.isPlaying())
{
pausePlayBtn.setImageResource(R.drawable.pause);
}
else
{
pausePlayBtn.setImageResource(R.drawable.play);
imageView.setImageResource(R.drawable.five);
}
}
public void playprevoius()
{
mediaPlayer.pause();
mediaPlayer.stop();
mediaPlayer.release();
posisi = ((posisi-1)<0 ? (musik.size()-1) : (posisi-1));
Uri uri = Uri.parse(musik.get(posisi).toString());
mediaPlayer = MediaPlayer.create(Home.this, uri);
mSongname=musik.get(posisi).toString();
songNameTxt.setText(mSongname);
mediaPlayer.start();
imageView.setBackgroundResource(R.drawable.two);
if(mediaPlayer.isPlaying())
{
pausePlayBtn.setImageResource(R.drawable.pause);
}
else
{
pausePlayBtn.setImageResource(R.drawable.play);
imageView.setImageResource(R.drawable.five);
}
}
}
Untuk yang terakhir kita perlu menambahkan permission pada bagian manifest agar dapat mengakses keluar aplikasi dan merubah bagian activity yang dijalankan pertama kali.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Home" />
<activity android:name=".MainActivity"></activity>
</application>
</manifest>
Aplikasi telah selesai dibuat dan siap untuk dicoba. Namun jika kalian ingin memasangnya di smartphone kalian harus merubahnya kedalam bentuk .apk terlebih dulu dan memasangkan ke android kalian masing-masing. selamat mencoba....!
Sumber Referensi dan Gambar :
https://repository.amikom.ac.id