Reputation: 1173
I have just started learning android. Following code shows my first attempt.
package com.example.silentphone;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity {
private AudioManager audioManager;
private boolean mPhoneIsSilent;
/******I want to declare it here but the app crashes if i do
ImageView imageView = (ImageView) findViewById(R.id.ringer_icon);
Drawable newPhoneIcon;
*******************************/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
checkPhoneStatus();
}
@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, menu);
return true;
}
public void onClick(View view) {
Button toggleButton = (Button) findViewById(R.id.toggleBtn);
if (mPhoneIsSilent) {
System.out.println("Phone Silent");
// now put the phone in ringer mode
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
mPhoneIsSilent = false;
toggleGUI();
} else {
System.out.println("Phone active");
// now put the phone in silent mode
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
mPhoneIsSilent = true;
toggleGUI();
}
}
public void checkPhoneStatus() {
int ringerMode = audioManager.getRingerMode();
if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
// means the phone is silent
mPhoneIsSilent = true;
} else {
mPhoneIsSilent = false;
}
}
public void toggleGUI() {
/******These two variables need to be declared here.Why cant i declare it at class level.If i declare it at class level the app crashes.s****************************/
ImageView imageView = (ImageView) findViewById(R.id.ringer_icon);
Drawable newPhoneIcon;
/******************************************************************************/
if (mPhoneIsSilent) {
// means the phone is silent so show phone silent image
newPhoneIcon = getResources().getDrawable(R.drawable.speaker_off);
imageView.setImageDrawable(newPhoneIcon);
} else {
newPhoneIcon = getResources().getDrawable(R.drawable.phone_on);
imageView.setImageDrawable(newPhoneIcon);
}
}
}
My question is why i need to declare
ImageView imageView = (ImageView) findViewById(R.id.ringer_icon);
Drawable newPhoneIcon;
within the function. Why cant i declare it in class level. App crashes if i declare it in class-level. Every time function toggleGui is called a new object of those two classes is made and that will be ineffective i guess but i may be wrong. Can someone provide me with a good explanation. Thanks.
Upvotes: 0
Views: 278
Reputation: 494
Declare youre variable class level as follows
ImageView imageView;
and initialize it inside oncreate method after setcontentview(R.layout.your_layout);
imageView = (ImageView) findViewById(R.id.ringer_icon);
do not initialize it on toggleGUI() method. because it is never call inside the onCreate().
initialize your all UI elements inside oncreate() method.
Upvotes: 0
Reputation: 141
generally you should create any mutable variables whithin the scope in which they are used -- it's OOP encapsulation/loose coupling/high cohesion concept and I suggest to follow it for many reasons )
You can define them in class level I believe, just make sure they are initialized properly before access them -- the app craches probably because you try to call toggleGUI before imageView defined.
Regards,
Alex.
Upvotes: 0
Reputation: 8134
The declaration in Activity is not a problem.
The findViewById
for your ImageView
should be called after setting your content view. (layout for the activity).
Otherwise, the following should work:
public class MainActivity extends Activity {
private AudioManager audioManager;
private boolean mPhoneIsSilent;
//declaring these here is not a problem
ImageView imageView;
Drawable newPhoneIcon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//when you map the imageView, it should be after the setContentView so your activity identifies exactly what to map - for id and component -in your layout
imageView = (ImageView) findViewById(R.id.ringer_icon);
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
checkPhoneStatus();
}
@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, menu);
return true;
}
public void onClick(View view) {
Button toggleButton = (Button) findViewById(R.id.toggleBtn);
if (mPhoneIsSilent) {
System.out.println("Phone Silent");
// now put the phone in ringer mode
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
mPhoneIsSilent = false;
toggleGUI();
} else {
System.out.println("Phone active");
// now put the phone in silent mode
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
mPhoneIsSilent = true;
toggleGUI();
}
}
public void checkPhoneStatus() {
int ringerMode = audioManager.getRingerMode();
if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
// means the phone is silent
mPhoneIsSilent = true;
} else {
mPhoneIsSilent = false;
}
}
public void toggleGUI() {
if (mPhoneIsSilent) {
// means the phone is silent so show phone silent image
newPhoneIcon = getResources().getDrawable(R.drawable.speaker_off);
imageView.setImageDrawable(newPhoneIcon);
} else {
newPhoneIcon = getResources().getDrawable(R.drawable.phone_on);
imageView.setImageDrawable(newPhoneIcon);
}
}
}
http://developer.android.com/reference/android/app/Activity.html#setContentView(int)
For findViewById:
http://developer.android.com/reference/android/app/Activity.html#findViewById(int)
Upvotes: 2