[android] 특정 요일, 특정 시간마다 내가 지정한 사운드 파일 재생하기

원리는 24시간 마다 반복하고, 오늘의 요일이 알람에 울리게 지정한 요일과 같으면 사운드를 재생한다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onRegist"
        android:text="등록" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onUnregist"
        android:text="해지" />

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

        <ToggleButton
            android:id="@+id/toggle_sun"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textOff="일"
            android:textOn="일" />

        <ToggleButton
            android:id="@+id/toggle_mon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textOff="월"
            android:textOn="월" />

        <ToggleButton
            android:id="@+id/toggle_tue"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textOff="화"
            android:textOn="화" />

        <ToggleButton
            android:id="@+id/toggle_wed"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textOff="수"
            android:textOn="수" />

        <ToggleButton
            android:id="@+id/toggle_thu"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textOff="목"
            android:textOn="목" />

        <ToggleButton
            android:id="@+id/toggle_fri"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textOff="금"
            android:textOn="금" />

        <ToggleButton
            android:id="@+id/toggle_sat"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textOff="토"
            android:textOn="토" />
    </LinearLayout>

</LinearLayout>

등록, 해지, 각 요일의 on/off 버튼을 추가한다.

 

public class MainActivity extends Activity
{
   private static final String BASE_PATH = Environment.getExternalStorageDirectory() + "/myapp";
   private static final String NORMAL_PATH = BASE_PATH + "/normal";

   private AlarmManager _am;

   private ToggleButton _toggleSun, _toggleMon, _toggleTue, _toggleWed, _toggleThu, _toggleFri, _toggleSat;

   @Override
   protected void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      _am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
      _toggleSun = (ToggleButton) findViewById(R.id.toggle_sun);
      _toggleMon = (ToggleButton) findViewById(R.id.toggle_mon);
      _toggleTue = (ToggleButton) findViewById(R.id.toggle_tue);
      _toggleWed = (ToggleButton) findViewById(R.id.toggle_wed);
      _toggleThu = (ToggleButton) findViewById(R.id.toggle_thu);
      _toggleFri = (ToggleButton) findViewById(R.id.toggle_fri);
      _toggleSat = (ToggleButton) findViewById(R.id.toggle_sat);
   }

   public void onRegist(View v)
   {
      Log.i("MainActivity.java | onRegist", "|" + "========= regist" + "|");

      File file = new File(NORMAL_PATH + "/drop_1235.m4a");
      Log.i("MainActivity.java | onRegist", "| file exists? : " + file.exists() + "|" + file.hashCode());

      boolean[] week = { false, _toggleSun.isChecked(), _toggleMon.isChecked(), _toggleTue.isChecked(), _toggleWed.isChecked(),
            _toggleThu.isChecked(), _toggleFri.isChecked(), _toggleSat.isChecked() }; // sunday=1 이라서 0의 자리에는 아무 값이나 넣었음

      Intent intent = new Intent(this, AlarmReceiver.class);
      intent.putExtra("file", file.toString());
      intent.putExtra("weekday", week);
      PendingIntent pIntent = PendingIntent.getBroadcast(this, file.hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT);

      Calendar cal = Calendar.getInstance();
      cal.set(Calendar.SECOND, cal.get(Calendar.SECOND) + 10); // 10초 뒤

      long oneday = 24 * 60 * 60 * 1000;// 24시간

      // 10초 뒤에 시작해서 매일 같은 시간에 반복하기
      _am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), oneday, pIntent);
   }

   public void onUnregist(View v)
   {
      Log.i("MainActivity.java | onUnregist", "|" + "========= unregist" + "|");

      File file = new File(NORMAL_PATH + "/drop_1235.m4a");
      Log.i("MainActivity.java | onRegist", "| file exists? : " + file.exists() + "|" + file.hashCode());

      Intent intent = new Intent(this, AlarmReceiver.class);
      PendingIntent pIntent = PendingIntent.getBroadcast(this, file.hashCode(), intent, 0);

      _am.cancel(pIntent);
   }   
}

 

버튼을 누른지 10초뒤에 시작해서 24시간 마다 반복한다.

사운드롤 재생하도록 설정한 요일과 오늘의 요일이 같으면 사운드를 재생한다.

intent에 재생할 사운드 파일의 전체 경로를 넣고, 어느 요일에 재생할건지도 boolean 배열에 담아서 넘긴다.

다만 Calendar.Sunday = 1 이라서 배열의 처음에는 아무 값이나 넣었다.

 

고유값은 그냥 File의 hashCode 를 쓰기로 한다.

중복될 수도 있다고는 하는데, 파일이 수천개도 아니고 이 정도 수준에서는 중복될일 없을 것이다.

파일에도 _id같은 unique id가 있으면 좋으련만…

 

 

 

public class AlarmReceiver extends BroadcastReceiver
{
   @Override
   public void onReceive(Context context, Intent intent)
   {
      Log.i("AlarmReceiver.java | onReceive", "|" + "============ receive" + "|");

      boolean[] week = intent.getBooleanArrayExtra("weekday");
      Log.i("AlarmReceiver.java | onReceive", "|일 : " + week[Calendar.SUNDAY]);
      Log.i("AlarmReceiver.java | onReceive", "|월 : " + week[Calendar.MONDAY]);
      Log.i("AlarmReceiver.java | onReceive", "|화 : " + week[Calendar.TUESDAY]);
      Log.i("AlarmReceiver.java | onReceive", "|수 : " + week[Calendar.WEDNESDAY]);
      Log.i("AlarmReceiver.java | onReceive", "|목 : " + week[Calendar.THURSDAY]);
      Log.i("AlarmReceiver.java | onReceive", "|금 : " + week[Calendar.FRIDAY]);
      Log.i("AlarmReceiver.java | onReceive", "|토 : " + week[Calendar.SATURDAY]);

      Calendar cal = Calendar.getInstance();
      Log.i("AlarmReceiver.java | onReceive", "|" + cal.get(Calendar.DAY_OF_WEEK) + "|");
      // 오늘 요일의 알람 재생이 true이면 사운드 재생

      if (!week[cal.get(Calendar.DAY_OF_WEEK)])
         return;

      File file = new File(intent.getStringExtra("file"));
      Log.i("AlarmReceiver.java | onReceive", "|" + file.toString() + "|");

      MediaPlayer player = new MediaPlayer();
      player.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
      {
         @Override
         public void onPrepared(MediaPlayer mp)
         {
            mp.start();
         }
      });
      try
      {
         player.setDataSource(file.toString());
         player.prepare();
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }

   }
}

해당 시간이  되면 이 리시버가 호출된다.

intent에서 사운드 파일의 경로와 재생할 요일 정보를 얻는다.

오늘의 요일에 해당하는 값이 true이면 사운드를 재생한다.

 

 

<receiver android:name="AlarmReceiver" />

manifest 파일에 리시버를 등록해주면 된다.

 

 

알람을 등록할 때 사용한 File.hashCode가 고유값이 되어서 나중에 수정할 때도 저 값을 이용하면 된다.

이러면 여러 개의 알람을 등록할 수도 있다.

다만 파일이 지워질 때 알람도 같이 취소시켜줘야 하는 불편함은 생긴다.