Friday, July 29, 2011

Stalker: Demographics

So what's more creepy than an Android application that stalks your Facebook friends for you?  The fact that Facebook itself, is stalking the users who install it!

Apparently Facebook keeps track of a lot of the API usage for applications, and one of the more interesting pieces of data is the "Demographics" statistic.

Stalker has only been out for about 20 days, so here's what Facebook has recorded so far of all the folks that have installed it:


Monday, July 18, 2011

Stalker 1.1

The next version of Stalker is now on the Android Market - and it's sporting a whole new (iPhone inspired) look!





Monday, July 11, 2011

Introducing: Stalker for Android



Don't miss out on someone else's important life event again!

Tired of continually opening the Facebook application on your phone to check the Facebook status of a few people? Is your girlfriend on a trip to Wine Country, and you want to live vicariously through her adventures? Is there someone you just met at a bar and are anxious to find out if they find you "interesting"?

Stalker is just the app for you!

Stalker will connect to your Facebook account and notify you anytime a select list of friends has updated their status (or when they have anything happen on their wall)!



Stalker is free and ad supported. You are limited to only stalking a single friend unless you purchase the Stalker License application ($1.99) from the market. Once you have the Stalker License application purchased all ads will be removed, and you can stalk as many friends as you would like.

Market Link

Monday, July 04, 2011

Externalizing Android strings in Eclipse

The Android SDK documents highly recommend the practice of externalizing all of your strings to an external XML file (strings.xml), instead of hard coding them in java or other XML documents.

Why? So its easier for you to provide translations for your app down the road if you want.

For a long time I have put off doing this in any of my Android applications, as its a hugely time consuming task with seemingly little benefit to me.. until recently when I discovered a handy feature of the Android ADT plugin for Eclipse: Refactoring Android Strings!

Highlite any string, click on Refactor in the main Eclipse menu, Android, Extract Anroid String.

It will automatically extract your string into the strings.xml file, and it will generate the necessary API call in place to load your string!  Handy!



Tuesday, June 14, 2011

Android + Dropbox SDK + ProGaurd = Frustration

So it's no secret that I have been playing with the Dropbox API for my next Android App (yet to be announced).  In order to interact with Dropbox you have to sign all of your requests with special keys that they provide - if you lose these keys, or someone compromises them -- you are SOL and someone could potentially pretend to be your app.

Java is pretty easy to decompile to pull out constant strings - so how do you combat this? Obfuscation!

The Android SDK (since 2.3?) comes with Progaurd built-in.  Everything you read says its super easy to enable - and works well out of the box.

... maybe so if you aren't using any 3rd party libraries.

ProGaurd does NOT work well out of the box with the Dropbox code and libraries.  Below is my progaurd config that finally produced a usable apk:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose

-dontoptimize

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService
-keep public class * extends org.apache.commons.logging.LogFactory

-libraryjars /Users/npike/Documents/workspace/PicturePushr/lib/apache-mime4j-0.6.jar
-libraryjars /Users/npike/Documents/workspace/PicturePushr/lib/dropbox-client-1.0-SNAPSHOT.jar
-libraryjars /Users/npike/Documents/workspace/PicturePushr/lib/httpmime-4.0.jar
-libraryjars /Users/npike/Documents/workspace/PicturePushr/lib/json_simple-1.1.jar
-libraryjars /Users/npike/Documents/workspace/PicturePushr/lib/signpost-commonshttp4-1.2.1.1.jar
-libraryjars /Users/npike/Documents/workspace/PicturePushr/lib/signpost-core-1.2.1.1.jar

-dontwarn org.apache.commons.logging.LogFactory,org.apache.commons.codec.binary.Base64,net.jcip.annotations.NotThreadSafe,net.jcip.annotations.Immutable,net.jcip.annotations.ThreadSafe

-keepclasseswithmembernames class * {
native ;
}

