Sunday, November 8, 2009

Verizon Droid and bugs

Android has been getting excellent press lately. It's really exciting!

Seems like they're putting a huge marketing push behind the new Verizon Droid phone, which is running the new Android 2.0, comes with the car GPS holder, and looks sexy. Finally a pretty Android phone on par with iPhone's looks!

Yeah so the "reddit is fun" app seems to exhibit weird behavior on Droid. Users have reported some crashes coming back to it from a browser link. Also the default Light theme is apparently broken... I guess Droid or Android 2.0 changed the themes around from the 1.6 built-ins.

Hope I can find some time soon to look at 2.0 SDK, which I haven't even installed yet.

Tuesday, September 15, 2009

Crashes with CyanogenMod and apps2sd

A handful of users have been reporting force closes and bugginess when running reddit is fun and CyanogenMod and apps2sd. Unfortunately I don't use either, so I can't reproduce the bugs.

I wonder if any Android developers who do use these mods would mind helping debug this issue?

(follow the issue at http://github.com/talklittle/reddit-is-fun/issues/#issue/13)

EDIT: Ok, I looked at xda-developers forum and see there's this script, switchrom.sh to make it easier to switch between different ROMs. Well, I guess I'll try it out then.

Used this recovery image by JesusFreke to do Nandroid backup before anything else. Then replaced with Cyanogen's 1.4 after I installed CyanogenMod 4.1.9.2. (probably could have skipped using the first recovery image at all... oh well)

Took a break and donated 5 bucks to Cyanogen's beer fund :)

Then backed up sd card contents, and following directions here to setup partitions for apps2sd (which is automatic in Cyanogen rom after doing partitioning)

EDIT2: Yes, I have now indeed encountered force closes that I didn't encounter with stock rom. They mostly happen when rotating the screen. Happened again when rotating screen with login dialog onscreen. Also I get a weird bug where it doesn't load the threads list correctly the first time, and I have to refresh to get anything to show up.

EDIT3: FIXED!!! I had a bunch of errors caused by things like weird Android behavior, trying to run onPrepareDialog for every possible Dialog whenever you rotate the screen or return from another Activity, leading to NullPointerExceptions. Some other things too, like having to setup the DefaultHttpClient to be multithreaded (found examples on apache.org HttpClient 4.0 samples). So grab version 0.7.11, and CyanogenMod too :)

Saturday, September 5, 2009

Released reddit is fun under GPLv3

I just open sourced my first Android app, reddit is fun. I did it because I won't have time to maintain it anymore (or if I do have time, I think I'm ready to move onto other projects). Hopefully people will find it useful, or even better, contribute to it. Contributions could be in the form of better themes, improved layouts, and added features (like offline caching).

I chose GPL over the Apache license because I think GPL makes more sense here. I gave it a lot of thought, and I think that if I use GPL (which requires derived works to also release their source under GPL) then it'll be easier for people to contribute to a "community" sort of app. The alternative under Apache would be that people could take the code and do whatever they wanted, and then keep the changes to themselves as closed source. Which might be good if people want to make a really high quality reddit app and keep the source to themselves. But really, I can't see additions to the current code being so drastic that people would want to hide their changes.

Git repository: http://github.com/talklittle/reddit-is-fun/tree

Monday, August 31, 2009

reddit is fun v0.7.0 - My last major release for awhile

reddit is fun v0.7.0!





New features:
  • check your reddit mail. change the mail notification style, or disable, in Menu->Settings.
  • automatic background mail notification service, off by default. (Menu->Settings)
  • change sort order of threads and comments. new, hot, top, etc.
  • pick from your personalized subreddit list
  • let you change default starting reddit (Menu->Settings)


This'll be my last major release for awhile since I'm going back to start my Masters program. I'll work on new features when I have time though. Thanks for everyone's support!

EDIT: Oops, I forgot to implement "load more comments". I'll do that soon.

EDIT: 0.7.1 fixes some bad formatting of titles and comment bodies. Thanks to Todd for bringing this to my attention.
EDIT: 0.7.2 fixes couple minor bugs. thanks to jk3us again for pointing out force close when replying to thread while not logged in.
EDIT: 0.7.3 fixes a force close when selecting "pick subreddit" without internet connection
EDIT: 0.7.4 finally implements "load more comments". not inline, unfortunately (how would I handle all the indentation?). also adds "go to parent" context menu option for more convenient navigation.

 Also if you'd like to donate, please use the "reddit is fun donation" app in the Market. I also have a paypal account (talklittle, gmail). Thanks very much! :)

Friday, August 28, 2009

1000 downloads!

I just hit the 1000 download mark on Android Market for reddit is fun! Thanks, reddit.com!

Wednesday, August 26, 2009

Intent filter for "Share link"

I just released reddit is fun v0.6.4.

