com.kyleszombathy.sms_scheduler.MessageAlarmReceiver.java Source code

Java tutorial

Introduction

Here is the source code for com.kyleszombathy.sms_scheduler.MessageAlarmReceiver.java

Source

/*
 Copyright 2016 Kyle Szombathy
    
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
    
 http://www.apache.org/licenses/LICENSE-2.0
    
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
package com.kyleszombathy.sms_scheduler;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.telephony.SmsManager;
import android.util.Log;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Objects;

public class MessageAlarmReceiver extends WakefulBroadcastReceiver {
    private static final String TAG = "MessageAlarmReceiver";
    private AlarmManager alarm;
    private PendingIntent pendingIntent;
    private SmsManager smsManager = SmsManager.getDefault();
    public static final int NOTIFICATION_ID = 11111;
    private NotificationManager mNotificationManager;
    private Context context;
    private String SENT = "sent";
    private String DELIVERED = "delivered";

    @Override
    public void onReceive(Context context, Intent intent) {
        this.context = context;
        boolean sendSuccessFlag = true;

        // Get wakelock
        Intent service = new Intent(context, MessageAlarmReceiver.class);

        // Start the service, keeping the device awake while it is launching.
        Log.i("SimpleWakefulReceiver", "Starting service @ " + SystemClock.elapsedRealtime());
        startWakefulService(context, service);

        // Get data from intent
        ArrayList<String> phoneList = intent.getStringArrayListExtra("pNum");
        String messageContent = intent.getStringExtra("message");
        int alarmNumber = intent.getIntExtra("alarmNumber", -1);
        ArrayList<String> nameList = intent.getStringArrayListExtra("nameList");

        // Split message, regardless if needed - just in case I have the message length number wrong
        final ArrayList<String> messageArrayList = smsManager.divideMessage(messageContent);

        // Sends to multiple recipients
        for (int i = 0; i < phoneList.size(); i++) {
            // Send message and retrieve
            boolean result = sendSMSMessage(phoneList.get(i), messageArrayList);
            if (!result) {
                sendSuccessFlag = false;
            }
        }

        /* Register for SMS send action */
        context.getApplicationContext().registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String result = "";
                final String[] TRANSMISSION_TYPE = { "Transmission successful", "Transmission failed", "Radio off",
                        "No PDU defined", "No service" };

                switch (getResultCode()) {
                case Activity.RESULT_OK:
                    result = TRANSMISSION_TYPE[0];
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    result = TRANSMISSION_TYPE[1];
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    result = TRANSMISSION_TYPE[2];
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    result = TRANSMISSION_TYPE[3];
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    result = TRANSMISSION_TYPE[4];
                    break;
                }
                Log.i(TAG, result + " for message " + messageArrayList.toString());
                // Handle error
                if (!Objects.equals(result, TRANSMISSION_TYPE[0])) {
                    //messageSendSuccess[0] = false;
                }
            }
        }, new IntentFilter(SENT));

        // Create notification message
        String notificationMessage = Tools.createSentString(context, nameList, 1, sendSuccessFlag);

        // Send notification if message send successfull
        if (sendSuccessFlag) {
            sendNotification(context, notificationMessage, messageContent, true, nameList);
        } else {
            sendNotification(context, notificationMessage, messageContent, false, nameList);
        }
        // Archive, regardless of send success or not
        markAsSent(context, notificationMessage, alarmNumber);
        // Release wakelock
        completeWakefulIntent(service);
    }

    /** Sends the actual messaage and handles errors*/
    private boolean sendSMSMessage(String phoneNumber, final ArrayList<String> messageArrayList) {
        int size = messageArrayList.size();

        // Sent and delivery intents
        Intent sentIntent = new Intent(SENT);
        Intent deliveryIntent = new Intent(DELIVERED);

        /*Create Pending Intents*/
        PendingIntent sentPI = PendingIntent.getBroadcast(context.getApplicationContext(), 0, sentIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent deliverPI = PendingIntent.getBroadcast(context.getApplicationContext(), 0, deliveryIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        // Sends single or multiple messages based off message length
        if (size == 1) {
            smsManager.sendTextMessage(phoneNumber, null, messageArrayList.get(0), sentPI, deliverPI);
        } else {
            // Create sending/delivery lists for sending to multiple recipients
            ArrayList<PendingIntent> sentPIList = new ArrayList<>(Collections.nCopies(size, sentPI));
            ArrayList<PendingIntent> deliveryPIList = new ArrayList<>(Collections.nCopies(size, deliverPI));
            smsManager.sendMultipartTextMessage(phoneNumber, null, messageArrayList, sentPIList, deliveryPIList);
        }
        return true;
    }

    /** Posts a notification indicating recipients
     * @param context Application Context
     * @param notificationMessage
     * @param messageContent Message content to show
     * @param sendSuccessful Was the message sent succesfully*/
    private void sendNotification(Context context, String notificationMessage, String messageContent,
            boolean sendSuccessful, ArrayList<String> recipients) {
        mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        // Check if notification access is granted
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (mNotificationManager.isNotificationPolicyAccessGranted()) {

                // Bundle Extras
                Bundle bundle = new Bundle();
                bundle.putStringArrayList("recipients", recipients);
                bundle.putBoolean("sendSuccessful", sendSuccessful);

                // Create base notification
                PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, Home.class),
                        0);
                NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
                        .setSmallIcon(R.drawable.ic_done_black_24dp).setAutoCancel(true).setExtras(bundle);

                /*
                // If notification isn't present
                  if (notification == null) {
                // Construct notification
                mBuilder.setStyle(new NotificationCompat.BigTextStyle()
                        .bigText(notificationMessage + ": " + messageContent));
                    
                if (sendSuccessful) {
                    postSimpleNotification();
                    mBuilder.setContentTitle(context.getString(R.string.message_success));
                    mBuilder.setContentText(notificationMessage);
                    mBuilder.setContentIntent(contentIntent);
                    mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
                } else { // If !sendSuccessful
                    mBuilder.setContentTitle(context.getString(R.string.message_failure));
                    mBuilder.setContentText(notificationMessage);
                }
                  } else { // If notification is present
                    
                  }*/
            }
        }
    }

    private void postSimpleNotification(Context context, String notificationMessage, String messageContent,
            boolean sendSuccessful, ArrayList<String> recipients) {

    }

    public static byte[] getNotifications(Context context, String uri) {
        // TODO: Build out notifications.
        // Disabled because PhotoUri and Photo_Bytes was removed.

        /*        SQLDbHelper mDbHelper = new SQLDbHelper(context);
                SQLiteDatabase db = mDbHelper.getReadableDatabase();
            
                String[] projection = {
            SQLContract.MessageEntry.PHOTO_URI_1,
            SQLContract.MessageEntry.PHOTO_BYTES
                };
            
                // Which row to update, based on the ID
                String selection = SQLContract.MessageEntry.PHOTO_URI_1 + " LIKE ?";
                String[] selectionArgs = { uri };
            
                byte[] notification = null;
            
                try {
        Cursor cursor = db.query(
                SQLContract.MessageEntry.TABLE_NOTIFICATIONS,  // The table to query
                projection,                               // The columns to return
                selection,                                // The columns for the WHERE clause
                selectionArgs,                            // The values for the WHERE clause
                null,                                     // don't group the rows
                null,                                     // don't filter by row groups
                null                                      // The sort order
        );
        if( cursor != null && cursor.moveToFirst() ) {
            cursor.moveToFirst();
            notification = cursor.getBlob(cursor.getColumnIndex
                    (SQLContract.MessageEntry.PHOTO_BYTES));
            
            cursor.close();
        } else {
            Log.e(TAG, "Cursor Empty");
        }
                } catch (Exception e) {
        Log.e(TAG, "SQLException", e);
                }
            
                mDbHelper.close();
            
                if (notification == null) {
        return null;
                } else {
        return notification;
                }*/
        return null;
    }

    /** Marks the specific alarm number as sent and sends a broadcast to home
     * @param context The application context
     * @param notificationMessage The notification message for notification on home screen
     * @param alarmNumber The specific alarm number*/
    private void markAsSent(Context context, String notificationMessage, int alarmNumber) {
        // Set as archived
        SQLUtilities.setAsArchived(context, alarmNumber);
        // Send broadcast to Home
        Intent intent = new Intent("custom-event-name");
        intent.putExtra("alarmNumber", alarmNumber);
        intent.putExtra("notificationMessage", notificationMessage);
        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
    }

    public void createAlarm(Context context, Message message) {
        createAlarm(context, message.getDateTime(), message.getPhoneList(), message.getContent(),
                message.getAlarmNumber(), message.getNameList());
    }

    /** Method to set a new alarm
     * @param context The app context
     * @param timeToSend The Time to send the message (in Calendar format)
     * @param phoneNumberList String Arraylist of phone numbers
     * @param messageContent The content of the message you want to send
     * @param alarmNumber Provide an identifier for the alarm
     * @param nameList The list of names, corresponding with the phone numbers*/
    public void createAlarm(Context context, Calendar timeToSend, ArrayList<String> phoneNumberList,
            String messageContent, int alarmNumber, ArrayList<String> nameList) {
        this.context = context;

        // Creates new alarm
        alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent intentAlarm = new Intent(context, MessageAlarmReceiver.class);

        // Add extras
        Bundle extras = new Bundle();
        extras.putStringArrayList("pNum", phoneNumberList);
        extras.putString("message", messageContent);
        extras.putInt("alarmNumber", alarmNumber);
        extras.putStringArrayList("nameList", nameList);
        intentAlarm.putExtras(extras);

        // Set alarm
        pendingIntent = PendingIntent.getBroadcast(context, alarmNumber, intentAlarm,
                PendingIntent.FLAG_UPDATE_CURRENT);
        alarm.set(AlarmManager.RTC_WAKEUP, timeToSend.getTimeInMillis(), pendingIntent);

        // Enable {@code MessageBootReceiver} to automatically restart the alarm when the
        // device is rebooted.
        ComponentName receiver = new ComponentName(context, MessageBootReceiver.class);
        PackageManager pm = context.getPackageManager();

        pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);

        Log.i(TAG, "createAlarm: Alarm Created. alarmNumber: " + alarmNumber);
    }
    // END_INCLUDE(set_alarm)
}