org.yuttadhammo.BodhiTimer.TimerReceiver.java Source code

Java tutorial

Introduction

Here is the source code for org.yuttadhammo.BodhiTimer.TimerReceiver.java

Source

/*
This file is part of Bodhi Timer.
    
Bodhi Timer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
Bodhi Timer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with Bodhi Timer.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.yuttadhammo.BodhiTimer;

import java.io.IOException;
import java.util.Date;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.SystemClock;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.speech.tts.TextToSpeech;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.util.Log;

public class TimerReceiver extends BroadcastReceiver {
    private final static String TAG = "TimerReceiver";
    final static String CANCEL_NOTIFICATION = "CANCEL_NOTIFICATION";
    public static MediaPlayer player;

    public static String BROADCAST_RESET = "org.yuttadhammo.BodhiTimer.RESTART";

    private TextToSpeech tts;

    @Override
    public void onReceive(Context context, Intent pintent) {
        Log.v(TAG, "ALARM: received alarm");

        NotificationManager mNM = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        if (player != null) {
            Log.v(TAG, "Releasing media player...");
            try {
                player.release();
                player = null;
            } catch (Exception e) {
                e.printStackTrace();
                player = null;
            } finally {
                // do nothing
            }
        }

        // Cancel notification and return...
        if (CANCEL_NOTIFICATION.equals(pintent.getAction())) {
            Log.v(TAG, "Cancelling notification...");

            mNM.cancelAll();
            return;
        }

        // ...or display a new one

        Log.v(TAG, "Showing notification...");

        player = new MediaPlayer();

        int setTime = pintent.getIntExtra("SetTime", 0);
        String setTimeStr = TimerUtils.time2humanStr(context, setTime);
        Log.v(TAG, "Time: " + setTime);

        CharSequence text = context.getText(R.string.Notification);
        CharSequence textLatest = String.format(context.getString(R.string.timer_for_x), setTimeStr);

        // Load the settings 
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        boolean led = prefs.getBoolean("LED", true);
        boolean vibrate = prefs.getBoolean("Vibrate", true);
        String notificationUri = "";

        boolean useAdvTime = prefs.getBoolean("useAdvTime", false);
        String advTimeString = prefs.getString("advTimeString", "");
        String[] advTime = null;
        int advTimeIndex = 1;

        if (useAdvTime && advTimeString.length() > 0) {
            advTime = advTimeString.split("\\^");
            advTimeIndex = prefs.getInt("advTimeIndex", 1);
            String[] thisAdvTime = advTime[advTimeIndex - 1].split("#"); // will be of format timeInMs#pathToSound

            if (thisAdvTime.length == 3)
                notificationUri = thisAdvTime[1];
            if (notificationUri.equals("sys_def"))
                notificationUri = prefs.getString("NotificationUri",
                        "android.resource://org.yuttadhammo.BodhiTimer/" + R.raw.bell);
        } else
            notificationUri = prefs.getString("NotificationUri",
                    "android.resource://org.yuttadhammo.BodhiTimer/" + R.raw.bell);

        Log.v(TAG, "notification uri: " + notificationUri);

        if (notificationUri.equals("system"))
            notificationUri = prefs.getString("SystemUri", "");
        else if (notificationUri.equals("file"))
            notificationUri = prefs.getString("FileUri", "");
        else if (notificationUri.equals("tts")) {
            notificationUri = "";
            final String ttsString = prefs.getString("tts_string", context.getString(R.string.timer_done));
            Intent ttsIntent = new Intent(context, TTSService.class);
            ttsIntent.putExtra("spoken_text", ttsString);
            context.startService(ttsIntent);
        }

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context.getApplicationContext())
                .setSmallIcon(R.drawable.notification).setContentTitle(text).setContentText(textLatest);

        Uri uri = null;

        // Play a sound!
        if (!notificationUri.equals(""))
            uri = Uri.parse(notificationUri);

        // Vibrate
        if (vibrate && uri == null) {
            mBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
        }

        // Have a light
        if (led) {
            mBuilder.setLights(0xff00ff00, 300, 1000);
        }

        mBuilder.setAutoCancel(true);

        // Creates an explicit intent for an Activity in your app
        Intent resultIntent = new Intent(context, TimerActivity.class);

        // The stack builder object will contain an artificial back stack for the
        // started Activity.
        // This ensures that navigating backward from the Activity leads out of
        // your application to the Home screen.
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
        // Adds the back stack for the Intent (but not the Intent itself)
        stackBuilder.addParentStack(TimerActivity.class);
        // Adds the Intent that starts the Activity to the top of the stack
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(resultPendingIntent);
        NotificationManager mNotificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);

        // Create intent for cancelling the notification
        Context appContext = context.getApplicationContext();
        Intent intent = new Intent(appContext, TimerReceiver.class);
        intent.setAction(CANCEL_NOTIFICATION);

        // Cancel the pending cancellation and create a new one
        PendingIntent pendingCancelIntent = PendingIntent.getBroadcast(appContext, 0, intent,
                PendingIntent.FLAG_CANCEL_CURRENT);

        if (uri != null) {

            //remove notification sound
            mBuilder.setSound(null);

            try {
                if (player != null && player.isPlaying()) {
                    player.release();
                    player = new MediaPlayer();
                }

                int currVolume = prefs.getInt("tone_volume", 0);
                if (currVolume != 0) {
                    float log1 = (float) (Math.log(100 - currVolume) / Math.log(100));
                    player.setVolume(1 - log1, 1 - log1);
                }
                player.setDataSource(context, uri);
                player.prepare();
                player.setLooping(false);
                player.setOnCompletionListener(new OnCompletionListener() {

                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        // TODO Auto-generated method stub
                        mp.release();
                    }

                });
                player.start();
                if (vibrate) {
                    Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
                    vibrator.vibrate(1000);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (prefs.getBoolean("AutoClear", false)) {
            // Determine duration of notification sound
            int duration = 5000;
            if (uri != null) {
                MediaPlayer cancelPlayer = new MediaPlayer();
                try {
                    cancelPlayer.setDataSource(context, uri);
                    cancelPlayer.prepare();
                    duration = Math.max(duration, cancelPlayer.getDuration() + 2000);
                } catch (java.io.IOException ex) {
                    Log.e(TAG, "Cannot get sound duration: " + ex);
                    duration = 30000; // on error, default to 30 seconds
                } finally {
                    cancelPlayer.release();
                }
                cancelPlayer.release();
            }
            Log.v(TAG, "Notification duration: " + duration + " ms");
            // Schedule cancellation
            AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            alarmMgr.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + duration,
                    pendingCancelIntent);
        }

        if (useAdvTime && advTimeString.length() > 0) {
            Intent broadcast = new Intent();

            SharedPreferences.Editor editor = prefs.edit();
            if (advTimeIndex < advTime.length) {
                editor.putInt("advTimeIndex", advTimeIndex + 1);

                String[] thisAdvTime = advTime[advTimeIndex].split("#"); // will be of format timeInMs#pathToSound

                int time = Integer.parseInt(thisAdvTime[0]);

                broadcast.putExtra("time", time);

                // Save new time
                editor.putLong("TimeStamp", new Date().getTime() + time);
                editor.putInt("LastTime", time);

                // editor.putString("NotificationUri", thisAdvTime[1]);

                mNM.cancelAll();
                Log.v(TAG, "Starting next iteration of the timer service ...");
                Intent rintent = new Intent(context, TimerReceiver.class);
                rintent.putExtra("SetTime", time);
                PendingIntent mPendingIntent = PendingIntent.getBroadcast(context, 0, rintent,
                        PendingIntent.FLAG_UPDATE_CURRENT);
                AlarmManager mAlarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
                mAlarmMgr.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + time, mPendingIntent);
            } else {
                broadcast.putExtra("stop", true);
                editor.putInt("advTimeIndex", 1);

            }
            broadcast.setAction(BROADCAST_RESET);
            context.sendBroadcast(broadcast);

            editor.apply();

        } else if (prefs.getBoolean("AutoRestart", false)) {
            int time = pintent.getIntExtra("SetTime", 0);
            if (time != 0) {

                mNM.cancel(0);
                Log.v(TAG, "Restarting the timer service ...");
                Intent rintent = new Intent(context, TimerReceiver.class);
                rintent.putExtra("SetTime", time);
                PendingIntent mPendingIntent = PendingIntent.getBroadcast(context, 0, rintent,
                        PendingIntent.FLAG_UPDATE_CURRENT);
                AlarmManager mAlarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
                mAlarmMgr.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + time, mPendingIntent);

                // Save new time
                SharedPreferences.Editor editor = prefs.edit();
                editor.putLong("TimeStamp", new Date().getTime() + time);
                editor.putInt("LastTime", time);
                editor.apply();

                Intent broadcast = new Intent();
                broadcast.putExtra("time", time);
                broadcast.setAction(BROADCAST_RESET);
                context.sendBroadcast(broadcast);

            }
        }

        mNotificationManager.notify(0, mBuilder.build());

        Log.d(TAG, "ALARM: alarm finished");

    }
}