4
\$\begingroup\$

I'm happy to present my first Android project, which collects market index data (three Asian indices) and fires a notificaiton every Wednesday, Thursday and Friday at 7:30 AM displaying the data.

I've applied to Computer Science in Lund, Sweden. I am looking to improve my Java through Android development (which I've found particularly interesting).

Please consider giving some feedback. I'll be happy with anything!

MainActivity:

public class MainActivity extends AppCompatActivity {
 public static final String CHANNEL_ID = "com.example.morgonnotification.channel";
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 createNotificationChannel();
 ReminderReceiver.setNextNotification(this);
 }
 private void createNotificationChannel() {
 NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Index Channel", NotificationManager.IMPORTANCE_HIGH);
 NotificationManagerCompat.from(this).createNotificationChannel(channel);
 }
}

ReminderReceiver (BroadcastReceiver):

public class ReminderReceiver extends BroadcastReceiver {
 public static void setNextNotification(Context context) {
 AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
 Intent intent = new Intent(context, ReminderReceiver.class);
 PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
 ZonedDateTime fireTime = ZonedDateTime.now(ZoneId.of("Europe/Stockholm")).withHour(7).withMinute(30).withSecond(0);
 long nowEpochSecond = ZonedDateTime.now(ZoneId.of("Europe/Stockholm")).toEpochSecond();
 long fireTimeEpochSecond = fireTime.toEpochSecond();
 DayOfWeek day = fireTime.getDayOfWeek();
 switch (day.name()) {
 case "WEDNESDAY":
 //before 7:30 on a wednesday? Set alarm to this Wednesday morning
 fireTime = (nowEpochSecond < fireTimeEpochSecond) ? fireTime :
 fireTime.with(TemporalAdjusters.next(DayOfWeek.THURSDAY));
 break;
 case "THURSDAY":
 //before 7:30 on a Thursday? Set alarm to this Thursday morning
 fireTime = (nowEpochSecond < fireTimeEpochSecond) ? fireTime :
 fireTime.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
 break;
 case "FRIDAY":
 //before 7:30 on a Friday? Set alarm to this Friday morning
 fireTime = (nowEpochSecond < fireTimeEpochSecond) ? fireTime :
 fireTime.with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY));
 break;
 default:
 fireTime = fireTime.with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY));
 break;
 }
 if (alarmManager != null)
 alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
 fireTime.toInstant().toEpochMilli(), alarmIntent);
 }
 @Override
 public void onReceive(Context context, Intent intent) {
 if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction()) ||
 "android.intent.action.QUICKBOOT_POWERON".equals(intent.getAction()) ||
 intent.getAction() == null) {
 setNextNotification(context);
 }
 StringBuilder indicesBuilder = new StringBuilder();
 Thread thread = new Thread(() -> {
 try {
 Document doc = Jsoup.connect("https://money.cnn.com/data/world_markets/asia//").get();
 Elements nikkei = doc.select("#wsod_indexDataTableGrid > tbody > tr:nth-child(6) > td:nth-child(5) > span > span");
 indicesBuilder.append("N: ").append(nikkei.text()).append(", ");
 Elements shanghaiComposite = doc.select("#wsod_indexDataTableGrid > tbody > tr:nth-child(3) > td:nth-child(5) > span > span");
 indicesBuilder.append(" S: ").append(shanghaiComposite.text()).append(", ");
 Elements hangSeng = doc.select("#wsod_indexDataTableGrid > tbody > tr:nth-child(4) > td:nth-child(5) > span > span");
 indicesBuilder.append(" H: ").append(hangSeng.text());
 } catch (Exception e) {
 indicesBuilder.append("Something went terribly wrong");
 e.printStackTrace();
 } finally {
 Notification notification = new NotificationCompat.Builder(context, MainActivity.CHANNEL_ID)
 .setSmallIcon(R.drawable.ic_index)
 .setContentTitle("Morning indices")
 .setPriority(NotificationCompat.PRIORITY_HIGH)
 .setStyle(new NotificationCompat.BigTextStyle().bigText(indicessBuilder)).build();
 NotificationManagerCompat manager = NotificationManagerCompat.from(context);
 manager.notify(1, notification);
 indicesBuilder.setLength(0);
 }
 });
 thread.start();
 }
}

XML File:

<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
 android:allowBackup="true"
 android:icon="@mipmap/ic_launcher"
 android:label="@string/app_name"
 android:roundIcon="@mipmap/ic_launcher_round"
 android:supportsRtl="true"
 android:theme="@style/AppTheme">
 <receiver
 android:name=".ReminderReceiver"
 android:enabled="true"
 android:exported="true">
 <intent-filter >
 <action android:name="android.intent.action.BOOT_COMPLETED" />
 <action android:name="android.intent.action.QUICKBOOT_POWERON" />
 </intent-filter>
 </receiver>
 <activity android:name=".MainActivity">
 <intent-filter>
 <action android:name="android.intent.action.MAIN" />
 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>
</application>
asked Apr 29, 2020 at 21:04
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Welcome to Code Review. Your code seems me well structured, I have two suggestions for you:

switch (day.name()) {
 case "WEDNESDAY":
 //before 7:30 on a wednesday? Set alarm to this Wednesday morning
 fireTime = (nowEpochSecond < fireTimeEpochSecond) ? fireTime :
 fireTime.with(TemporalAdjusters.next(DayOfWeek.THURSDAY));
 break;
 case "THURSDAY":
 //before 7:30 on a Thursday? Set alarm to this Thursday morning
 fireTime = (nowEpochSecond < fireTimeEpochSecond) ? fireTime :
 fireTime.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
 break;
 case "FRIDAY":
 //before 7:30 on a Friday? Set alarm to this Friday morning
 fireTime = (nowEpochSecond < fireTimeEpochSecond) ? fireTime :
 fireTime.with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY));
 break;
 default:
 fireTime = fireTime.with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY));
 break;
}

There is code repetition and you have a binary association between one day and another one, so you could create a Map to reduce your code lines like below:

//creation of one map for the days
Map<String, String> map = new HashMap<String, String>();
map.put("WEDNESDAY", "THURSDAY");
map.put("THURSDAY" , "FRIDAY");
map.put("FRIDAY" , "WEDNESDAY");
//here the code instead of your switch
DayOfWeek day = fireTime.getDayOfWeek();
String name = day.name();
if (map.containsKey(name)) {
 fireTime = (nowEpochSecond < fireTimeEpochSecond) ? fireTime :
 fireTime.with(TemporalAdjusters.next(DayOfWeek.valueOf(map.get(name))));
} else {
 //default value of your switch
 fireTime = fireTime.with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY));
}

About the following lines in your jsoup code :

StringBuilder indicesBuilder = new StringBuilder();
indicesBuilder.append("N: ").append(nikkei.text()).append(", ");
indicesBuilder.append(" S: ").append(shanghaiComposite.text()).append(", ");
indicesBuilder.append(" H: ").append(hangSeng.text());

You can obtain the same result not going crazy about data format when you add or delete new indices using StringJoiner class:

StringJoiner sj = new StringJoiner(", ");
sj.add("N: " + nikkei.text());
sj.add("S: " + shanghaiComposite.text());
sj.add("H: " + hangSeng.text());
String bigText = sj.toString(); //<-- the string you can use later in your code.
answered Apr 30, 2020 at 9:25
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.