The main feature was a suggestion by jk3us which was to add the app to the list of destinations for sharing, for instance when you click "Share page" from the Browser menu.

To do it, I had to add an intent filter. It looks like this:

            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
               </intent-filter>

I also fixed a long-standing possible force close due to a race condition around dismissing the login dialog and reading from the dialog's members. I never experienced the force close until today, but I have a feeling some other phone models experience it more often than the G1. I was moving some stuff around in the code, which caused the force close to happen very, very frequently. Which makes me think that other phone models could easily have had a higher frequency of this happening, if it was really due to a race condition. Oh well, it should be gone now.

Saturday, August 22, 2009

reddit is fun v0.6.0 - You can submit links

I just released reddit is fun 0.6.0 and it feels awesome. (the act of releasing a new version, that is.)

The big feature of 0.6.0 is posting new threads (links or self posts). Yessss.


Sssssssss.


Anyway, there's still a long way to go before my app reaches "pro" status. First up are things like the orange-red envelope, expanding and collapsing comment trees, and viewing user posting histories.

I also have a long list of big and small changes I'd still like to make. So there's plenty left to do. Too bad when school starts I'll have a lot less time to work on this.


Reddit post:
http://www.reddit.com/r/Android/comments/9d6dg/reddit_is_fun_060_is_out/

EDIT: 0.6.1 lets you follow links embedded in comments. It was annoying not to be able to get to those. I copied the behavior of the Android Messaging app.

EDIT: 0.6.2 lets you hide comments by long-pressing and using the context menu. I figure the context menu can be used for less frequently used (for me at least) actions, while regular clicks will show the frequently used actions -- voting, reply, and visiting links embedded in the comment.

Edit: 0.6.3 lets you go to the next/previous pages in threads list. hooray! It was weird implementing this because the reddit API requires you to provide the correct "count" value in the URL, or else it doesn't tell you how to get back to the previous page. Whatever. Details...
Also fixes the bug with rotating the screen putting you back at the reddit frontpage instead of whatever subreddit you were in.

Tuesday, August 18, 2009

reddit is fun v0.5.3

I just released 0.5.3 of reddit is fun!

So, thanks to helpful feedback from people, I fixed quite a few stability issues. It sucks to admit it, but the first release had lots of synchronous tasks that should have been asynchronous. I hadn't realized that was really necessary until people told me about their crashes. So I went back to eclipse and pounded away at the app for hours, refactoring until I turned all the synchronous crap into AsyncTasks, which are EXTREMELY useful on Android. (Before I knew about AsyncTask, I was trying to use Threads and Handlers and callbacks, and keeping track of the state of the Activities. AsyncTask takes care of the nitty gritty stuff and makes it much easier and more robust.)

Anyway I'm also getting good suggestions for UI improvements. Awesome. I really like my pace on this project because it feels like I can just get into it and keep going full speed. Maybe it's the fact that it's all Java and that Eclipse fills in a lot of the uninteresting stuff for you so you can worry about the program instead of the code. There were a couple debug sessions that dragged on, though. But it's always nice to take a step back and think of a possible cause and solution for a bug, and even nicer when it works. It kicks butt. No, it kicks two butts. Make that three.

Sunday, August 16, 2009

reddit is fun - first release, version 0.5.0





reddit is fun


My first app is now on the Android marketplace! "reddit is fun" is an app for browsing reddit.com with IMO a less annoying interface than dealing with the Android browser.

For this version, 0.5.0, you can look at the hot stories on different subreddits, login and vote, and leave comment replies.

In future versions I still have a lot of things to add:
  • Posting new threads
  • Better UI (some dialogs are wonky)
  • Looking at user info
  • The "red envelope" for replies
  • Sorting the subreddit and comments by things other than "hot"
  • "load more comments"
  • View more pages within a subreddit
  • Handling embedded links in comments
  • A few other features that might go into a paid version :)
So I guess this initial release took me about two and a half weeks. It felt like much longer though.... I've been working on it in my spare time after my day job.

Tuesday, June 16, 2009

StateListDrawable and TransitionDrawable

StateListDrawable and TransitionDrawable are useful classes when it comes to making custom buttons and controls.

Making a custom button is simple. First of all you need to create some graphics for the different states of your button (see the Android dev guide on basic 2d Graphics).

I created a couple NinePatchDrawable image files using GIMP and the draw9patch.bat tool included in the Android SDK under <sdk-dir>/tools/. Here they are:

bluebutton.9.png


redbutton.9.png


Android already has its own default built-in buttons which are pretty similar to these. Of course, in a real app you can give the buttons different shapes and designs. Also, since these are NinePatch images, I could have made them smaller to save space since they'd stretch the same way anyway.

To use these in my project, I created a couple XML files under my project's res/drawable directory, pressbutton.xml and longpressbutton.xml.