-keepclasseswithmembernames class * {
public (android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
public (android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}


Download

Thursday, June 02, 2011

Android Code Snippet: Uploading a file to DropBox with DropBox SDK for Java/Android

I won't cover the code necessary to actually login to dropbox (use their sample app to figure that out!), but just the specific API call to upload a file to Dropbox.

Surprisingly, they dont seem to provide any language specific API information what-so-ever.

Sunday, April 17, 2011

Android: Baseball Reg Season Standings 2.2 Released

Changes:


  • added schedule for the next 30 days

  • fixed spacing on widget

  • support for landscape widget mode

  • updated the look of the division standings




Changes for the LITE version:



  • Fixed spacing on widget

  • Added "nag square" on the widget to advertise the $0.99 widget

  • Clicking on the widget will launch the Android Market and bring you to the page to buy Baseball Reg Season Standings 2011



Thanks to Erik Bye for the design help - I am sure many improvements to come!

Monday, April 11, 2011

ChromeTabs

My typical weekend day is spent juggling my Macbook, my iPad, and my smart phone.  Each device running a completely different browser from the other.

Frequently I do a bunch of surfing on my Macbook, only to jump into bed with the iPad - or to take the dog for a walk (with my smartphone along for the ride).

Why can't my "tabs" in chrome come with me?

Firefox 4 has a nifty feature called Weave (the Weave project itself has been around for awhile, long before Firefox 4) - but this of course doesn't do me any good if I use Chrome as my browser on my MacBook, mobile safari on my iPad, and the browser on Android.

I decided to throw together a quick extension for Chrome that monitors my currently opened tab set - and keeps track of them via a small website that I can visit on any of my other devices to see what tabs I have open.



Good enough for me, for now - but I could easily see myself turning this into a full fledged extension and service for other people to use.

Wednesday, March 23, 2011

Android: Baseball Reg Season Standings 2011

It's almost ready! I have completely revamped the 2011 version of Baseball Reg Season Standings widget for Android and am very excited to release it on Opening Day.

So far only one addition to the feature list (the game of the day per team) - but the look, speed, and stability of the widget has been improved across the board.

Here's a few screenshots for now:

Tuesday, March 22, 2011

Android Widget Size Calculator

Eventually I want to make a much longer and technical post on this issue... but this is what you will get for right now.

Designing Widgets for Android is kind of a royal pain.  Why?  There are a bazillion different devices, with their own unique resolution!  How do you guarantee that an image/widget of one size, will look the same (or reasonably close) from one device to another?

I struggled considerably with supporting multiple resolutions on the widgets that I have created for Android - and the Google documentation on widget design, and supporting multiple resolutions is high technical and not very intuitive to understand.

Tuesday, March 15, 2011

Introducing Opening Day for Android



It might be a surprise to some of you that I am still a baseball fan (even though I just recently became one).

Opening day is almost here for Major League Baseball, and I have decided to celebrate with a new Android Widget:  Opening Day for Android.

Description in the Android Market:
Opening day for Major League Baseball season is almost here! Don't miss out on the first game, use Opening Day Countdown to keep track.

Note: Not affiliated with MLB.

Keywords: baseball, mlb, opening day



Get it on the Android Market (for free!) here.

Monday, February 28, 2011

openVPN, SliceHost, and OSX

Spent some time at the local coffee shop today, and got really paranoid about others sniffing my wireless bytes...  so I spent the whole visit setting up openVPN on my slicehost.

I found a good guide on the internet, but had to make some modifications to get it to work.

I am currently using the Viscosity openVPN client for osx: http://www.thesparklabs.com/viscosity/

Here is the guide that I used: http://ggin.com/blog/openvpn-setup-on-vps/

Modifications:

(I didn't build it from source)

cp -R /usr/share/doc/openvpn/examples/easy-rsa /etc/open/vpn

Should be:

cp -R /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn

When he says to do: ./vars I had to do source ./vars first.

Before doing:

sudo cp /usr/share/doc/openvpn/example/sample-config-files/server.conf /etc/openvpn/

I had to gunzip the server.conf.gz file and the path should actually be:
/usr/share/doc/openvpn/examples/sample-config-files/

For IPTables rules I used:


sudo vim /etc/iptables.test.rules
*nat
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT
*filter
-A INPUT -i tun+ -j ACCEPT
-A FORWARD -i tun+ -j ACCEPT
-A FORWARD -o tun+ -j ACCEPT
-A INPUT -p udp --dport 1194 -j ACCEPT


.. and that was basically it! Just make sure to use the right files when setting up Viscosity:

CA ca.crt
Cert username.crt
Key username.key

(I don't have User/Pass authentication enabled in the client)

Wednesday, February 23, 2011

HDF5: Fixed length strings

For the sake of Google searches - here is a bit of code on how to create compound data types with fixed length strings in HDF5 H5 files.


/**
* Create the H5 file with the contents of the Data list.
*/
public Boolean create() {
try {
FileInfo h5 = new FileInfo(this.h5Path);

H5FileId fileId = null;
if (this.makeNew) {
fileId = H5F.create(h5.Name, H5F.CreateMode.ACC_TRUNC);
H5F.close(fileId);
}
fileId = H5F.open(h5.Name, H5F.OpenMode.ACC_RDWR);

H5DataTypeId stringMeasurand = H5T.copy(H5T.H5Type.C_S1);
H5T.setSize(stringMeasurand, (uint)MEASURAND_LENGTH);

H5DataTypeId stringChannel = H5T.copy(H5T.H5Type.C_S1);
H5T.setSize(stringChannel, (uint)CHANNEL_LENGTH);

H5DataTypeId tid1 = H5T.create(H5T.CreateClass.COMPOUND,(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(dictStruct)));
H5T.insert(tid1, "Measurand", 0, stringMeasurand);
H5T.insert(tid1, "Rate", MEASURAND_LENGTH, H5T.H5Type.NATIVE_FLOAT);
H5T.insert(tid1, "Channel", MEASURAND_LENGTH+sizeof(float), stringChannel);

// Rank is the number of dimensions of the data array.
const int RANK = 1;
ulong[] attributeDims = new ulong[RANK];
attributeDims[0] = (ulong)data.Count;

H5DataSpaceId spaceId = H5S.create_simple(RANK, attributeDims);
H5DataSetId dataSetId = H5D.create(fileId, "/foo",
tid1, spaceId);

H5D.write(dataSetId, tid1, new H5Array(data.ToArray()));
H5T.close(tid1);

H5D.close(dataSetId);
H5F.close(fileId);

return true;
} catch(Exception ex) {
Console.WriteLine(ex.Message);
return false;
}

return true;
}



/**
* Create a new struct with the specified measurand information.
*/
private unsafe dictStruct addRow(string measurand, float rate, string channel) {
dictStruct retval = new dictStruct();

byte[] mBytes = System.Text.Encoding.ASCII.GetBytes(measurand);
byteCopy(mBytes, retval.measurand,MESSAGE_LENGTH);


retval.rate = rate;

byte[] channelBytes = System.Text.Encoding.ASCII.GetBytes(channel);
byteCopy(channelBytes, retval.channel, CHANNEL_LENGTH);


return retval;
}


And then how you define your struct:


public const int MEASURAND_LENGTH = 16;
public const int CHANNEL_LENGTH = 12;

[StructLayout(LayoutKind.Sequential, Pack=1)]
public unsafe struct dictStruct {

public fixed byte measurand[MEASURAND_LENGTH];
public float rate;
public fixed byte channel[CHANNEL_LENGTH];

}

Sunday, February 20, 2011

What a week for my poor poor Jeep

How many people get their vehicle broken into and rear-ended in the same day?  Well, there's at least one..

I know that I live in a sketchy area for work (Lancaster, CA).  Because of that I usually leave NOTHING inside the jeep, and even leave the doors unlocked.  (Thinking that if they see the doors are unlocked, they won't slash my soft top to gain access to the inside of my vehicle)

My jeep has an after market stereo - and I ALWAYS take the head unit inside with me every single night - except for this one time.  I had been driving the jeep for the last few days, and was really getting tired of bringing everything in at night (and bringing everything back out in the morning), so I decided to just leave the headunit in the (locking) center console of my jeep.  Mistake.

Woke up early on February 16th I saw that the center console of the jeep was wide open, and a few of my random car/electronic manuals were sitting on the passenger seat.  They did it.  They had pried open the center console with a screwdriver (I assume).  I don't imagine it was difficult, the center console is pretty cheap, but still it had to take some effort.

I did not do a complete inventory, but it looks like they walked away with:

  • Stereo head unit

  • Car charger

  • Car dock

  • mini stereo cable

  • caffeinated mintes.  (really? you took my mints??)


Didn't bother calling the police, since it was likely < $100 worth of theft and they took so god damn long to show up the last time one of my cars got broken into.

So the day is off to a great start... and naturally I have a horrible day at work, where nothing works, and nothing works in my favor.

This day also happens to be the last day of work for one of my coworkers. (Who is working at another location)  I had planned to meet him and my other coworkers at a restaurant for a going-away dinner.  It was rainy, the roads were slickish, and I was stopped in traffic at a stop light.  I heard the tires screeching, I heard a metal on metal bang behind me, and then I felt my Jeep being pushed from behind.  I moved a grand total of a foot, threw the e-brake and the hazards, and got out.



Behind me was a rather destroyed looking black Jetta (attached to my rear bumper), and behind her was an old lady driving a CrownVic.

Just when I didn't think the day could get any better, I became the lead car in a three car pile up.

As you can see in the picture to the right, not much damage occurred to the jeep, just a dent under the license plate.  (You can also see a bit of her car still embedded in my bumper!)  I called 911 and they promptly had firetrucks, ambulances, and a CHP officer at my location within 10 minutes.

Have you ever dialed 911 on an Android phone (or even a smart phone) before?  I certainly haven't.  I was surprised to see that Android locks out all data connections for 5 minutes after an "Emergency Call" has taken place, to allow 911 to call you back.  Pretty neat.

The CHP officer collected all of our information, and eventually let me go while he dealt with the severely damaged vehicles.

What a day.

I think I will gladly fork over that additional $80 a month for a garage in my Lancaster apartment now... at least it will give me peace of mind while sleeping at night.

I want to say thanks to TrailGear for their excellent bumper - I can only dream of what sort of damage would have occurred to the rear of my jeep otherwise (still have to bring the jeep to a mechanic to see if the frame has been compromised in anyway).

Thursday, January 20, 2011

Android: Automating Emulator Actions

When testing Android apps in the Android Emulator you often have to trigger multiple events by hand that a real phone would do on its own for a given "real" event, like plugging in a power cable.

Simulating a power cable being connected to the emulator requires two separate events,
power status charging

and
power ac on

To interact with the android emulator you telnet into it to get an interactive shell - which enables you to send all sorts of commands to it.  Typing in commands like the above over and over to simulate a power cable being connected is annoying at best.

On OSX I have written the following python scripts to enable the condition(s) I want with a single command.

#!/usr/bin/python
import telnetlib
tn = telnetlib.Telnet("localhost",5554)
tn.write("power status charging\r\n")
tn.write("power ac on\r\n")


Save that guy as "power_on.py" in your android-sdk/platform-tools directory - and any time you want to simulate the power cable being connected simply type:
power_on.py

... and for an added bonus here is my power_off script:

#!/usr/bin/python
import telnetlib
tn = telnetlib.Telnet("localhost",5554)
tn.write("power status discharging\r\n")
tn.write("power ac off\r\n")

Wednesday, January 12, 2011

Fun with the SwiftKey Trial for Android

SwiftKey is a 3rd party keyboard for Android that features "AI driven auto complete".

Strangely, it seems to offer suggestions for your "next" word when typing, even if you haven't typed anything at all - so I decided to keep accepting the automatically predicated words until it stopped suggesting them.

Here is what it ultimately typed out for me:
Minimize the last few years ago, I am a beautiful person, but I think I put 79,,,,

Nice!

Saturday, January 08, 2011

Eclipse 3.6 Helios and SVN

Upgraded from Eclipse 3.5 to 3.6 today (blazing fast in OSX finally) and found that my SVN plugin didnt work.

Follow the instructions here to fix: http://www.dingobytes.com/tutorial/subversion-install-for-eclipse-helios-3-6

Android: Introducing BatteryUptime Pro

Pro version of the popular Battery Uptime widget!

Keeps track of the time your Android phone is unplugged.  Records your best run time.  (Same as Settings->About Phone->Battery), and charts your battery uptime over the course of the last 30 days.

Pro version of widget also features the ability to refresh more often than every 30 minutes!

Pro version of widget also features a quick way to navigate to the Android System Battery Stats straight from your homescreen!

After installing the widget, connect your phone to AC power and then remove from AC power to start tracking battery uptime.

lightning-iconPro version of the popular Battery Uptime widget!

Keeps track of the time your Android phone is unplugged.  Records your best run time.  (Same as Settings->About Phone->Battery), and charts your battery uptime over the course of the last 30 days.

Pro version of widget also features the ability to refresh more often than every 30 minutes!

Pro version of widget also features a quick way to navigate to the Android System Battery Stats straight from your homescreen!

After installing the widget, connect your phone to AC power and then remove from AC power to start tracking battery uptime.

Available in the Android Marketplace for $0.99

qrcodescreenshot_config
screenshot_chart

Saturday, November 27, 2010

Android: Hacking the lock screen with LiveWallpapers

Toying with making a LiveWallpaper that can display your Google Calendar info (and other goodies) on the lock screen when the phone is locked, and only displaying your wallpaper when the phone is unlocked.

Screen shot 2010-11-27 at 11.27.08 AM