Nicba1010 icon

Test

Nicba1010 | PRO | 07/17/19 11:03:03 AM UTC | 0 ⭐ | 323 👁️ | Never ⏰ | []
text |

11.27 KB

|

None

|

0 👍

/

0 👎

public class FakeService extends Service {
    /**
     * Play alarm up to 10 minutes before silencing
     */
    private static final int ALARM_TIMEOUT_SECONDS = 10 * 60;
    private static final long[] sVibratePattern = new long[]{500, 500};
    public static final String FAKE_SERVICE_PARAM = "FAKE_SERVICE_PARAM";
    private static final int NOTIFICATION_ID = 1;
    private static final String CHANNEL_ID = "ALARM_CHANNEL ID";
    private static final String CHANNEL_NAME = "ALARM_CHANNEL NAME";
    public static String ACTION_ALARM_SNOOZE = "com.troido.intent.action.ACTION_ALARM_SNOOZE";
    private boolean mPlaying = false;
    private Vibrator mVibrator;
    private MediaPlayer mMediaPlayer;
    private TelephonyManager mTelephonyManager;
    private int mInitialCallState;
    BroadcastReceiver snoozeAlarmReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action != null && action.equalsIgnoreCase(ACTION_ALARM_SNOOZE)) {
                stopSelf();
            }
        }
    };
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent == null) {
            stopSelf();
            return START_NOT_STICKY;
        }
        Commands.ALARM alarmType = (Commands.ALARM) intent.getSerializableExtra(FAKE_SERVICE_PARAM);
        Notification notification = createNotification(alarmType);
        registerSnoozeAlarmReceiver();
        startForeground(NOTIFICATION_ID, notification);
        play(alarmType);
        // Record the initial call state here so that the new alarm has the
        // newest state.
        mInitialCallState = mTelephonyManager.getCallState();
        return START_NOT_STICKY;
    }
    @RequiresApi(Build.VERSION_CODES.O)
    private String createNotificationChannel() {
        String channelId = CHANNEL_ID;
        NotificationChannel chan = new NotificationChannel(channelId, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
        chan.setLightColor(Color.RED);
        chan.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        NotificationManager service = ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE));
        if (service != null) {
            service.createNotificationChannel(chan);
        }
        return channelId;
    }
    private void registerSnoozeAlarmReceiver() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ACTION_ALARM_SNOOZE);
        registerReceiver(snoozeAlarmReceiver, intentFilter);
    }
    private Notification createNotification(Commands.ALARM alarmType) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel();
        }
        Intent snoozeIntent = new Intent();
        snoozeIntent.setAction(ACTION_ALARM_SNOOZE);
        PendingIntent snoozePendingIntent =
                PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);
        String alarmText = "";
        if (alarmType == Commands.ALARM.BURGLARY) {
            alarmText += "ALARM FOR BURGLARY IS RINGING..";
        } else if (alarmType == Commands.ALARM.Fire) {
            alarmText += "ALARM FOR FIRE IS RINGING..";
        } else if (alarmType == Commands.ALARM.BOTH) {
            alarmText += "ALARM FOR FIRE AND BURGLARY IS RINGING..";
        }
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("ALARM! ALARM! ALARM!")
                .setContentText(alarmText)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setContentIntent(snoozePendingIntent)
                .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                        snoozePendingIntent);
        return mBuilder.build();
    }
    private Uri getUriAlert() {
        Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
        if (alert == null) {
            // alert is null, using backup
            alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            // I can't see this ever being null (as always have a default notification)
            // but just incase
            if (alert == null) {
                // alert backup is null, using 2nd backup
                alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
            }
        }
        return alert;
    }
    // Volume suggested by media team for in-call alarms.
    private static final float IN_CALL_VOLUME = 0.125f;
    private void play(Commands.ALARM alarmType) {
        // stop() checks to see if we are already playing.
        stop();
        Log.v("ALARM", "AlarmKlaxon.play() ");
        // TODO: Reuse mMediaPlayer instead of creating a new one and/or use
        // RingtoneManager.
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            public boolean onError(MediaPlayer mp, int what, int extra) {
                Log.e("ALARM", "Error occurred while playing audio.");
                mp.stop();
                mp.release();
                mMediaPlayer = null;
                return true;
            }
        });
        try {
            // Check if we are in a call. If we are, use the in-call alarm
            // resource at a low volume to not disrupt the call.
            if (mTelephonyManager.getCallState()
                    != TelephonyManager.CALL_STATE_IDLE) {
                Log.v("ALARM", "Using the in-call alarm");
                mMediaPlayer.setVolume(IN_CALL_VOLUME, IN_CALL_VOLUME);
                setDataSourceFromResource(getResources(), mMediaPlayer,
                        R.raw.burglary);
            } else {
                if (alarmType == Commands.ALARM.BURGLARY || alarmType == Commands.ALARM.BOTH) {
                    setDataSourceFromResource(getResources(), mMediaPlayer,
                            R.raw.burglary);
                } else if (alarmType == Commands.ALARM.Fire) {
                    setDataSourceFromResource(getResources(), mMediaPlayer,
                            R.raw.fire);
                }
            }
            startAlarm(mMediaPlayer);
        } catch (Exception ex) {
            Log.v("ALARM", "Using the fallback ringtone");
            // The alert may be on the sd card which could be busy right
            // now. Use the fallback ringtone.
            try {
                // Must reset the media player to clear the error state.
                mMediaPlayer.reset();
                setDataSourceFromResource(getResources(), mMediaPlayer,
                        R.raw.burglary);
                startAlarm(mMediaPlayer);
            } catch (Exception ex2) {
                // At this point we just don't play anything.
                Log.e("ALARM", "Failed to play fallback ringtone", ex2);
            }
        }
        /* Start the vibrator after everything is ok with the media player */
        mVibrator.vibrate(sVibratePattern, 0);
        enableKiller();
        mPlaying = true;
    }
    // Do the common stuff when starting the alarm.
    private void startAlarm(MediaPlayer player)
            throws java.io.IOException, IllegalArgumentException,
            IllegalStateException {
        final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        // do not play alarms if stream volume is 0
        // (typically because ringer mode is silent).
        if (audioManager != null && audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
            player.setAudioStreamType(AudioManager.STREAM_ALARM);
            player.setLooping(true);
            player.prepare();
            player.start();
        }
    }
    private void setDataSourceFromResource(Resources resources,
                                           MediaPlayer player, int res) throws java.io.IOException {
        AssetFileDescriptor afd = resources.openRawResourceFd(res);
        if (afd != null) {
            player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
                    afd.getLength());
            afd.close();
        }
    }
    /**
     * Stops alarm audio and disables alarm if it not snoozed and not
     * repeating
     */
    public void stop() {
        Log.v("TAG", "AlarmKlaxon.stop()");
        if (mPlaying) {
            mPlaying = false;
            // Stop audio playing
            if (mMediaPlayer != null) {
                mMediaPlayer.stop();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
            // Stop vibrator
            mVibrator.cancel();
        }
        disableKiller();
    }
    /**
     * Kills alarm audio after ALARM_TIMEOUT_SECONDS, so the alarm
     * won't run all day.
     * <p>
     * This just cancels the audio, but leaves the notification
     * popped, so the user will know that the alarm tripped.
     */
    private void enableKiller() {
        mHandler.sendMessageDelayed(mHandler.obtainMessage(KILLER, ""),
                1000 * ALARM_TIMEOUT_SECONDS);
    }
    private void disableKiller() {
        mHandler.removeMessages(KILLER);
    }
    // Internal messages
    private static final int KILLER = 1000;
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case KILLER:
                    Log.v("ALARM", "*********** Alarm killer triggered ***********");
                    stopSelf();
                    break;
            }
        }
    };
    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String ignored) {
            // The user might already be in a call when the alarm fires. When
            // we register onCallStateChanged, we get the initial in-call state
            // which kills the alarm. Check against the initial call state so
            // we don't kill the alarm during a call.
            if (state != TelephonyManager.CALL_STATE_IDLE
                    && state != mInitialCallState) {
                stopSelf();
            }
        }
    };
    @Override
    public void onCreate() {
        mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        // Listen for incoming calls to kill the alarm.
        mTelephonyManager =
                (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        if (mTelephonyManager != null) {
            mTelephonyManager.listen(
                    mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        }
        AlarmAlertWakeLock.acquireCpuWakeLock(this);
    }
    @Override
    public void onDestroy() {
        stop();
        // Stop listening for incoming calls.
        mTelephonyManager.listen(mPhoneStateListener, 0);
        AlarmAlertWakeLock.releaseCpuLock();
        unregisterReceiver(snoozeAlarmReceiver);
    }
}

Comments