4
\$\begingroup\$

On the main view, all you see is a button to click on that says, "start setup". Once the user clicks on Start Setup, a file is read in the background and a progress bar is shown in the main thread. Once the "setup" is complete, a "Setup Complete" notification should pop up. After that, some kind of status indicating the battery level or status should display to the user.

Here are my attempts so far. I've included it in a Pastebin. Feel free to ask me if you would like to see the views or something else.

//Main Activity.java

package com.example.Patient_Device;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import java.io.*;


public class MainActivity extends Activity {

    //fields
    private ProgressDialog progressBar;
    private Context context;


    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.start_setup);
        //Set the context
        context = this;

        //Initialize the start setup button and add an onClick event listener to the button
        final Button start_setup_button = (Button) findViewById(R.id.start_setup_button);
        start_setup_button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {

                //Executes the AsyncTask
                new RetrieveInfoTask().execute();

                //Instantiates the intent to launch a new activity
                Intent myIntent = new Intent(MainActivity.this, RetrieveInfoActivity.class);
                MainActivity.this.startActivity(myIntent);

            }
        });
    }

    public class RetrieveInfoTask extends AsyncTask<Void, Void, Void> {

        //Called on the UI thread to execute progress bar
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressBar = new ProgressDialog(context);
            progressBar.setIndeterminate(true);
            progressBar.setCancelable(false);
            progressBar.setMessage(MainActivity.this.getString(R.string.retrieve_info));
            progressBar.show();
        }

        //Methods that retrieves information from the user device. This is performed in the Background thread
        private void retrieveInfo() {

            try {

                //Reading the drawable resource line by line
                String str="";
                StringBuffer buf = new StringBuffer();
                InputStream is = MainActivity.this.getResources().openRawResource(R.drawable.user_info);
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                if (is!=null) {
                    while ((str = reader.readLine()) != null) {
                        buf.append(str + "\n" );
                    }
                }
                is.close();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }


        //doInBackground calls retrieveInfo() to perform action in Background
        @Override
        protected Void doInBackground(Void... params) {

            retrieveInfo();
            return null;
        }

        //When the background task is done, dismiss the progress bar
        @Override
        protected void onPostExecute(Void result) {
            if (progressBar!=null) {
                progressBar.dismiss();
            }
        }


    }
}

//RetrieveInfoActivity.java

package com.example.Patient_Device;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.BatteryManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class RetrieveInfoActivity extends Activity {

    private static String TAG = "RetrieveInfoActivity";
    private Context context;
    String fileLastSync = "09-18-2014 03:47 PM";

   @Override
   public void onCreate(Bundle savedInstanceState) {

            context = this;

            super.onCreate(savedInstanceState);
            setContentView(R.layout.retrieve_info);

            //Once the new activity is launched, the setup is complete
            Toast.makeText(getApplicationContext(), "Setup Complete!",
                    Toast.LENGTH_LONG).show();

            //Gets the 'last synced' string and sets to datetime of the last sync
            Resources resources = context.getResources();
            String syncString = String.format(resources.getString(R.string.last_sync), fileLastSync);

            //Dynamically sets the datetime of the last sync string
            TextView lastSyncTextView = ((TextView) findViewById(R.id.last_sync) );
            lastSyncTextView.setText(syncString);

            //calls registerReceiver to receive the broadcast for the state of battery
            this.registerReceiver(this.mBatInfoReceiver,new
                    IntentFilter(Intent.ACTION_BATTERY_CHANGED));


   }

    private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver()  {

        @Override
        public void onReceive(Context arg0, Intent intent) {

            //Battery level
            int level = intent.getIntExtra("level", 0);

            //Dynamically sets the value of the battery level
            TextView batteryTextView = ((TextView) findViewById(R.id.battery) );
            batteryTextView.setText("Battery Level: " + String.valueOf(level)+ "%");

            //If the battery level drops below 25%, then announce the battery is low
            //TODO: Add 25 to constants file.
            if(level < 25) {

                Toast.makeText(getApplicationContext(), "Low Battery!",
                        Toast.LENGTH_LONG).show();


            }
            //Plugged in Status
            int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);

            //Battery Status
            int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);

            //If the device is charging or contains a full status, it's charging
            boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                    status == BatteryManager.BATTERY_STATUS_FULL;

            //If the device isCharging and plugged in, then show that the battery is charging
            if(isCharging && plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB) {

                Toast.makeText(getApplicationContext(), "Charging.." + String.valueOf(level)+ "%",
                        Toast.LENGTH_LONG).show();

            }else{
                Toast.makeText(getApplicationContext(), "Unplugged!",
                        Toast.LENGTH_LONG).show();
            }


        }

    };

    @Override
    public void onDestroy() {

        try {
            super.onDestroy();
            unregisterReceiver(this.mBatInfoReceiver);
        }
        catch (Exception e) {
            Log.e(RetrieveInfoctivity.TAG, getClass() + " Releasing receivers-" + e.getMessage());
        }

    }

}

