Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

2012/04/10

Source Not Found

I haven't yet found any useful suggestions on dealing with Source Not Found; so, I'm going to take some stabs in the dark and see if any of them result in a scream.

First off, I know that I have said that the warnings aren't that important, as long as there aren't any actual errors. How about I just test that; I comment out the unnecessary import statements [a simple /* on one side and */ on the other does the trick. Alternatively for single lines // works.]

Commenting in this way is a great method to quickly change code around - because if I decide that removing something was a mistake, I just have to uncomment it, not remember how it went and re-type it.

Then the remaining warning is around
private DatePickerDialog.OnDateSetListener mDatePicked;
and how I use it in
mDatePicked = new DatePickerDialog.OnDateSetListener() {
In that Eclipse is telling me that mDatePicked is not used! Um, oops...what's gone wrong here then? I declare mDatePicked, as you see above, then I do some stuff onDateSet.
Now, I have a sneaking suspicion that there's some duplication between these two lines, so let's see what happens if I take one out, leaving
mDatePicked {
 Nope, that errors. Badly. Howabout taking out the first one? Also makes things worse, in that the warning has upgraded to an error.
Aha! Stack Overflow to the rescue! Looks like the whole thing is redundant now I've got
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
So I'll just try cutting out the lot, see what I get. No...that causes even more problems. I'm going around in circles here. I believe the technical term is GAH!

2012/04/07

Finishing touches

As I said last time, I reckon there are two things left to do before I have a module that is worth testing.

First - I want to notify the user when a date is entered successfully. Now, this is not essential in the grand scheme of things, because when the whole app is complete, closing SSA will lead the user to a screen which shows the date (among other things). Whether or not I decide to retain it then, I want to have it now, just so that I know it's working when I test it!

The easiest way to do that is with what is called Toast - I imagine because when it is ready, it pops up! Toast is a kind of message that appears in a little box floating on the screen for a set duration.
Toast has three key components (or 'arguments', in this instance). The Context, being the current state of the application; the Text, being what you want your Toast to display; and the Duration, being how long to display it for.

As usual with Android's imaginative variable names, we get something like this:

Context context = getApplicationContext();
        CharSequence text = "You are getting married on " + WedDate + "!";
        int duration = Toast.LENGTH_LONG;
        Toast toast = Toast.makeText(context, text, duration);
        toast.show();
As you can see, here we will tell people "You are getting married on []!", for a duration of Toast.LENGTH_LONG. I don't know exactly how long that is, but it's a few seconds; certainly long enough to read this message.

Alright, so on to the second thing I wanted to add - and this is probably entirely temporary: a message on WLA to confirm that the app knows the user's wedding date.
I've put exactly the same Toast, just replacing "You are getting married on " with "Your wedding date is ", so that if I close SSA and get back to WLA at the same time as a Toast appears, I will know which Activity is responsible for it.

In both these cases, I already had the import statement - import android.widget.Toast - otherwise I would have to add it before Eclipse would be happy.

Now, bearing in mind that 1) This is one small corner of the planned app, and 2) That it may not even begin to work when tested - it's time to start testing this thing, and see what breaks!

2012/04/05

Slow Improvement

Aha! It gets better - I have not only discovered that it is possible to make the calendar appear, not just the day/month/year spinners; I have also discovered a method called onDateSetListener. I've even found out how to make a value (like "Yes, a date has been picked") persist from one session to the next.

The calendar thing I'm going to just make note of for now - remembering as I said back here that as long as it works, prettiness comes later.

The method onDateSetListener might explain some of the problems I've had with onClickSetListener - it wasn't quite the right method for what I was doing. I'll try replacing it based on what I've found at the Android Developers' forum and Stack Overflow.

So from
WeddingDate = (DatePicker)findViewById(R.id.datepicker) 
WeddingDate.setOnClickListener(this);
I now have:
WeddingDate = (DatePicker)findViewById(R.id.datepicker);
        mDatePicked = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// TODO Auto-generated method stub } 
I think that's progress, of a sort? At least, Eclipse isn't flagging any major errors, and I can put something into the method stub to cover the last point I mentioned up top - making sure that once a date is picked, the user doesn't have to do it again.

That's where this comes in. Now, the example given isn't quite right - it's for a setting that the user might change at any time, so the setting is re-saved every time the application closes. I want mine to save the setting solely when the user finishes with SSA - if they ever say they want to change the date, I'll get the app to just bring them back to SSA.

So, in WLA I have put
        SharedPreferences settings = getSharedPreferences(WedPrefs,0);
        String WedDate = settings.getString("WedDate", "");
which is aimed at getting together an object called "settings", which in addition to knowing the Wedding Date can also hold other information in future. I've picked my variable names and properties such that they match up with the if block I created here.
Coming back to SSA, where it said //TODO above, I've now got
SharedPreferences settings = getSharedPreferences(WedPrefs,0);
SharedPreferences.Editor editor = settings.edit();
WedDate = String.valueOf(year) + String.valueOf(monthOfYear) + String.valueOf(dayOfMonth);
editor.putString(WedDate);
This still isn't quite right - the string WedDate operates, and becomes year + monthOfYear + dayOfMonth [for example the 19th May 2012 would appear as 2012419* which I think is the easiest way to grab it back out afterwards] but then Eclipse isn't keen on editor.putString(WedDate); and I'm not sure why.

Well, I wasn't. I tried typing it again, and when the tips popped up:
I saw that the putString method requires two separate arguments.
By analogy with the method in WLA, the first argument has to be "WedDate".
Because of the name I've given in SSA, the second argument has to be WedDate. Fortunately one is in "" and the other is not, so that isn't confusing at all!
May want to change one of those names, I'll think about it.


In any case, this has taken a while, but I've nearly finished the initial stage. There are two immediate steps remaining - one, a message to inform the user whether the date is entered successfully, and two, something on the WLA to state whether a date already exists.
Then to build this into the full app, I'll need something to direct the app back from SSA to WLA - if I understand Android convention correctly, that will be automatic as long as I close down SSA correctly.
Then I can start testing it.

*2012419, you say? Yes. 2012 for the year; then Java counts months from 0 to 11, so in spite of being the fifth month May comes out as 4; then 19 for the 19th. I think that the month will show as 4, not 04...
Some systems counting from 0 and others from 1 is the reason for fence-post errors!

2012/04/04

Struggling with SSA (no, not what you might think!*)

AAAAAAAARRRRRRRRRRRRRRGGGGHHHHHHHHHHHHHH!
'scuse shouting, this is frustrating.

The latest thing I've tried is:
        DatePicker WeddingDate = (DatePicker)findViewById(R.id.datepicker);
        WeddingDate.setOnClickListener(this);
 based on an example I found for implementing an OnClickListener.

[OnClickListener being a method which can look out for an action by the user and take action when it is detected.]

However, Eclipse doesn't like this - the specific error it's giving me is

The method setOnClickListener(View.OnClickListener) in the type View is not applicable for the arguments (SplashScreenActivity)
 The above is shown in red to give some inkling of how angry Eclipse is with me. Now, I actually just realised an error in the above - I already defined WeddingDate as a DatePicker above, so re-defining it like this is just going to confuse Eclipse. So I take that out to get:
WeddingDate = (DatePicker)findViewById(R.id.datepicker) 
WeddingDate.setOnClickListener(this);
Main difference? WeddingDate is now highlighted in blue - Eclipse has recognised it as a defined object. The error is still marked, however.
My best guess is that I shouldn't be using an OnClickListener on a DatePicker. Hmmm. There is a way to use auto-completion to check that.

Aha. By typing
WeddingDate.set
I get a list of methods whose names begin "set" that might apply to the object WeddingDate. It's a long'un, but the beginning looks something like this:

and as I go down the list, setOnClickListener is a valid option.

Better yet, when I take the suggested variable of setOnClickListener(l) I get a different error.
l cannot be resolved to a variable
Which is fine, because it shows me that the previous error related not to the method setOnClickListener, but only to the argument, which the first time is "this" and the second time is "l". They've given me different errors because in Java "this" has a default meaning (thus the purple colouring) and "l" does not.

I do not know how to resolve this at present, but I'm sure I can come back to it.





*I realized after dubbing my SplashScreen as SSA** for the purposes of this blog that in the parlance of American Evangelicals SSA stands for same-sex attraction; as such "struggling with SSA" is the process that homophobic Evangelicals have to go through if they realise they are homosexual.
I don't feel attracted to men, and even if I did it wouldn't change the fact that I am attracted to women; so not only is the wedding still on, but the post title might be misleading to people from that world.

** I learn from the fiancĂ©e that SSA† is also a term in Chemistry for the Steady-State Approximation.

† SSA also stands for the Secular Student Alliance who are all kinds of awesome if you're USian and not so keen on the Religious Right.‡


‡ Nested footnotes FTW!

Do we have a date, dear?

I have this ongoing problem of how to persuade my app to listen out for word from the calendar on the front page [for a quick reminder, that looks something like the below:]
I need this page to notice when a date has been entered; save the date somewhere accessible for all other parts of the app; then call up the next page of the app.

As my last few posts have alluded to, this is where not having worked with Android or Java before is really kicking my arse - because this is basic stuff, and I'm having to do a lot of reading and looking at example code to figure it out.
As a result, some of my code may be more apt for an entry on The Daily WTF than Google Play [as the name suggests, the Daily WTF is a blog exposing code that makes programmers go WTF!?]. That in itself doesn't trouble me, as long as it works.

So, with no further ado, here's the next bit I've been working with.



        if(WedDate.matches("")) {
        Intent intent = new Intent(this, SplashScreenActivity.class);
        startActivity(intent); } 
To give a little background, this is in WLA, the main view for the app - and before loading, it is checking whether there is a value for WedDate. If one exists, then great - the app can continue in this page. If however the app doesn't know the date of the wedding, it loads SSA to ask the user for it.
As best I understand it, this is the best way to do things - I don't want to load WLA and then force new users to navigate away from it, and I don't want to make regular users faff about with the date before going on to do useful things.

So far so good - no errors being marked by Eclipse here! Doesn't mean there won't be a problem at run-time, of course, but...baby-steps.
On to SSA, and what we do when the user inputs a date.

2012/03/29

Android Theory

I've been delving around in Android and Java help materials - tutorials, guides and forums - to help me put together this part of the app.

So, here's the first thing that I've found out, from the official guide to developing for Android here:

An activity represents a single screen with a user interface.
That means I don't want WeddingLogisticsActivity to be a big thing - I want to deal with something called, I don't know, SplashScreenActivity (now referred to as SSA) which is aimed purely at this initial screen of the app.
[Note for future reference - I will probably want a test so that SSA only runs the first time you open the app. Easiest thing that occurs to me is to check whether the variable WeddingDate is empty; if it is, run SSA, otherwise don't. That should avoid problems.]

Looking in more detail at this page, I think the way to proceed is to tell WLA to start an activity called SSA, in the terms
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
Or in my case:
        Intent intent = new Intent(this, SplashScreenActivity.class); 
        startActivity(intent);
Then I set up the beginnings of the new Activity for SSA in the same way; only to realise that I need to put SSA in its own file, called (logically enough) SplashScreenActivity.java as otherwise the app would get confused.
Now, I'm still seeing an error in WLA on the line Intent intent etc, as the app doesn't seem to recognise it; so I tried adding an import statement as below:
import android.content.Intent;
which solved the problem.
Import statements are my friend.

Right, in the classic way of things, it is past time to post this, and I still haven't solved the original problem. Tomorrow, I promise!

2012/03/28

Java Adventures

So, this is where I've hit the problem that Java is not a language I'm familiar with.

So that's why this post is a bit late - I've had to delve into some Java resources to figure out how to distinguish my arse from my elbow.

Anyway, I already had:

public class WeddingLogisticsActivity extends Activity {


/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}


I'm fairly sure I need to declare a DatePicker (tell the app to expect a DatePicker, and what to call it), so I added
DatePicker WeddingDate;
This means when I refer to WeddingDate, the app knows what I'm talking about.
Then, from looking at example code, (mostly from hackaday which I mentioned before), I need to tell the app what to do with WeddingDate. And...I can't quite figure that bit out yet. More reading required!

2012/03/27

Code: Import, Activity, Extend

This next bit is focussed in the source-code folder (src), in a section named WeddingLogisticActivity.java

Eclipse has automatically added in what you see on the left here.
First of all we have the name of the package, which will eventually uniquely identify Wedding Logistics on Google Play.
Then we have the import statements. One analogy for these is academic references - if you write an essay which doesn't show the sources for your statements of fact then your readers will think you're making it up. Well, think of your app as a very sceptical reader - unless every statement is ultimately backed up in a reference [unless every method is in an imported library], it won't believe you [won't be able to execute that method].

The import statements I have already just cover me for the basic operation of the Android Operating System, and for the initial Activity that I'll get to in a moment, so I'll be adding a few, to deal with the Context (the situation on your Android), the View (what's on screen), an OnClickListener (to notice when, say, the user clicks on a button), deal with Buttons, Toast (messages that appear temporarily on screen. So called because they pop-up, I think), and a DatePicker, &c.
I've got the outline of my list from the excellent hackaday.com Android Tutorial and then added one for the DatePicker. Eclipse helpfully highlights all of the import statements I'm not using at the moment
(see the little row of symbols on the left?) so I can remove any unnecessary imports once the code is finished. Equally, as I expand the app, I'm likely to need to add more imports to cover new features.

Then we declare a public class called WeddingLogisticsActivity (henceforth abbreviated to WLA), and that it extends the core Activity.
Just to unpack that a bit - public means that other processes can refer to WLA; class - well, for a full definition of that I'll give you the wikipedia article, but the short version is that it means I could have several examples of WLA, based on the definition of it given here.
As to the bit about extending Activity, well, the Activity is a core Android class which handles some basic stuff for me - saying WLA extends Activity is a way of telling the system I want WLA to start with all the attributes of Activity, and then I want to give it some more.

At present, all WLA does which is apparent to the user is load the screen from last time; however, if the user attempts to enter the date, nothing will happen. If they click Done, nothing will happen. Unfortunately, I'm out of time, so I'll get to rectifying that next time!