com.apps.howard.vicissitude.services.NotificationService.java Source code

Java tutorial

Introduction

Here is the source code for com.apps.howard.vicissitude.services.NotificationService.java

Source

//
//  NotificationService.java
//
//  Author:
//       Howard Beard-Marlowe <howardbm@live.se>
//
//  Copyright (c) 2015 Howard Beard-Marlowe
//
//  This program 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.
//
//  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

package com.apps.howard.vicissitude.services;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;

import com.apps.howard.vicissitude.R;

import java.util.HashMap;

/**
 * Service responsible for displaying the alerts
 * (Including sounds and vibration)
 */
public class NotificationService extends Service {

    /**
     * Hashmap allows for grouping alerts by sender
     * TODO: Evaluate whether this should actually be grouped by alert name
     */
    private final HashMap<String, String> lastNotificationMessage = new HashMap<>();
    /**
     * Vibration pattern, short controlled bursts
     */
    private final long vibrationPattern[] = { 0, 200, 500 };
    /**
     * Notification manager which handles notifications
     */
    private NotificationManager notificationManager;
    /**
     * Vibrator which uses a pattern to vibrate the phone
     */
    private Vibrator vibrator;
    /**
     * Preferences required for override volume
     * and tone settings
     */
    private SharedPreferences prefs;

    //region Android Lifecycle
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

        notificationManager.cancelAll();
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Attempt to get extras if they exist
        Bundle intentExtras;
        try {
            intentExtras = intent.getExtras();
        } catch (NullPointerException e) {
            intentExtras = null;
        }
        // Attempt to get action if it exists
        String action;
        try {
            action = intent.getAction();
        } catch (NullPointerException e) {
            action = null;
        }

        if (intentExtras != null) {
            // Extract extras
            String message = intentExtras.getString("notification-message");
            String sender = intentExtras.getString("notification-sender");
            String alarmName = intentExtras.getString("notification-alarm-name");

            logMessage(alarmName, message);
            buildNotification(message, sender);
        }

        if (action != null)
            maybeCancelNotification(action);

        return START_NOT_STICKY;
    }
    //endregion

    //region Internal Functions
    private void logMessage(String alarmName, String message) {
        Intent logIntent = new Intent(this, AlertLogService.class);
        logIntent.putExtra("log-service", "Notification Service");
        logIntent.putExtra("log-action", message + " triggered alarm:" + alarmName);

        this.startService(logIntent);
    }

    private void maybeCancelNotification(String action) {
        if (!action.equals("")) {
            vibrator.cancel();
            lastNotificationMessage.remove(action);
        }
    }

    private Uri getAlarmTone() {
        return Uri.parse(prefs.getString(getString(R.string.pref_sound_alarm_tone_key),

                RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM).toString()));
    }

    private String maybeSetNotificationMessage(String sender) {
        String lastMessage = this.lastNotificationMessage.get(sender);

        if (lastMessage != null)
            return lastMessage;

        return "";
    }

    private NotificationCompat.Builder getNotificationBuilder(String message, String sender) {
        return new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_stat_name)
                .setContentTitle(getString(R.string.notification_title_notification_service) + sender)
                .setStyle((new NotificationCompat.BigTextStyle()).bigText(message)
                        .setBigContentTitle(getString(R.string.notification_title_notification_service) + sender)
                        .setSummaryText("Vicissitude"))
                .setGroup(sender).setSound(getAlarmTone(), AudioManager.STREAM_ALARM).setAutoCancel(true);
    }

    private void buildNotification(String message, String sender) {
        String newNotificationMessage = maybeSetNotificationMessage(sender);

        newNotificationMessage += message + System.getProperty("line.separator");

        NotificationCompat.Builder mBuilder = getNotificationBuilder(message, sender);

        // Creates an explicit intent for an Activity in your app
        Notification mNotification;

        Intent resultIntent = new Intent(this, NotificationService.class);
        resultIntent.setAction(sender);

        PendingIntent resultPendingIntent = PendingIntent.getService(this, 0, resultIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        mBuilder.setContentIntent(resultPendingIntent);
        mBuilder.setDeleteIntent(resultPendingIntent);

        mNotification = mBuilder.build();
        mNotification.flags |= Notification.FLAG_INSISTENT;

        this.lastNotificationMessage.put(sender, newNotificationMessage);

        maybeOverrideVolumeBeforeNotify();

        notificationManager.notify(sender, 1, mNotification);
        vibrator.vibrate(vibrationPattern, 0);
    }

    private void maybeOverrideVolumeBeforeNotify() {

        boolean settingsOverrideVolumeEnabled = prefs.getBoolean(this.getString(R.string.pref_override_volume_key),
                false);
        int settingsOverrideVolume = prefs.getInt(this.getString(R.string.pref_alert_volume_key), 1);

        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

        if (settingsOverrideVolumeEnabled) {
            audioManager.setStreamVolume(AudioManager.STREAM_ALARM, settingsOverrideVolume, 0);
        }
    }
    //endregion
}