[Q] Parsing XML from web into ListView - Java for Android App Development

Hey guys,
I've been making an app for my ROM (SkyDragon) and I want to include a news section, which will retrieve info from the web using a XML file.
But, I've tried many things and they won't work. So could anyone post a quick working parsing code here that will put the items in a listview, so I can experiment a bit with it? It'd be widely appreciated

I might reccommend using a library like Jackson 2.0+. I have not had the experience to use it with XML, but rather JSON, but it does appear to be just as easy to do so (at least since 2.0).
You would set up a POJO (Plain Old Java Object) class to represent the structure of the xml data, for instance:
Code:
public class Simple
{
private int x, y;
public int getX(){ return x; }
public int getY(){ return y; }
public void setX(int x){ this.x = x; }
public void setY(int y){ this.y = y; }
}
would represent xml like:
Code:
<Simple>
<x>1</x>
<y>2</y>
</Simple>
and to build the object you would use the library as such:
Code:
ObjectMapper xmlMapper = new XmlMapper();
Simple value = xmlMapper.readValue("<Simple><x>1</x><y>2</y></Simple>", Simple.class);

Thanks, will try it. But it can't be that simple, right? I mean, every tutorial is pretty big, and uses multiple activities.
Sent from my awesome fridge

Well like I said, I haven't actually used it for XML but rather JSON, but it really was that simple for me. What I listed is of course a very simple example, but scaling it up really just requires mapping your xml source to a POJO. The hardest part about your use will be that you don't control the XML.
Here is an example right out of a project of mine that worked great. "request.result" was basically a String object that contained the JSON response from a restful web service that I did not control but knew the structure of (by examination). Truly it is just these 2 lines of code to parse the response and after that you have an object that is easy to use.
Code:
ObjectMapper mapper = new ObjectMapper();
inventory = mapper.readValue(request.result, PlayerInventory.class);
Unfortunately this service no longer exists so I cannot get you an example response, but below is the POJO that I used to map it.
Code:
package com.mcdermotsoft;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class PlayerInventory
{
private int ok;
private Map<String,Slot> contents;
public PlayerInventory(){}
public int getOk() {
return ok;
}
public Map<String,Slot> getContents() {
return contents;
}
public void setOk(int ok) {
this.ok = ok;
}
public void setContents(Map<String,Slot> contents) {
this.contents = contents;
}
}
"@JsonIgnoreProperties(ignoreUnknown = true)" is important because I really didn't care to map everything from the response so this annotation tells the Jackson parser to ignore anything it can't map instead of throwing an exception (don't remember what the exception is but you might run into it yourself).

Related

Application Request for Weight Watchers Points Calculator

Can someone make a .cab or an .exe program to calculate Weight Watchers points? I found this article on the internet where it looks like someone as already done it but they did not post it. Here is the article
http://geekswithblogs.net/cdahlinge...-mobile-meets-weight-watchers--mvp-style.aspx
Craig Dahlinger
<< Presenting at Richdmond code camp 2008.2 | Home | mshtml – the ongoing adventure >> windows mobile meets weight watchers : MVP style Ok, so I know it has been a long time since a post, but it has been really busy with work and family. I have been busy coding and learning lots of new stuff. I work with a great bunch of developers and my current team lead is a great mentor.
Well for the new year the wife and I decided to get back into shape. I started hitting the gym and so did she but she is also doing weight watchers with a friend. One of the things they do is they have to calculate points on a daily basis. These points are comprised of calories, fat and fiber. There is a formula for these three which in turn results in the number of points a particular item is. A few months ago I convinced the wife to get a windows mobile device (woo hoo!) and she is a good power user. So one night she asks me, β€œIs there a way I can just enter in the calories, fat and fiber on my phone and it tell me how many points something is?”. I did some searching and there are numerous online versions of the calculator but no native ones for windows mobile. I found the formula here, and started to get to work.
I wanted to approach this application using the MVP design pattern. I know it may be overkill for this simple of an application but I thought it would be good practice.
I started with the interface for the data model, in this case it would be the main caloric properties of food.
namespace WWPC.Common.Interfaces{ public interface IFoodModel { int Fiber { get; set; } int Calories { get; set; } float Fat { get; set; } int Points { get; set; } int CalculatePoints(); }}I then wrote up the interface for the view for the model.
namespace WWPC.Common.Interfaces{ public interface IFoodCalcView { int Calories { get; } int Fiber { get; } float Fat { get; } int Points { set; } event EventHandler DataChanged; }}Next, came the interface for the presenter.
public interface IFoodCalcPresenter { void OnCalculatePoints(); }
Ok, now that I got my main interfaces in place, time to code up the implementation. I started with the model first since this was the class that would provide the implementation for calculating the caloric points. Using the formula mentioned above, the CalculatePoints() method came out like so:
public int CalculatePoints(){ var calories = Convert.ToDecimal(Calories); var cal = calories / 50; var totalFat = Convert.ToDecimal(Fat); var fat = totalFat / 12; var fiber = Convert.ToDecimal(Fiber); return Points = Convert.ToInt32(Math.Round(cal + fat - (fiber/5), 0)); } With the model complete, I then moved to the presenter. The presenter would be responsible for binding the model to the view responding to the data changes in the view and rebinding those changes to the model. I made the presenter with an overloaded constructor to take a view and a model. The presenter then binds to the data changed event on the view which enables the presenter to update the model from the view. The OnCalculatePoints() method will update the view with the points value after using the model for calculation.
namespace WWPC.Common{ public class FoodPresenter : IFoodCalcPresenter { private readonly IFoodCalcView _View; private readonly IFoodModel _Model; public FoodPresenter(IFoodCalcView view, IFoodModel model) { _View = view; _View.DataChanged += new EventHandler(_View_DataChanged); _Model = model; } void _View_DataChanged(object sender, EventArgs e) { SetModelFromView(); } private void SetModelFromView() { _Model.Calories = _View.Calories; _Model.Fat = _View.Fat; _Model.Fiber = _View.Fiber; } #region IFoodCalcPresenter Members public void OnCalculatePoints() { _View.Points = _Model.CalculatePoints(); } #endregion }}
With the presenter done it was time to implement the view. I wanted a simple mobile form where you can enter in data quickly and then calculate the results. I initially tried using a label to display the result, but did not like it. I then tried a mobile gauge control, but that took up too much space on the small screen. Finally I decided to use the notification class for windows mobile. I did not use the managed wrapper version, I used the the version created by Christopher Fairbairn, found here. This version has an awesome implementation which exposes many features of the notification class. I wanted to give the user the ability to dismiss the notification when they were done reading the results. Also using the notification class the UI was able show the needed text boxes for entry and the SIP panel along with the results without needing to scroll the screen. Here is a screen shot of the main form.
Now with the controls in place on the form, I can implement the view. The form creates a new presenter and passed into it a new model during construction. When the calculate menu option is clicked the main form raises the data changed event then calls the OnCalculateMethod on the presenter. When the presenter binds the model to the view, during the set of the points value, the notification is shown to the user via the ShowNotification method.
namespace WWPC.Calc{ public partial class WWPCalculator : Form, IFoodCalcView { private readonly FoodPresenter _Presenter; private NotificationWithSoftKeys _Notification; public WWPCalculator() { InitializeComponent(); _Presenter = new FoodPresenter(this,new FoodModel()); } public int Calories { get { return (string.IsNullOrEmpty(txtCalories.Text)) ? 0 : Int32.Parse(txtCalories.Text); } } public int Fiber { get { return (cmbFiber.Text == "4 or more") ? 4 : (string.IsNullOrEmpty(cmbFiber.Text)) ? 0 :Int32.Parse(cmbFiber.Text); } } public float Fat { get { return (string.IsNullOrEmpty(txtFat.Text)) ? 0 : float.Parse(txtFat.Text); } } public int Points { set { ShowPointsNotification(value); } } public event EventHandler DataChanged; private void mnuExit_Click(object sender, EventArgs e) { this.Close(); } private void mnuCalculate_Click(object sender, EventArgs e) { if (DataChanged != null) this.DataChanged(sender, e); _Presenter.OnCalculatePoints(); } private void mnuClear_Click(object sender, EventArgs e) { txtCalories.Text = string.Empty; txtFat.Text = string.Empty; cmbFiber.Text = "0"; } private void ShowPointsNotification(int points) { _Notification = new NotificationWithSoftKeys { Text = String.Format("Total Points:{0}", points), Caption = "Weight Watchers Point Calculator", RightSoftKey = new NotificationSoftKey(SoftKeyType.Dismiss, "Dismiss"), }; _Notification.RightSoftKeyClick+=new EventHandler(_Notification_RightSoftKeyClick); _Notification.Visible = true; } void _Notification_RightSoftKeyClick(object sender, EventArgs e) { if (_Notification == null) return; _Notification.Visible = false; _Notification = null; } }}
Now, when it is all put together, it looks like so.
Below is a link to the source code. The project was done using Visual Studio 2008 against the windows mobile 5 sdk. It will also work against windows mobile 6 sdk, I just chose version 5 since that is the common sdk. Thanks for reading!!

[Q] Why cant I call a method from another class?

I have 2 classes in one .java file and it runs fine without errors or anything (the second class is used as a timer and changes variables every second) everything works but it wont call methods properly. Any idea of why this would be??? Heres my code of the second class.
Code:
class MyTime extends TimerTask{
//java.text.DateFormat format = SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, Locale.getDefault());
public game timecall2= new game();
public MyTime(Context ctx) {
// create internal instance
Context ctx2;
}
@Override
public void run() {
game.sec--;
if(game.sec==-1){game.sec=59;game.min--;}
game.Title2(); // set text in title bar
}
}
It would be easier if you explain more cleary, what you want to do.
Or post more code.
public game timecall2= new game();
I think, game is your first class?
Then you want to use the variable sec of the class game?
-> are they declared as static or why you don't call it over the object timecall2 you created?
Sry, but without more Code/Information to unterstand your problem, it's difficult to help. Also don't know, how skilled your are in programming.
*game* is the first class
I've tried calling the method through *timecall2* object but it doesn't help.
I've tried declaring the function as both static and no-static but nothing seems to change.
I've got lots of programming experience in other languages, but I'm less experienced with Java
And what's going wrong now?
Why don't you debug trough the code. Should be the easiest ways to find the problem.
You generally should use getters and setters for accessing variables inside of another class. Meaning that you have a method to set the value of the variable and a method to retrieve the value
Code:
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MyClass extends Activity {
private static int mMin = 0;
private static int mSec = 0;
private TextView titleText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView titleText = (TextView) findViewById(R.id.titleText);
}
public static int getSec() {
return mSec;
}
public static void setSec(int newVal) {
mSec = newVal;
}
public static int getMin() {
return mMin;
}
public static void setMin(int newVal) {
mMin = newVal;
}
public static void setTitleText(String newVal) {
if (titleText != null) {
titleText.setText(newVal);
}
}
}
Notice the "static" modifier of the class methods.
Generally, you wouldn't instantiate this activity class. Especially if it already lives in memory. What I am guessing that you are doing here is that "game" is your activity and that MyTime is an object that you are using from inside of the activity and that you need to modify variables that live in the main Activity.
If that is the case then you would just do something like this:
Code:
import java.util.TimerTask;
import com.myapp.game.MyActivity;
class MyTime extends TimerTask {
private int sec = 0;
private int min = 0;
@Override
public void run() {
sec = MyActivity.getSec();
min = MyActivity.getMin();
sec--;
if(sec==-1) {
sec=59;
min--;
}
String title = String.valueOf(min)+":"+String.valueOf(sec); //obviously you need formatting
MyActivity.SetTitle(title); // set text in title bar
MyActivity.setSec(sec);
MyActivity.setMin(min);
}
}
That said... I just did the above as an example. This is entirely the wrong way to make a game timer. There is a better example here
From what I remember from C++, you would have a "base" class and then other classes beneath that base class.
To use the base class methods, the other classes had to be "friends". I'm a little rusty on my JAVA syntax...is "extends" the same thing as a friend class?
Java doesn't have friend functions, and "extends" means that the class is a subclass of whatever its extending.
To access a function/variable between classes that said function/variable must be static. Beware tho when do this depending on you implementation you must check for null variables. Since its static you can access you dont need a class object to access them through.
ak. SomeClass.function();
instead of using SomClass sc = new SomeClass(); sc.function();
since u can access it at any time its contents may not be initialized and be null. So ALWAYS check for null varaibles! lol. That or u can have one variable of that class to check if its class is initialized. such as..
SomeFunction.isInit();
where isInit(); is
private static initialized = false;
public static boolean isInit()
{
return initialized;
}
where in your onCreate & on onDestroy functions you set the initialized variable accordingly.
or..u could just do if(SomeClass.this!=null) lol :S
/me stops writting wot
Thanks for the input everyone. I've realised the problem (but still can't fix it). I can call methods in other classes from my timer class.... but my main class that has the methods that I need implements OnClickListener (public class game extends Activity implements OnClickListener) so it is ONLY updating the view methods when something is clicked on. How should I go about fixing it so that I can call methods that will update when a timer calls them (e.g. I display the remaining time in the title bar and it doesn't update the current time UNLESS a button is clicked on)
Why not run the timer as a thread in the activity class itself?

Strange error while returning an Object value

I posted my problem at stackoverflow, please help me if you can.
my problem is very.. different. I got a code similar to:
Code:
public class PlayerCharacter
{
public void move(int direction)
{
if(direction != 0) //Skips this
{
...
}
else //Enter here
{
destinationMap = GamePlayScreen.canTransferMap(direction);
...
}
...
}
}
public Class GamePlayScreen
{
private PlayerCharacter p;
private static GamePlayScreen instance;
...
public void codeStartsHere()
{
//heppens in motionEvent only
p.move(0);
}
public static Map canTransferMap(int direction)
{
return instance.canTransferToMap(direction); //returns here the currect value
}
private Map canTransferToMap(int direction)
{
...
return getMap(nextMapName); //returns here the currect value
}
public Map getMap(String mapName)
{
for(Map t : maps)
{
if(t.getMapName().equals(mapName) == true)
{
return t; //returns here the currect value
}
}
return null; //never gets here
}
}
Everything works fine until "GamePlayScreen.canTransferMap(direction)" ends. Though it gets the correct value from "instance.canTransferToMap(direction)", when I watch PlayerCharacter->move->destinationMap I see that it returns a null!
I went step by step and watched the return values in every "return", before & after it: it returns null instead of the value! What is even stranger, it ALWAYS works at the first time and fails at the 2nd.
I updated the android SDK but didn't help, and so reinstalling the application & doing "project->clean".
Notes:
1. I'm using Galaxy S I9000, eclipse and it is a canvas drawn application.
2. I wrote as close a copy as I could (please note that this is my REAL code).
Thanks in advance
It's hard to tell for sure, but I think you've got a scope problem. You're assigning a value to destinationMap by calling a static function of the class GamePlayScreen, but the static function is calling non-static functions within the same class so unless maps is declared static, your for loop: for (Map t: maps) , is probably returning a local variable Map that is going out of scope as soon as your call return t.
It isn't a local array, it's "private ArrayList<Map> maps;" that is defined along side "private PlayerCharacter p;" and "private static GamePlayScreen instance;" in GamePlayScreen's instance;
I tired to replace the "for-each" loop with a regular "for" but it doesn't change anything.
Though a return of a non-existing object address may sound logical, it is not possible in Java because all of the objects are allocated in the heap and not in stack. (Though I had such problems in C++)
Well, I'd have to see all the code involved I guess. I know that all objects in Java are heap based, but that also means that they must be new'd somewhere too and I saw no new for the Map object, but I suppose you did that when you placed them in the ArrayList. The static qualifier on canTransferMap() throws me off though. Why is it there if you're returning a properly new'd object?
In my code I wish to access GamePlayScreen's data from within PlayerCharacter, even though I do not have the needed reference.
My solution for that is to have a static reference to GamePlayScreen in GamePlayScreen and thus it is available from everywhere. (And I know I will not have more then one GamePlayScreen at once in my game)
About the "new" keyword, as for now I have zero "new"-s while playing the game.
I pre-allocate ALL of my data and release the temporary in a loading screen, right before the actual game starts.

[Q] Noob working on first solo App (aka: help)

Dear XDA,
I am a noob developer and I am trying to create my first real android application. (outside of Hello World prompts and predetermined tutorial programs) I am looking for a bit of guidance on how to best approach my project idea. What I want to do is create a sort of personal cook book for a friend with a main menu with options that takes you to a submenu with additional options that will take you to content pages that have return home buttons.
Please keep in mind that I am still in the learning process and want to learn. Any tips, comments, or approaches would help me a lot.
I am using eclipse to program currently and heavily relying on resources like http://developer.android.com to do even the simplest things.
Thank you!
~obewah
Well without getting into much detail i would say that you would need to come up with a data structure to store your recipes in, make some layouts for the screens you want to display. Also try to reuse the Activity that displays the recipe. When you start that Activity you can send an Extra in the Intent to specify which recipe to display. This will make it very easy to add recipes on the fly
From something awesome
Additional to what killersnowman said, I would recommend you to study ListActivity, and also databases, so you can add recipes from app.
Also you may want take a look to shared preferences.
If you have some coding question, feel free to contact me
Cheers From Colombia
D4.
Depends on if you want to be able to add/edit recipes or not. If you're going to add/edit etc., you'll want to do a database. If you just want to display recipes, reading in flat files would probably be easiest.
Probable be best to use strings.XML for the recipes. And for the buttons search for information about onClickListener and intent.
lukemovement1 said:
Probable be best to use strings.XML for the recipes. And for the buttons search for information about onClickListener and intent.
Click to expand...
Click to collapse
This might be the easiest so do this.
Sent from my SGH-T959 using XDA App
lukemovement1 said:
Probable be best to use strings.XML for the recipes. And for the buttons search for information about onClickListener and intent.
Click to expand...
Click to collapse
Easiest but not the most flexible
From something awesome
Thanks! Progress Update #1
First off thank you for all of the help so far! So far I have two XML layouts (one for the intro page with a picture, dedication, and button to the main.xml and the main with buttons to different categories inside the application)
This is my first independent code (which I am oh so proud of even if it only clicks through to another XML screen-- you have no idea how long it took me to make it work correctly)
Code:
package com.android.obewah.baristame;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class BaristaMeActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.startup);
final Button button = (Button) findViewById(R.id.startupBU);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click {
setContentView(R.layout.main);};}
);}}
I am still trying to wrap my brain around how I am going to put in the recipes.
My current plan of action is to create a scroll menu that pops up when you select a category (via button on main page) that leads you to an XML of the recipe.
However this seems like it may be an unnecessarily difficult approach. I don't plan to have an option of adding recipes from the app just for it to be a reference.
Thoughts/Comments?
~obewah
final Button button = (Button) findViewById(R.id.startupBU);
Click to expand...
Click to collapse
Im going to change this too-
final Button startupBU = (Button) findViewById(R.id.startupBU);
to keep things ID'ed correctly
obewah said:
First off thank you for all of the help so far! So far I have two XML layouts (one for the intro page with a picture, dedication, and button to the main.xml and the main with buttons to different categories inside the application)
This is my first independent code (which I am oh so proud of even if it only clicks through to another XML screen-- you have no idea how long it took me to make it work correctly)
Code:
package com.android.obewah.baristame;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class BaristaMeActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.startup);
final Button button = (Button) findViewById(R.id.startupBU);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click {
setContentView(R.layout.main);};}
);}}
I am still trying to wrap my brain around how I am going to put in the recipes.
My current plan of action is to create a scroll menu that pops up when you select a category (via button on main page) that leads you to an XML of the recipe.
However this seems like it may be an unnecessarily difficult approach. I don't plan to have an option of adding recipes from the app just for it to be a reference.
Thoughts/Comments?
~obewah
Click to expand...
Click to collapse
Might i suggest not just changing the layout in the onClickListener but calling startActivity and changing to an Activity that has that layout. This will preserve the back buttons functionality without a bunch of overriding it.
From something awesome
killersnowman said:
Might i suggest not just changing the layout in the onClickListener but calling startActivity and changing to an Activity that has that layout. This will preserve the back buttons functionality without a bunch of overriding it.
Click to expand...
Click to collapse
Please elaborate on how I would do that (and forgive my ignorance)
~obewah
this might interest you
http://developer.android.com/guide/practices/design/seamlessness.html#multiple-activities
Don't Overload a Single Activity Screen
Any application worth using will probably have several different screens. When designing the screens of your UI, be sure to make use of multiple Activity object instances.
Depending on your development background, you may interpret an Activity as similar to something like a Java Applet, in that it is the entry point for your application. However, that's not quite accurate: where an Applet subclass is the single entry point for a Java Applet, an Activity should be thought of as one of potentially several entry points to your application. The only difference between your "main" Activity and any others you might have is that the "main" one just happens to be the only one that expressed an interest in the "android.intent.action.MAIN" action in your AndroidManifest..xml file.
So, when designing your application, think of your application as a federation of Activity objects. This will make your code a lot more maintainable in the long run, and as a nice side effect also plays nicely with Android's application history and "backstack" model.
do you know any html coding? because you can use a webview to load a .html file from R.raw.file.html. i have done this with my change log on my app. also if you using strings.xml have a look at using the \n to add a new link.
Update 3
Well the first two buttons took me about two hours each. Then the next 8 or so took 15 min.
Here is what the code looks like atm; can anyone tell me how to make the back button cause it to go back one step in the program and not exit?
Code:
package com.android.obewah.baristame;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.Window;
import android.widget.Button;
public class BaristaMeActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.startup);
Button startupBU = (Button) findViewById(R.id.startupBU);
startupBU.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Perform action on click
setContentView(R.layout.main);
//start rec. buttons
}
});}
Class mystuff;
public void toreci(View v) {
setContentView(R.layout.make);
}
public void toramer(View v) {
setContentView(R.layout.ramer);
}
public void tohome(View v) {
setContentView(R.layout.main);
}
public void torcapp(View v) {
setContentView(R.layout.rcapp);
}
public void torlatt(View v) {
setContentView(R.layout.rlatt);
}
public void torbrev(View v) {
setContentView(R.layout.rbrev);
}
public void tordopp(View v) {
setContentView(R.layout.rdopp);
}
public void toriame(View v) {
setContentView(R.layout.riame);
}
public void torilat(View v) {
setContentView(R.layout.rilat);
}
public void toribre(View v) {
setContentView(R.layout.ribre);
}
public void test(View v) {
setContentView(R.layout.test);
}
}
Agree with killersnowman, don't overload the activity.
Have a recipe activity and layout. Make the button start the recipe activity and pass extra's (ints, strings, booleans) across in a bundle.
Here is an example on how to do it.
http://droidapp.co.uk/?p=48
Make the recipe activity read from the bundle, and then populate textviews / images etc based on them.
eatmold said:
Agree with killersnowman, don't overload the activity.
Have a recipe activity and layout. Make the button start the recipe activity and pass extra's (ints, strings, booleans) across in a bundle.
Here is an example on how to do it.
http://droidapp.co.uk/?p=48
Make the recipe activity read from the bundle, and then populate textviews / images etc based on them.
Click to expand...
Click to collapse
Ok, I have some dumb questions for you please forgive me in advance.
1) So what you are trying to tell me is to create another .java activity file that the main activity forwards to in order to preserve the integrity of the main activity. This new activity should be activated by the click here to start button and it will have all of the button code in it:
Code:
public void tolabou(View v) {
setContentView(R.layout.lcoff);
}
public void toldrip(View v) {
setContentView(R.layout.ldrip);
}
public void tolflav(View v) {
setContentView(R.layout.lflav);
Is that right?
2) Can you give me a idiot friendly definition of "activity, ints, strings, booleans, and bundle" and how they compliment each other
3) Right now I have a layout.xml for each recipe is that bad?
Feel free to answered all or any part of those questions and again I am truly grateful for all of the help I have received!
Well i can answer #2.
For more on activities: http://developer.android.com/reference/android/app/Activity.html
An activity is like each "part" of a program. You can have as any as you want. The main one gets called by the launcher to start the app.
For variable types look at: http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
Int = number without decimal (-7,0,1,8) -2,147,483,647 to 2,147,483,647 max.
for decimals use float or double
string = text. ("Hello World!")
boolean = true/false (1/0, on/off, whatever).
bundle = some android thing. I believe it can save the state of your program to resume and stuff.
For future referance:
Java Tutorials: http://download.oracle.com/javase/tutorial/index.html (Lots of good stuff for starting programming and java)
Android Dev: http://developer.android.com/guide/index.html (Android specific stuff)
OK, I'll try to explain the process:
Main Screen:
1 Activity : main.java (This is the Java class, contain java code)
1 Layout : main.xml (This is the XML layout, linked to the class in setContentView)
Recipe Screen:
1 Activity : recipe.java
1 Layout : recipe.xml
So if in the main screen there are 2 buttons ("Lasagne" and "Pasta Bake"). Pressing either of these buttons will launch the recipe screen, but will pass a different string in the bundle to the new activity:
Code:
LasagneButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Intent myintent = new Intent("com.whatever.whateverapp.RECIPE");
Bundle mybundle = new Bundle();
mybundle.putString("recipename", "lasagne");
myintent.putExtras(mybundle);
startActivity(myintent);
}
});
The code above is creating a new intent, and a bundle. Adding a string called "recipename" to the bundle and setting it's value to "lasagne". This bundle is then added to the intent, and the activity is started. For the second button you would do exactly the same but set the string to "PastaBake".
So now when the recipe activity starts you need to extract the string, the next code should be placed under onCreate in your recipe activity:
Code:
Bundle mybundle = getIntent().getExtras();
String recipename = mybundle.getString("recipename");
Now with this recipename string you will need to populate your layout.
Hope that makes it a bit clearer. Here are some short tutorials I have written that may help you understand the basics a bit more (BTW: I am no expert, and have only been programming Android / Java for 6 months or so):
Buttons & Actions: http://droidapp.co.uk/?p=4
Changing Screens: http://droidapp.co.uk/?p=24
You will need to read and understand the second one to understand setting up activities as they need to be declared in the AndroidManifest file.

