1

I'm new to android development and I am creating an android application that works like "4 Pics 1 Word" for my project. I'm having difficulties in storing ArrayList in SharedPreferences or in the internal storage of the android phone. The reason why is because I am randomizing the next activity using random generator and ArrayList. Any suggestions or ideas that my help my case? Thank you in advance! I've been stuck here for hours now.

This is my MainActivity

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

Button btnStart;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button btnStart = (Button) findViewById(R.id.btnStart);
    btnStart.setOnClickListener(this);
}

@Override
        public void onClick(View v) {
            // We are creating a list, which will store the activities that haven't been opened yet
            ArrayList<Class> activityList = new ArrayList<>();
            activityList.add(first.class);
            activityList.add(second.class);
            activityList.add(third.class);
            activityList.add(fourth.class);
            activityList.add(fifth.class);

            Random generator = new Random();
            int number = generator.nextInt(5) + 1;

            Class activity = null;

            // Here, we are checking to see what the output of the random was
            switch(number) {
                case 1:
                    activity = first.class;
                    // We are adding the number of the activity to the list
                    activityList.remove(first.class);
                    break;
                case 2:
                    activity = second.class;
                    activityList.remove(second.class);
                    break;
                case 3:
                    activity = third.class;
                    activityList.remove(third.class);
                    break;
                case 4:
                    activity = fourth.class;
                    activityList.remove(fourth.class);
                    break;
                default:
                    activity = fifth.class;
                    activityList.remove(fifth.class);
                    break;
            }
            // We use intents to start activities
            Intent intent = new Intent(getBaseContext(), activity);
            // `intent.putExtra(...)` is used to pass on extra information to the next activity
            intent.putExtra("ACTIVITY_LIST", activityList);
            startActivity(intent);
        }
    }

And here's my first activity:

public class first extends AppCompatActivity implements View.OnClickListener{
EditText etAnswer;
Button btnGo;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_first);
    etAnswer = (EditText) findViewById(R.id.etAnswer);
    btnGo = (Button) findViewById(R.id.btnGo);
    btnGo.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    switch(v.getId()){
        case R.id.btnGo:
            String answer = etAnswer.getText().toString();
            if(answer.equals("Jose Rizal") ||  answer.equals("jose rizal") || answer.equals("Rizal") || answer.equals("rizal") ){
                AlertDialog.Builder dlgAlert  = new AlertDialog.Builder(this);
                dlgAlert.setMessage("The famous Rizal monument in Luneta was not the work of a Filipino but a Swiss sculptor named Richard Kissling?" +
                        "Source: http://www.joserizal.ph/ta01.html");
                dlgAlert.setTitle("Did you know that ...");
                dlgAlert.setPositiveButton("Next",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                ArrayList<Class> activityList = new ArrayList<>();
                                Bundle extras = getIntent().getExtras();
                                activityList = (ArrayList<Class>) extras.get("ACTIVITY_LIST");

                                if(activityList.size() == 0) {
                                    Context context = getApplicationContext();
                                    CharSequence last = "Congratulations! You just finished the game! Please wait for the next update!";
                                    int durationFinal = Toast.LENGTH_LONG;

                                    Toast toast = Toast.makeText(context, last, durationFinal);
                                    toast.show();
                                } else {
                                    // Now, the random number is generated between 1 and however many
                                    // activities we have remaining
                                    Random generator = new Random();
                                    int number = generator.nextInt(activityList.size()) + 1;

                                    Class activity = null;

                                    // Here, we are checking to see what the output of the random was
                                    switch(number) {
                                        case 1:
                                            // We will open the first remaining activity of the list
                                            activity = activityList.get(0);
                                            // We will now remove that activity from the list
                                            activityList.remove(0);
                                            break;
                                        case 2:
                                            // We will open the second remaining activity of the list
                                            activity = activityList.get(1);
                                            activityList.remove(1);
                                            break;
                                        case 3:
                                            // We will open the third remaining activity of the list
                                            activity = activityList.get(2);
                                            activityList.remove(2);
                                            break;
                                        case 4:
                                            // We will open the fourth remaining activity of the list
                                            activity = activityList.get(3);
                                            activityList.remove(3);
                                            break;
                                        default:
                                            // We will open the fifth remaining activity of the list
                                            activity = activityList.get(4);
                                            activityList.remove(4);
                                            break;
                                    }

                                    // Note: in the above, we might not have 3 remaining activities, for example,
                                    // but it doesn't matter because that case wouldn't be called anyway,
                                    // as we have already decided that the number would be between 1 and the number of
                                    // activities left.


                                    // Starting the activity, and passing on the remaining number of activities
                                    // to the next one that is opened
                                    Intent intent = new Intent(getBaseContext(), activity);
                                    intent.putExtra("ACTIVITY_LIST", activityList);
                                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                                    startActivity(intent);
                                }
                            }
                        });
                dlgAlert.setCancelable(true);
                dlgAlert.create().show();

            }else{
                Context context = getApplicationContext();
                CharSequence text = "Wrong! Try Again.";
                int duration = Toast.LENGTH_SHORT;

                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
            }
            break;
    }
}

}

  • Did you take a look at this :http://stackoverflow.com/questions/7057845/save-arraylist-to-sharedpreferences#7057858 – Moien.Dev Mar 07 '17 at 14:58
  • @MCZ yes, unfortunately the "set" only works for String and not on class. I used that earlier and I got the error in scoreEditor.putStringSet("key", set); – Marlon Mendoza Mar 07 '17 at 15:02
  • Why are you changing activities? If you just want to change the question that's being displayed according to a random int, you should use a DB or network data source to get your new question. – npace Mar 07 '17 at 15:04
  • @npace yeah about that I'm new to android studio and I'm not good at changing the xml files and/or using local db. So I found a way to just use activities since I only have to do 25 activities (25 levels) – Marlon Mendoza Mar 07 '17 at 15:06
  • @MarlonMendoza I suggest you look at some more beginner tutorials before continuing with this approach. It's really hacky and there are much better ways of getting the same result. – npace Mar 07 '17 at 15:07
  • @npace thank you but I am so close to finishing this. This is my last problem. Storing the progress. – Marlon Mendoza Mar 07 '17 at 15:10
  • check this link http://stackoverflow.com/questions/14981233/android-arraylist-of-custom-objects-save-to-sharedpreferences-serializable – Lovekush Vishwakarma Mar 07 '17 at 16:02
  • @LovekushVishwakarma thank you! I'll try that. Hope it works! – Marlon Mendoza Mar 07 '17 at 16:18

1 Answers1

0

Okay, this is a horrible hack and I don't endorse it in any way, but since you are so close to finishing your app, I propose a workaround:

Instead of storing an ArrayList<Class> in your SharedPreferences (which is impossible), store a HashSet<String> containing the fully qualified names of your classes via putStringSet().

In order to get the String representations of the fully qualified names of your classes you need to call getName(), e.g. first.class.getName().

Then, you can get your Set<String> from SharedPreferences using getStringSet() and create a Class instance for each String in that set via Class.forName().

npace
  • 4,218
  • 1
  • 25
  • 35
  • Thank you so much! I will try that. I really appreciated it. – Marlon Mendoza Mar 07 '17 at 15:29
  • Let me know if it works, I'm not sure which version of `Class.forName()` you should use when dealing with `Activities` - the one with a single parameter or the one with three params. – npace Mar 07 '17 at 15:33
  • I actually don't know how to do that but I got the idea so I will try to learn to do that. Thank you! – Marlon Mendoza Mar 07 '17 at 15:34