I need to display in a AlertDialog the following message and show it. using this code I already have done it on this way :
AlertDialog dialog;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.pic_time +
" qntpic" +//This is one variable i must call from a .java called PreviewCamera
R.string.pic +
"time" +//This is one variable i must call from a .java called PreviewCamera
R.string.time);
builder.setPositiveButton(android.R.string.ok, null );
dialog = builder.create();
dialog.show()
but i don't know how to proceed to call this variables, i try already some methods but no results.
This variables are int, and private on PreviewCamera.
Using the information that you guys give it to me, this appear.
This is the solution if maybe someone find the same problem as me
AlertDialog dialog; AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(getResources().getString(R.string.pic_time) +
Integer.parseInt(bdl.getqntpic()) +
getResources().getString(R.string.pic)+
Integer.parseInt(bdl.getTime()) +
getResources().getString(R.string.time));
builder.setPositiveButton(android.R.string.ok, null ); dialog = builder.create(); dialog.show(); }
Is that right? it kind of works.
Thanks!
R.string.pic_time return the id of the resource.
If you want the value of the resource, you have to use getResources().getString(R.string.pic_time) for a String or getResources().getInteger(R.integer.time) for an Integer.
The Integer can be converted to String by use : String.valueOf(yourInt)
You are confusing .xml variables and .java variables.
.XML variables are get with getResources().getString(R.string.pic_time) or getResources().getInt(R.int.pic_time). They are defined inside a .xml file (named only with lowercase letters and underscore) under a folder "res/values". They are set at compiletime and cannot(/shouldn't?) be changed at runtime (afaik).
.java variables are variables set by your java code, inside classes. They are get with references. When you call System.out.println(pic_time);, you get the value of your variable "pic_time" thanks to its reference in memory.
Example : the class MainActivity will get the variable "pic_time" from the class A_Class :
MainActivity.java
public class Accueil extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
A_Class mySecondClass = new A_Class();
int myInt = mySecondClass.getPicTime();
System.out.println(myInt);
}
}
A_Class.java
public class A_Class
{
private int pic_time;
public A_Class()
{
pic_time = 50;
}
public int getPicTime()
{
return pic_time;
}
}
Related
So, I am trying to write text to a file in Android Studio. I have the following code:
public void sampleFunction() {
File file = new File(getExternalFilesDir(null), "sample-file.txt");
}
The issue is that the method getExternalFilesDir(null) cannot be resolved. After doing some research I have noted that I need to provide the Context class. Such as:
public void sampleFunction(Context c) {
File file = new File(c.getExternalFilesDir(null), "equation_history.xml");
}
And when I called sampleFunction, I would simply pass in the current Context:
sampleFunction(this);
This normally would work, however, I need to call this function inside a setOnClickListener function for a Button. For example:
Button b_go = findViewById(R.id.b_go);
b_go.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Functions.sampleFunction(this);
}
});
So the return value for this is android.view.View.OnClickListener rather than android.content.Context.
How might I get around this? Any advice would be greatly appreciated.
Instead of passing "this" as an argument try calling getApplicationContext() or if you are in fragment just call getActivity().
What is often done is that a Context myContext variable is declared in the class, then onCreate, you populate it with myContext = this; Then, in any listener or Async Task, you can use myContext.getExternalFilesDir(null)
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
Outside my onCreate method my stringarray isnt able to be called , why is that ?
I tried to initialize the stringarray again in the method outside onCreate with getResources(); but I cant call that either,
im guessing there is some fundemental knowledge im lacking as im fairly new in the programming world, can u help me or explain why the string array can't be called outside onCreate and/or how to work around it ?
example inside onCreate :
final String[] list = res.getStringArray(R.array.fact);
outside onCreate :
public void facts(){
getResources();
final String[] list = res.getStringArray(R.array.fact);
}// marked res. in red saying "qualifier must be an expression" and without that I cant call "list"..
I believe your issue is variable scope. You've declared your string array in the onCreate() method, giving it "method scope" and then you're tying to access it in another method. I would suggest declaring your string array as a class level variable so that you can access it from any method within that class.
To avoid the NullPointerException issue pointed out by Ben P. in a comment, you could initialize your array variable in the onResume() method so that you have it ready to go before you need to use it anywhere else.
Make sure to take a look at the reference links below the code example. I think they'll help explain "why" better than I can in a quick answer here.
public class MainActivity extends AppCompatActivity {
private static String[] list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
// onResume() runs after onCreate() and onStart() in the Android Activity lifecycle.
// If your array has not been initialized yet, do it now.
if (list == null || list.length == 0) {
list = getResources().getStringArray(R.array.fact);
}
}
public void facts() {
// Do something with your array...
for (String arrayItem : list) {
String fact = arrayItem.toUpperCase();
}
}
}
References:
The Activity Lifecycle: https://developer.android.com/guide/components/activities/activity-lifecycle
Variable scope: https://www.java-made-easy.com/variable-scope.html
Replace
final String[] list = res.getStringArray(R.array.fact);
by
final String[] list = getResources().getStringArray(R.array.fact);
The full text of the error is:
C:\Users\Dov\Google Drive\AndroidStudioProjects\FlagQuiz - Copy (2)\app\src\main\java\com\dslomer64\flagquiz\QuizFragment.java
Error: Fragments should be static such that they can be re-instantiated by the system, and anonymous classes are not static [ValidFragment]
To make it worse, it doesn't tell me which line the error is in. I had assumed, since it was mentioned above, that QuizFragment is at fault, but how? So I then concluded that QuizFragment was mentioned only to indicate which class the error is in.
Also, note that no line is flagged with error as the yellow square shows.
I found the word "anonymous" in 3 places in comments in the incomplete code segment below.
DialogFragment quizResults = new DialogFragment() // anonymously **********
// extend DialogFragment class
{
#Override public Dialog onCreateDialog(Bundle bundle)
{
...
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setPositiveButton
(
R.string.reset_quiz,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
resetQuiz();
}
} // end anonymous inner class *******************
);
return builder.create(); // return the AlertDialog
} // end method onCreateDialog
}; // end DialogFragment anonymous inner class ****************
Is there something wrong (as of AS 2.3.3; nothing was wrong before upgrade) with DialogFragment quizResults = new DialogFragment() or the definition of builder, which contains an anonymous inner class?
If so, why no compilation errors? And in this case, how do I fix the problem?
(I don't want to just start hacking away at code I didn't write [I received project from an author and made many modifications] since there are at least 3 conceivable starting points and maybe none address the error(s?).
nothing was wrong before upgrade
Most likely, there was. Android Studio was not complaining about your code previously, but it may not have worked properly anyway. What changed is that now Android Studio is pointing out the problem, rather than you finding out the hard way in testing.
Is there something wrong... with DialogFragment quizResults = new DialogFragment()
Yes. It's impossible to recreate the fragment.
So, when the user rotates the screen, or changes locale, or night mode kicks in, or any number of other possible configuration changes, when Android destroys the fragment and tries to recreate it, it can't. Only the lines of code in your question can recreate the fragment, and those lines of code are yours, not the framework's, and it doesn't know about them.
It is possible that you have worked around this by blocking the ordinary destroy-and-recreate cycle for the activity, via android:configChanges. That itself is usually an anti-pattern, but if you legitimately need android:configChanges and are using it properly, you should be able to suppress this Lint error.
And in this case, how do I fix the problem?
Create a regular Java class for quizResults, extending DialogFragment and including your code. Then, use that Java class.
The part that is wrong is the following:
DialogFragment quizResults = new DialogFragment() {
#Override
public Dialog onCreateDialog(Bundle bundle) {
where you are defining an anonymous subclass of DialogFragment. This is the wrong way to use Fragments as suggested by the new lint check in Android 2.3.3.
Why? Instantiating Fragments like this will cause problems if you are using an Activity's FragmentManager.
The problematic situation is as follows: when Activity#saveInstanceState(Bundle outState) is called the FragmentManager will attempt to save the state of your Fragment. When subsequently the Activity's state is restored, the FragmentManager will attempt to recreate your Fragments (using no-args constructors) and set their states to the way they were before. This is not possible if you use anonymous subclasses of Fragment.
Henec, Fragments must have a no-args constructor and the preferred way of instantiating them is with static factory methods. Instead of anonymous subclasses, use Fragment#setArguments(Bundle bundle):
inside QuizFragment.java:
public static QuizFragment instantiate(Bundle args) {
QuizFragment frag = new QuizFragment();
frag.setArguments(args);
return frag;
}
I ran into this same problem. I converted the anonymous DialogFragment class into a regular class :
public DialogFragment instantiate(Bundle args){
DialogFragment quizResults = new DialogFragment();
quizResults.setArguments(args);
Dialog aDialog = createDialog(args);
aDialog.show();
return quizResults;
}
// create an AlertDialog and return it
public Dialog createDialog(Bundle bundle){
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setCancelable(false);
builder.setMessage(
getResources().getString(
R.string.results, totalGuesses, (1000 / (double) totalGuesses)));
// "Reset Quiz" Button
builder.setPositiveButton(R.string.reset_quiz,
new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int id)
{
resetQuiz();
}
} // end anonymous inner class
); // end call to setPositiveButton
return builder.create(); // return the AlertDialog
} // end method createDialog
The original code block under onClick(View v):
///////////////////////////////////////////////////////////////////
DialogFragment quizResults = new DialogFragment()
{
// create an AlertDialog and return it
#Override
public Dialog onCreateDialog(Bundle bundle)
{
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setCancelable(false);
builder.setMessage(
getResources().getString(R.string.results, totalGuesses, (1000 / (double) totalGuesses)));
// "Reset Quiz" Button
builder.setPositiveButton(R.string.reset_quiz,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
resetQuiz();
}
} // end anonymous inner class
); // end call to setPositiveButton
return builder.create(); // return the AlertDialog
} // end method onCreateDialog
Was replaced with call to instantiate the DialogFragment as below:
DialogFragment quizResults = instantiate(mSavedInstanceState);
Thanks to #Commonsware and #David Rawson, I managed to make it work with static inner class for myDialogClass by changing anything the compiler griped about to static, which included several methods as well as many (every?) variable.
This posed one problem:
public static void loadNextFlag()
{
...
// display current question number--2nd and 3rd parameters are INPUT into the xml statement
questionNumberTextView.setText
(correctAnswers + 1) + //was ,
"/" + FLAGS_IN_QUIZ);
// AssetManager assets = getActivity().getAssets();
...
} // end method loadNextFlag
The line for formatting questionNumberTextView had to be changed to
questionNumberTextView.setText(
("" + (correctAnswers + 1)
"/" + FLAGS_IN_QUIZ);
because the original
questionNumberTextView.setText(getResources().getString
(R.string.question,
(correctAnswers + 1),
FLAGS_IN_QUIZ);
gave the static vs. non-static error for getResources. I just settled for not as great a format, but suitable.
I also made assets a global static variable to be assigned only once, in onCreateView.
So textbooks don't always do it right, since to do so would raise the level of the text too far above the intended audience.
So I've debugged my program and have found that the part of my program is updating, whilst another isn't.
I have a method:
public void storeApplication(String name, String item){
Application app = new Application(name, item);
peopleAttending.add(app);
}
The debugger reports that an object is contained in the LinkedList (peopleAttending).
In another method:
public void populateListView() {
int noOfPeopleAttending = peopleAttending.size();
String noPeopleAttending = String.valueOf(noOfPeopleAttending);
Toast.makeText(GuestsAttending.this, noPeopleAttending, Toast.LENGTH_SHORT).show();
}
This method can be called after the previous one and states that there isn't an object within the LinkedList.
I've checked the object references just to make sure that they are pointing at the same reference and they are.
Any help would be greatly appreciated.
EDIT: Entire Class:
public class GuestsAttending extends Activity {
private LinkedList<Application> peopleAttending = new LinkedList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_guests_attending);
populateListView();
}
public void storeApplication(String name, String item){
Application app = new Application(name, item);
peopleAttending.add(app);
}
public void populateListView() {
// GuestsAdapter adapter = new GuestsAdapter(this, peopleAttending);
// ListView listView = (ListView) findViewById(R.id.listView);
// listView.setAdapter(adapter);
peopleAttending.size();
int noOfPeopleAttending = peopleAttending.size();
String noPeopleAttending = String.valueOf(noOfPeopleAttending);
Toast.makeText(GuestsAttending.this, noPeopleAttending, Toast.LENGTH_SHORT).show();
}
Second Edit:
Java Booking Screen Method:
public void saveBookingInfo(View view) {
GuestsAttending sendApplication = new GuestsAttending();
EditText applicantNameText = (EditText) findViewById(R.id.applicantNameTextField);
EditText itemToBurnText = (EditText) findViewById(R.id.itemToBurnTextField);
String appName = applicantNameText.getText().toString();
String appItemToBurn = itemToBurnText.getText().toString();
if (appItemToBurn.isEmpty() || appName.isEmpty()) {
Toast.makeText(BookingScreen.this, "Please fill in all fields.", Toast.LENGTH_SHORT).show();
}
else {
sendApplication.storeApplication(appName, appItemToBurn);
}
}
GuestsAttending Java Class: -- See Above.
Useful hint: It's really popular to set type of List as a List<> interface from java.util package instead of LinkedList<> itself.
Anyway, i am pretty sure that storeApplication method is not automatically triggered before onCreate method ran by Activity framework. Maybe your debugger is stopoing on it in different order (because of using threads or smth), but you should to log some invoke. Try to find it out.
I've found out what the problem is:
When I submit the booking information, it runs all the necessary methods. However, when the "storeApplication()" method has finished executing, the ArrayList 'empties' all the objects out.
I only noticed this when I used breakpoint and tried running the method twice, on the second time I entered booking details, the ArrayList stated it was empty.
I'm going to see if I can try and store the ArrayList in a more secure place.
[Update: Thanks to Craigy's suggestion below, I cleaned up my code a little and added 'final' before the string in onTap, and everything works great!]
I'm trying to store a URL (along with a title and snippet) in a custom OverlayItem on my app's mapview. When a user taps on the OverlayItem (in my case, a NewsMapItem), I want a dialog to pop up with the title and description. Below that, there are 'Open' and 'Dismiss' buttons. When the user taps the Open button, I'd like to access a URL stored in the NewsMapItem and load that in a WebView.
Please see the relevant code snippets below:
NewsMapItem - where I'd like to add in a link (in addition to the point, title, and snippet provided by the default OverlayItem class).
private class NewsMapItem extends OverlayItem {
private String mLink;
public NewsMapItem(GeoPoint point, String title, String snippet, String mLink) {
super(point, title, snippet);
this.mLink = mLink;
}
public String getLink() {
return mLink;
}
}
onTap override (inside my class extending ItemizedOverlay):
#Override
protected boolean onTap(int index) {
NewsMapItem item = overlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
// Added the line below...
final String url = item.getLink();
dialog.setCancelable(true);
dialog.setPositiveButton(R.string.mapview_open, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Removed this call...
// String url = item.getLink();
Intent showContent = new Intent(getApplicationContext(), JJGWebViewActivity.class);
showContent.setData(Uri.parse(url));
startActivity(showContent);
}
});
dialog.setNegativeButton(R.string.mapview_dismiss, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
dialog.show();
return true;
}
The item accessors are underlined in red, and Eclipse tells me "Cannot refer to a non-final variable item inside an inner class defined in a different method."
Any help, or is there a better way to do what I'm trying?
For simplicity's sake, I could not display the snippet at all, and store the URL in there, but I'd like to show a title and description in the dialog, so the user can choose whether or not to open a story more easily.
You can only access variables from an inner class in Java if the variables are declared as final (making them constants). More information
Cannot refer to a non-final variable inside an inner class defined in a different method
so try putting final in front of the declaration of the variables it complains about, or use the Eclipse code-complete to do it for you.