Android send data to broadcast receiver

Viewed 106

I am creating an Android app that notify the users when they received a SMS from selected numbers using Foreground Service. The program only notify the user when the Service is running. My Main Activity has 3 buttons: Start Service, Stop Service and Setting which lead to another Activity that let the user change their information such as password and selected number. Currently the application can read and write data to JSON fine and the data get pass to other activities through Intent, also the Broadcast Receiver for detecting SMS also work when a message in received, and since I want it to work with Foreground Service, I register it in onStartCommand and unregister it in onDestroy in the Service and not register it in Manifest. My problem is on how to pass the user data to the Broadcast Receiver, since it is register to listen to android.provider.Telephony.SMS_RECEIVED and when I try to pass Intent to it through sentBroadcast() in my Service, it does not receive any value of the user. I tried to settle in making the user public static and it worked, but not sure if this the right way to do it. Here is my current code:

MainActivity.java

Button btnStartService, btnStopService;
    TextView lblStatus;
    JSONHandler jsonHandler;//for handling JSON file and data
    public static User user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnStartService = findViewById(R.id.buttonStartService);
        btnStopService = findViewById(R.id.buttonStopService);
        jsonHandler = new JSONHandler(this);

        boolean isFilePresent = isFilePresent(this, "user.json");
        if(isFilePresent) {
            try {
                user = jsonHandler.readFromFile();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        } else {
            user = new User();
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestSmsPermission();
            requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE,READ_EXTERNAL_STORAGE}, 1);
        }
        else {
            startService();
        }
    }

    public boolean isFilePresent(Context context, String fileName) {
        String path = context.getFilesDir().getAbsolutePath() + "/" + fileName;
        File file = new File(path);
        return file.exists();
    }

    public void setBtnStartService(View view)
    {
        startService();
    }

    public void setBtnStopService(View view)
    {
        stopService();
    }

    public void startService() {
        Intent serviceIntent = new Intent(this, ForegroundService.class);
        serviceIntent.putExtra("inputExtra", "Message Service is running");
        serviceIntent.putExtra("user", user);
        ContextCompat.startForegroundService(this, serviceIntent);
        Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
    }

    public void stopService() {
        Intent serviceIntent = new Intent(this, ForegroundService.class);
        stopService(serviceIntent);
        Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
    }

    public void setBtnSetting(View view) {
        Intent intent = new Intent(this, AuthenticateActivity.class);
        intent.putExtra("user", user);
        intent.putExtra("action", "setting");
        startActivity(intent);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            startService();
        }
    }

    private void requestSmsPermission() {
        String permission = Manifest.permission.RECEIVE_SMS;
        int grant = ContextCompat.checkSelfPermission(this, permission);
        if ( grant != PackageManager.PERMISSION_GRANTED) {
            String[] permission_list = new String[1];
            permission_list[0] = permission;
            ActivityCompat.requestPermissions(this, permission_list, 1);
        }
    }

ForegroundService.java

public class ForegroundService extends Service {
    public static final String CHANNEL_ID = "ForegroundServiceChannel";
    SMSReceiver smsListener;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String input = intent.getStringExtra("inputExtra");
        User user = (User) intent.getSerializableExtra("user");
        createNotificationChannel();
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service")
                .setContentText(input)
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setContentIntent(pendingIntent)
                .build();

        startForeground(1, notification);

        //do heavy work on a background thread
        if(smsListener == null)
        {
            smsListener = new SMSReceiver();
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
            Intent i = new Intent(this, SMSReceiver.class);
            i.putExtra("user", user);
            sendBroadcast(i);
            registerReceiver(smsListener, intentFilter);
        }
        //stopSelf();

        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if(null!=smsListener)
        {
            unregisterReceiver(smsListener);
            smsListener = null;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel serviceChannel = new NotificationChannel(
                    CHANNEL_ID,
                    "Foreground Service Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
            );

            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(serviceChannel);
        }
    }
}

SMSReceiver.java

public class SMSReceiver extends BroadcastReceiver {
    private String msgBody;
    private String text = "";
    private SharedPreferences preferences;
    private String sender = "";

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        // User user = (User) intent.getExtras().getSerializable("user"); not working
        User user = MainActivity.user;
        ArrayList<String> banks = user.getBankList();
        if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {

            Toast.makeText(context, "message received", Toast.LENGTH_SHORT).show();

            Bundle bundle = intent.getExtras();

            try {
                if (bundle != null) {
                    final Object[] pdus = (Object[]) bundle.get("pdus");
                    SmsMessage smsMessage;
                    for (int i = 0; i < pdus.length; i++) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
                            smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i], bundle.getString("format"));
                        else smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
                        msgBody = smsMessage.getMessageBody();
                        sender = smsMessage.getOriginatingAddress();
                        if(banks.contains(sender)) {
                            if (msgBody.contains(user.getPattern())) {
                                String[] tokens = msgBody.split(" ");
                                for (int j = 0; j < tokens.length; j++) {
                                    if (tokens[j].contains("API")) {
                                        text = tokens[j];
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    //MainActivity.message = msgBody;
                    if(!text.isEmpty()) {
                        Toast.makeText(context, "message is: " + text, Toast.LENGTH_SHORT).show();
                    }
                }
            } catch (Exception e) {
                Log.d("Exception caught", e.getMessage());
            }
        }
        else {
            Log.i("cs.fsu", "smsReceiver : NULL");
        }
    }
}

Is this the right way to maintain user data throughout the application lifecycle? By making public static for every class accessible? Or is there away to pass it through Intent? Please help me out

0 Answers
Related