0

Im new to android programming and Im trying to apply a theme on my flashlight app. The error seems to be when I click on "OK" button when trying to apply one of the two themes.

Here's my code on SimpleNotificationAppActivity.java

public class SimpleNotificationAppActivity extends Activity implements android.content.DialogInterface.OnClickListener{
    private boolean isFlashOn = false;
    private Camera camera;
    //private ImageButton button;
    private Button button;
    private MediaPlayer button2;

    ////////////
    public final static int CREATE_DIALOG  = -1;
    public final static int THEME_HOLO_LIGHT  = 0;
    public final static int THEME_HOLO  = 1;

    int position;
    ///////////////

    @Override
    protected void onStop() {
        super.onStop();

        if (camera != null) {
            camera.release();
        }
    }




    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        //setTheme(android.R.style.Theme_Holo_Light);
        setContentView(R.layout.main);
        button = (Button) findViewById(R.id.buttonFlashlight);
        button2 = MediaPlayer.create(SimpleNotificationAppActivity.this,R.raw.two_tone_nav); //SOM DO CLIQUE
        //button = (ImageButton) findViewById(R.drawable.image_on);
        //button.setBackgroundResource(R.drawable.switch_on);
        Context context = this;
        PackageManager pm = context.getPackageManager();


        if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            Log.e("err", "Device has no camera.");
            Toast.makeText(getApplicationContext(),
                    "Sorry, your device doesn't have camera :(",
                    Toast.LENGTH_SHORT).show();

            return;
        }

        camera = Camera.open();
        final Parameters p = camera.getParameters();

        button.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                if (isFlashOn) {
                    Log.i("info", "torch is turned off!");      
                    button2.start();
                    p.setFlashMode(Parameters.FLASH_MODE_OFF);
                    camera.setParameters(p);                    
                    isFlashOn = false;
                    //button.setText("Torch-ON");
                    button.setBackgroundResource(R.drawable.button_on);
                } else {
                    Log.i("info", "torch is turned on!");
                    button2.start();
                    p.setFlashMode(Parameters.FLASH_MODE_TORCH);
                    camera.setParameters(p);                    
                    isFlashOn = true;
                    //button.setText("Torch-OFF");
                    button.setBackgroundResource(R.drawable.button_off);
                }
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main_activity_actions, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item){
        super.onOptionsItemSelected(item);
        switch(item.getItemId()){
        case R.id.theme:
            themeMenuItem();
            break;
        case R.id.about:
            aboutMenuItem();
            break;
        }
        return true;

        }
    private void aboutMenuItem(){
        new AlertDialog.Builder(this)
        .setTitle("About")
        .setMessage("Flashlight app developed and designed by Rui Moreira.\n\nfacebook.com/RuiSousaMoreira")
        .setNeutralButton("Ok", new DialogInterface.OnClickListener() {


            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub

            }
        })
        .setIcon(R.drawable.app_icon_small)
        .show();
    }

    private void themeMenuItem(){

        //setTheme(android.R.style.Theme_Holo);
        //setTheme(R.layout.main2);
////////////////////////////////////////////////////
position = getIntent().getIntExtra("position", -1);

switch(position)
{
case CREATE_DIALOG:
createDialog();
break;
case THEME_HOLO_LIGHT:
setTheme(android.R.style.Theme_Holo_Light);
break;
case THEME_HOLO:
setTheme(android.R.style.Theme_Holo_Light_DarkActionBar);
break;
default:
}

//super.onCreate(savedInstanceState);
//setContentView(R.layout.main);


////////////////////////////////////////////////////


    }


    private void createDialog()
    {
        /** Options for user to select*/
        String choose[] = {"Holo Light","Holo Dark"};

        AlertDialog.Builder b = new AlertDialog.Builder(this);

        /** Setting a title for the window */
        b.setTitle("Choose your Application Theme");

        /** Setting items to the alert dialog */
        b.setSingleChoiceItems(choose, 0, null);

        /** Setting a positive button and its listener */
        b.setPositiveButton("OK", this);//
        /*TRIED THIS TOO, BUT DOESNT SOLVES THE PROBLEM
         * 
         * b.setPositiveButton("Ok", new DialogInterface.OnClickListener() {


            public void onClick(DialogInterface dialog, int which) {
            ///TESTE

                AlertDialog alert = (AlertDialog)dialog;
                int position = alert.getListView().getCheckedItemPosition();

                finish();
                Intent intent = new Intent();
                intent.putExtra("position", position);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);

                ///TESTE

            }
        });*/

        /** Setting a positive button and its listener */
        b.setNegativeButton("Cancel", null);

        /** Creating the alert dialog window using the builder class */
        AlertDialog d = b.create();

        /** show dialog*/
        d.show();
    }


    public void onClick(DialogInterface dialog, int which) {
        // TODO Auto-generated method stub
        AlertDialog alert = (AlertDialog)dialog;
        int position = alert.getListView().getCheckedItemPosition();

        finish();
        Intent intent = new Intent(this, SimpleNotificationAppActivity.class);
        intent.putExtra("position", position);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);

    }

Basically when i click "Theme" right here: http://i.share.pho.to/64979323_o.png

This dialog shows up: http://i.share.pho.to/302de3a9_o.png

I select the theme, and I want to update app's theme by pressing ok. Can anyone please help me achieving this? I apreciate any suggestion :)

flx
  • 14,146
  • 11
  • 55
  • 70
Rui Moreira
  • 167
  • 2
  • 4
  • 11

2 Answers2

0

As you have tried, setTheme() is the way to change the theme. However,

Note that this should be called before any views are instantiated in the Context (for example before calling setContentView(View) or inflate(int, ViewGroup)).

So, you will have to restart your app. My, possibly dirty, solution would be to kill the Activity and call the main activity of your app with some information in the Intent about what theme must be applied.

An SO User
  • 24,612
  • 35
  • 133
  • 221
0

As Little Child said simply using setTheme() is not working. It should use before setContentView(View). What you have to do is restart your application once press the 'OK' button and then when the application restarts set the new theme by setTheme() (do this before setContentView(View)).

To restart the application after one second you can use this (replace the Activity according to your application):

Intent intent=new Intent (this, MainActivity.class);

AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + 1000, 
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT
                        | PendingIntent.FLAG_CANCEL_CURRENT));
finish();

Here is the example code as I said in comment:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedPreferences shared=getSharedPreferences("app_name", Activity.MODE_PRIVATE);
        String theme=shared.getString("theme", null);
        if(theme != null && theme.equals("LIGHT")){
            setTheme(R.style.Theme_light);
        }else{
            setTheme(R.style.Theme_dark);
        }
            setContentView(R.layout.activity_main);
}
Zusee Weekin
  • 1,348
  • 2
  • 18
  • 41
  • Thank you for the suggestion. I kinda understand the idea but I cant figure out how to setTheme in onCreate(). `public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(?????????); setContentView(R.layout.main); .................` – Rui Moreira Feb 28 '14 at 11:36
  • I cant do setTheme(android.R.style.Theme_Holo_Light_DarkActionBar) because the app will always start with dark theme, instead of the theme that was chosen – Rui Moreira Feb 28 '14 at 11:42
  • In your situation you can save the theme in SharedPreferences which is selected by the user and used that restart code in onclick method of "OK" button. Then inside your onCreate() method in main activity, get that saved theme from SharedPreferences and set it for setTheme(). I will update the answer by adding that part. – Zusee Weekin Mar 02 '14 at 22:51