res/drawable/pressbutton.xml:


<selector android="http://schemas.android.com/apk/res/android">
<item state_pressed="true" drawable="@drawable/redbutton">
<item drawable="@drawable/bluebutton">
</selector>



With selectors (StateListDrawables), the object displays the first <item> underneath the <selector> tag whose attributes match the state of the object. Since the last <item> in my example doesn't have any attributes like state_pressed, it acts as a catch-all.




res/drawable/longpressbutton.xml:


<transition android="http://schemas.android.com/apk/res/android">
<item drawable="@drawable/redbutton">
<item drawable="@drawable/bluebutton">
</transition>



The <transition> (TransitionDrawable) is more of an animation definition, so you don't need attributes on the <item>s. It plays through the <item>s sequentially based on the argument you pass into the startTransition(milliseconds) method.

Now, getting TransitionDrawables to work is a bit trickier than using StateListDrawables. Well, at least it took me longer to figure out.

I made a subclass of Button called TransitionButton, like this:



public class TransitionButton extends Button {
private TransitionDrawable mTransition = null;
private Context mContext;

public TransitionButton(Context context) {
super(context);
mContext = context;
}
public TransitionButton(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
public TransitionButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
}

public void setTransition(TransitionDrawable transition) {
mTransition = transition;
setBackgroundDrawable(transition);
}

public void setPressed(boolean pressed) {
super.setPressed(pressed);
if (pressed && mTransition != null) {
mTransition.startTransition(1000);
} else if (!pressed && mTransition != null) {
mTransition.resetTransition();
}
}
}


To use the Button and TransitionButton, as usual I put the necessary code into the onCreate(Bundle) method of my Activity. So I have something like this:




public class StateAndTransition extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

final Context mContext = getApplicationContext();
Resources res = mContext.getResources();
TransitionDrawable transition = (TransitionDrawable) res.getDrawable(R.drawable.longpressbutton);

final Button stateButton = (Button) findViewById(R.id.statebutton);
stateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
stateButton.setTextSize(10 + stateButton.getTextSize());
}
});


final TransitionButton longpressButton = (TransitionButton) findViewById(R.id.longpress);
longpressButton.setTransition(transition);

longpressButton.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent m) {
if (m.getAction() == MotionEvent.ACTION_DOWN) {
longpressButton.setPressed(true);
} else {
longpressButton.setPressed(false);
}
return true; // The Listener consumes the Touch action
}
});

}


}




Finally, my res/layout/main.xml:



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/talklittle.android.examples.stateandtransition"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>

<Button android:id="@+id/statebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:text="Touch me"
android:textSize="8sp"
android:background="@drawable/pressbutton"/>

<talklittle.android.examples.stateandtransition.TransitionButton
android:id="@+id/longpress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:text="Hold me"
android:textSize="30sp"
android:background="@drawable/redbutton"/>

</LinearLayout>




Now, that will hopefully compile and run (with minor changes like adding the imports and package statements). If so, then you should see that the Button using a StateListDrawable works fine, while the TransitionButton is buggy. It looks like this at the end of the transition:

No, we don't want it to look like that. What's going on? The answer is that since we're using NinePatch images, the padding area of the images is not changed when we use a TransitionDrawable for the background. We can fix this by either using a regular Drawable (xxx.png instead of xxx.9.png) or by drawing padding lines that extend all the way along the right and bottom edges, making button text ugly unless you manually size the Buttons.

With custom Buttons though, I think most of the time you'd be using static sized images rather than NinePatch images, but that's just my opinion. I was just too lazy this time to make more than two images.

Anyway that's about it for this small tutorial. Hope it makes sense! I wrote it mostly for myself to document this procedure, since it took awhile to figure out the details.

Sunday, June 14, 2009

Wish my wireless router was better

I was able to get my Android Dev phone set up very easily without a data plan, just using a wireless connection and Linux, by following the directions on this very useful post from technomancy.org. Luckily I had an Ubuntu VM ready to go, so the entire setup process took no more than ten minutes.

Unfortunately, though, my wireless router is a bit old and sucky, and the wireless craps out from time to time. On top of that, the phone won't keep retrying the connection; I believe it tries to reconnect to your remembered wifi access points once each, then after that you have to manually go back and press the button to reconnect. (I'm running Android software 1.1. I don't think it's fixed yet in cupcake 1.5.) It's quite annoying. Maybe I'll have to put down the money for a data plan....

I think the folks in the issue tracker for #2718 are having the same issue on Cupcake though. Oh well, at least I'm not addicted to using the web from my phone yet. Mostly because "Crackdroid" sounds stupid.


On an unrelated note, I wonder how many android blogs on Blogger use this "Son of Moto" template? sigh... I'll try to come up with something better.