//StartSetupActivity.java


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class StartSetupActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


    }
}

//FragmentsActivity.java


import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentsActivity extends Fragment{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        return inflater.inflate(R.layout.main, container, false);
    }
}

How can I better organize and structure my code? How can I make it cleaner? Also, I'm still relatively new to design patterns. Should I get a battery manager or a separate battery class right to handle all the battery notifications on the screen?

I would like advice on what's traditionally used for battery notifications to go off if the phone is charging or unplugged and if the battery level is too low. Should those notifications be done with alert dialogues or toasts?

For the fragments activity, I just want to make my view on portrait and landscape mode. Am I supposed to extend the FragmentsActivity class in the MainActivity class? I'm confused on how to use fragments in my classes so that the view is visible on portrait and landscape on rotation.

Any feedback on Android lifecycle would be great as well.

\$\endgroup\$
2
\$\begingroup\$
    //Methods that retrieves information from the user device. This is performed in the Background thread
    private void retrieveInfo() {

        try {

            //Reading the drawable resource line by line
            String str="";
            StringBuffer buf = new StringBuffer();
            InputStream is = MainActivity.this.getResources().openRawResource(R.drawable.user_info);
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            if (is!=null) {
                while ((str = reader.readLine()) != null) {
                    buf.append(str + "\n" );
                }
            }
            is.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

This method doesn't return any result. You read into a buffer and then you discard it.

Lets say you return the contents of the buffer. Just to give this function some purpose.


This code, whilst involved in multi-threaded code, runs on a single thread. You create a new InputStream, one that you won't share. So the StringBuffer doesn't need to be synchronized. As a result, you can use StringBuilder. It's faster.

For more details on StringBuilder versus StringBuffer, see this Stack Overflow question. https://stackoverflow.com/questions/355089/stringbuilder-and-stringbuffer


Only put in a try statement what you need to put in a try statement.

        try {

            //Reading the drawable resource line by line
            String str="";
            StringBuffer buf = new StringBuffer();
            InputStream is = MainActivity.this.getResources().openRawResource(R.drawable.user_info);
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            if (is!=null) {
                while ((str = reader.readLine()) != null) {
                    buf.append(str + "\n" );
                }
            }
            is.close();

        }

String str is not exceptional, so it goes out of the try statement.
Neither is the buffer.
The InputStream might throw Resources.NotFoundException.
The BufferedReader can throw IOException.

So we get this:

        String str="";
        StringBuffer buf = new StringBuffer();
        try {

            //Reading the drawable resource line by line

            InputStream is = MainActivity.this.getResources().openRawResource(R.drawable.user_info);
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            if (is!=null) {
                while ((str = reader.readLine()) != null) {
                    buf.append(str + "\n" );
                }
            }
            is.close();

        }

And then we only catch that which CAN be thrown

        catch (IOException | Resources.NotFoundException e) {
            e.printStackTrace();
        }

(You might wanna do something sensible with it, like error handling).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.