Android/Java Newbie

Hi all, im having a go at developing a simple app. i have little experience with Java and Android development. i have a little test app at the moment and have created a new class, im trying to create a new instance of this class on a button click. it fails to do so, i cant for the life of me see why so.. can someone shed any light on this?
Thanks
Debuging this shows it hitting the "LocationFactory locationf = new LocationFactory();" line and throwing an exception-
"java.lang.NullPointerException"
Main
Code:
package com.example.testapp;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
import java.io.IOException;
public class MainActivity extends Activity {
private static final Context Context = null;
protected static final String TAG = null;
[user=439709]@override[/user]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
[user=439709]@override[/user]
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 mainButton(View view) throws IOException {
try {
LocationFactory locationf = new LocationFactory();
Toast.makeText(this, locationf.getAddress(),Toast.LENGTH_LONG).show();
} catch (Exception e)
{
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
}
}
}
Class
Code:
package com.example.testapp;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import java.io.IOException;
import java.util.Locale;
import java.util.List;
public class LocationFactory
{
private static final Context Context = null;
Geocoder geocoder = new Geocoder(Context, Locale.getDefault());
LocationManager manager = (LocationManager) Context.getSystemService(android.content.Context.LOCATION_SERVICE);
public double Latitude = 0.0;
public double Longitude = 0.0;
public LocationFactory()
{
}
public String getAddress() throws IOException
{
String ReturnAddress = "";
String Address = "", City = "", Country = "";
List<Address> addresses = null;
if(manager.isProviderEnabled(LocationManager.GPS_PROVIDER))
{
// Use GPS Radio Location
Location GPSlocation = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Latitude = GPSlocation.getLatitude();
Longitude = GPSlocation.getLongitude();
}
else
{
// Use Cell Tower Location
Location NETlocation = manager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Latitude = NETlocation.getLatitude();
Longitude = NETlocation.getLongitude();
}
if(Latitude > 0 && Longitude > 0)
{
addresses = geocoder.getFromLocation(Latitude, Longitude, 1);
if(!addresses.isEmpty())
{
Address = addresses.get(0).getAddressLine(0);
City = addresses.get(0).getAddressLine(1);
Country = addresses.get(0).getAddressLine(2);
}
}
ReturnAddress = Address + " " + City + " " + Country;
return ReturnAddress;
}
}
I don't see anywhere in your code where you are calling the mainButton(View view) method. In the Android lifecycle, the onCreate method is the equivalent of a normal Java program's main() method, which means that code execution begins with the first line of onCreate(). Not knowing what you're trying to do, a good start would be to call your mainButton() method AFTER setContentView() in onCreate().
Side note: your mainButton() method has a View parameter that is never used. Is there a reason for that?
Android activity lifecycle: http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
You have to use an intent on that button click, use the method onClickListener and define the intent in the androidmanifest.xml
e.g
Code:
Button button = (Button) findViewById(R.id.[B]button[/B]) // replace latter button with actual id defined in main xml.
button.setOnClickListener(new View.OnClickListener() {
[user=439709]@override[/user]
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent("[B]com.example.packagename.CLASSNAME[/B]")); // this should be your own package name.
}
});
Also define this in android manifest under the <application> and </application>
Code:
<activity
android:name=".[B]CLASSNAME[/B]"
android:label="@string/app_name"
>
<intent-filter>
<action android:name="[B]com.example.packagename.CLASSNAME[/B]" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Change the values of BOLD text according to your own values.
I tried to help you as far as I understood your question. Please let me know if you face any problem I would be more than happy to help you. Rest I am also in the learning phase so you can always PM me if you face any problem.
Hit thanks if I have helped you in any way.
coolbud012 said:
You have to use an intent on that button click, use the method onClickListener and define the intent in the androidmanifest.xml
Click to expand...
Click to collapse
Nope! He didn't say that he wanted to launch a new Activity when the button is clicked. He wants to create a new instance of his LocationFactory Class.
jpepin said:
Nope! He didn't say that he wanted to launch a new Activity when the button is clicked. He wants to create a new instance of his LocationFactory Class.
Click to expand...
Click to collapse
Oops yeah right read that now...I thought he want to start an activity... Anyways tried to delete my reply but not getting an option to delete.
There are many flaws in his code. And the other thing is if its his first app and if he has low level of programming experience then according to me it would be a next to impossible app for him, as per his code and what he is trying to implement.
I think he should rather start up with small apps, understand things and then move on to complex apps.
P.S - its just my opinion
Click to expand...
Click to collapse
Agreed that he should start small...which is exactly why your suggestion for creating and handling Intents makes no sense. Before that, he should first understand the activity lifecycle. Until then, he can just stick to trivial single-activity apps to gain experience.
OP: This code should be placed in the onCreate method:
Code:
Button button = (Button) findViewById(R.id.your_button_ID_here)
button.setOnClickListener(new View.OnClickListener() {
[user=439709]@override[/user]
public void onClick(View arg0) {
mainButton(); // get rid of the View parameter in this method...it's not needed
}
});
This will cause a new instance of your LocationFactory to be created, and will also cause your Toast message to be displayed.
thanks for the replies. yes you are right in that i am inexperienced, but this is just a test app for me to play around with and learn on. i tend to learn better by doing rather than constantly reading. thanks for your suggestions ill look into them
osmorgan said:
thanks for the replies. yes you are right in that i am inexperienced, but this is just a test app for me to play around with and learn on. i tend to learn better by doing rather than constantly reading. thanks for your suggestions ill look into them
Click to expand...
Click to collapse
I also believe in the same, I also keep on doing experiments and testing things out.
What I would suggest is that start with a small app and understand the insights on how android works and all...
Thanks
Potential Solution
Alright, I think I've found your problem. Have a look at where you define your variables in your LocationManager class:
Code:
private static final Context Context = null;
Geocoder geocoder = new Geocoder(Context, Locale.getDefault());
LocationManager manager = (LocationManager) Context.getSystemService(android.content.Context.LOCATION_SERVICE);
This is your problem:
Code:
Context Context = null;
If your context is null, and you use it to create a geocoder and call Context.getSystemService, you'll hit a null pointer. You're trying to access an object (the Context) that doesn't even exist
I'd recommend you pass the context in the LocationManager constructor and then instantiate your objects there. That's standard java procedure.
Code:
private Context mContext = null;
Geocoder geocoder = null;
LocationManager manager = null;
public double Latitude = 0.0;
public double Longitude = 0.0;
public LocationFactory(Context context)
{
this.mContext = context;
this.geocoder = new Geocoder(context, Locale.getDefault());
this.manager = (LocationManager) Context.getSystemService(android.content.Context.LOCATION_SERVICE);
}
I also renamed Context to mContext - it's generally a good idea to keep the instance's name separate from the class name.
Try that - it should work. Please feel free to ask any more questions - this is how I learned, and I think it's the best way!

Categories

Resources