I just shut down cisimple

I just shutdown my first startup, cisimple.  The official line is that the company was acquired, but anyone familiar with startups knows that an “acquisition” this early really means “acqui-hire”.  Here are a few things that I’ve learned, with a few recommendations for anyone thinking of starting their first company:

Learn what you’re not good at.

Find out what the various and incredibly important skillsets required to build a company are.  My background is in engineering, and I’m pretty good at it.  However, in no way did that prepare me to be good at marketing or selling things.  Or accounting for that matter (yuck, outsource it).  Furthermore, these functions are critical to success.

Get real world experience trying to do some of these things.  Do in person sales meetings so you get better at pitching.  In-person is key.  Try using things like ad networks and blog posts to drive traffic.  Look for ways to partner with other companies’ and cross-promote.

You just might find out you’re good at some of these things.  For example, I feel like I’m good at biz dev, and only decent at sales and marketing.  Now I know what kinds of people I need to surround myself with.

Do what you’re passionate about.

The hidden truth about founding a startup is that the vast majority of the time they are not fun at all. I know a few founders who have been pounding on the same company for 3+ years now with very little to show for it and no guarantee of a lucrative exit.  When you add up lost wage potential, the suddenly elusive personal life, and the lost hours of sleep, the sum is an extremely expensive endeavor.

Do it because you eat, sleep and breathe the shit you’re building.  Do it because not doing it would literally drive you crazy.

You’re further than you think you are.

The inside of an early stage startup is messy.  As a result it’s incredibly easy to become insecure about how the rest of the world views your startup and how “far your company has come”.   This can be a trap if you let it and it can lead you to making decisions simply for appearances sake.

Every once in a while I was able to get a glimpse of how the “outside world” viewed our company.  At first, I was incredibly surprised to learn that they believed we were a “real” company.  I mean, we were, but it was hard to feel like it some times.  Learning that we had people’s trust and respect was a truly incredibly thing.

It’s easy to read HN and TC articles about companies that are announcing funding or traction/revenue numbers and feel like “success” is a thousand miles away.  However, behind every success story I’ve heard is a roller coaster of incredibly close calls.  There was a point in time where they were where you are or possibly even worse off.

Build a founder network

The single most powerful tool I’ve been fortunate to acquire is a network of other founders. I cannot overstate the value of these people.  Having other founders to bounce ideas off of, make introductions or just have a beer with is priceless.

I have been incredibly surprised by just how accessible most of these people are.  I’ve learned that in the general case, entrepreneurs respect the struggle and are more than willing to help when they can.  I’ve found this to be true of both first time entrepreneurs as well as several well-known founders that I never thought I’d get a meeting with.

**Obviously, you must reciprocate by being respectful with everyone’s time and pay it forward when you can.

Note: A great way to build your own network is by joining an accelerator program like AngelPad.

Build a great team and do it early.

Building a great team is the single most important job you have.  A great team can (and often does) make the difference between funded and broke.  In fact, I know founders who have raised with no product, traction or revenue which they credit in large part to the strength of the team.

It is important to recognize that when you approach investors, they are looking for team “DNA”.  What this means is they want to see founders from reputable companies that they are familiar with and impressed by.  It’s also worth noting that this may, or may not align with building a team that is good at execution.

Not building a strong team early on was probably the single biggest mistake I made. Also, the earlier you build your team the more invested they will feel in the company.  This is not to say that finding co-founders/early employees is by any stretch an easy task.

Know your market

This was another one of those “business-y” things that my engineering background had not prepared me to think about.  Before selling your car and moving into an RV to start your company try this exercise first:

  • Estimate how much money you can make off of each customer (note: you may have several types of customers).
  • Take that number and multiply it times how many potential customers exist in the world.

This is the absolute maximum amount of money your company could possibly ever make in a perfect world.  If it’s not huge maybe try something else.  Some other questions worth asking:

  • Is this market growing or shrinking? (Dunder Mifflin?)  What’s the annual growth rate?  This is important b/c maybe it’s not a huge market now but in 2-3 years it might be.
  • What percentage of that big number are you going to be able to get in 1 year?  What about 3 years?  If you can build a sustainable business with very low percentages, that’s good.  If you need 25% to break even, that’s bad.
  • What strategies will you use to get those customers? How about 2-3 years down the road?  A good example here is a startup that focuses on low-touch SMB sales for the first year, then transitions into enterprise sales.
  • What is your typical customer spend?  One of our challenges was that developers notoriously don’t like to pay for things.  If the customers in your market are billionaire philanthropists that’s probably better.

Another big mistake I made was not researching the market opportunity in advance.

In summary, the last year and a half has been an incredible experience.  I’ve been asked if I’m still glad I did it and it’s a resounding “hell yeah”.  I’ve learned exponentially more than I would have if I’d stayed at a job and that’s priceless.  Furthermore, this is addictive.  It’s only a matter of time until I get the itch and do it again and next time I will be much better prepared.

Next up for me, I’m the new Director of Product over at Appurify.  If you’re a mobile developer you should check us out.  If you’d like to chat some time, I’m pretty accessible, just shoot me an email: kevin@kevinrohling.com

Finally, I have a few very big thank you’s to make:

  • AngelPadThomas/Carine thank you for creating AngelPad.  There are too many incredible founders that are part of the program to mention here but they’re an amazing support system and I credit them with much of what I’ve learned throughout this experience.
  • Jason Arbon - you are just plain awesome and an endless source of optimism
  • Philipp Stauffer - you took me from 0 to mba, i learned more than i think you know from our meetings
  • David Justice - you took a big chance on a crazy idea, i hope you learned as much as i did

Don’t Over-Engineer Your Engineering Team

As I write this I’m taking a bit of time between jobs.  I decided to take a couple of weeks off to, you know… write blog posts and hack on some stuff.  I won’t get into my reasons for leaving Breezy but it was an amiable separation.  I’ll likely post on this some time down the road. 

Working as CTO in a seed stage startup, was probably about the most fun I’ve ever had at any job.  Actually, I’m not even sure I’d call it a job.  Sure, I got paid, but I was getting to do what I love (build stuff) and hang out with other smart people doing the same.  Most of the time it didn’t feel like a job.

I could go on about things I’ve learned over the last year but one thing I found myself thinking about a lot was what engineering practices we should follow.  You know, should unit tests be required for all of our products?  How do we do QA?  What about deployments? etc.  These sorts of questions didn’t keep me up at night but they were genuine problems to solve and fun ones at that.

A bit about my background:  Ignoring all the random jobs I did before my first engineering gig (pond installations, lifeguard, server, etc.), my “career” in software officially started at Walt Disney World.  This place was about as far from a startup as anyone could contrive.  Hundreds of engineers, cubicles, change control policies. It defined enterprise.  After that I spent some time at Vertigo Software, relatively speaking a much smaller shop with about 50 people.  These guys operate very differently and move much more quickly.  It was an enlightening adjustment.

Having worked in both large and small environments (and medium-ish) I think I’ve become very pragmatic about engineering practices.  What I mean by that is there’s no religion to it.  There are no absolutes. I refute any argument that certain engineering practices should always be followed because it’s the “right” way.  Frankly, that would be too easy an answer.  As with most things in life, pragmatic engineering is about maximizing for the right variable at the right time.

 

Optimizing for Ship Time

When I started at Breezy, we were a small team.  I mean really small, as in just the founder (Jared Hansen) and myself.  He was working on scaring up some customers, meanwhile we needed a product people could touch ASAP.  I wrote a lot of code those days building out our Rails API, our Windows app, etc.  Jared and I both split QA responsibilities and deployments were typically pushed right after the code was committed.  It was strategically expensive to do anything that wasn’t product so very few unit tests were written.  Also, because it was such a small team things like branching strategies had very little value.

Implementing Process

After our MVP (Minimum Viable Product) shipped and our team grew, eventually reaching 5 engineers, a few things changed.  When our intern started, his first task was to retro-fit our API with unit tests.  This added immediate value and helped us discover a few bugs.  More importantly, we were able to refactor with confidence and going forward all new API development happened with unit tests.

Another huge process improvement was the addition of Continuous Integration.  Our Windows application had 4 different builds: 2 distributions (Enterprise & Consumer) x 2 environments (PROD & TEST).  Our Android application had 3 builds: DEV, Marketplace, and Enterprise.  We also had a similar build configuration for Blackberry but unfortunately never got around to setting it up for iOS.  Having all of this automated saved huge amounts of time.  Furthermore, it decreased the likelihood that human intervention would introduce errors into some build destined for Production.

 

Process Levers

There were two levers that I saw impacting how much process we implemented.  The first was product stage.  Early in the game, having something to show interested, potential customers was more important than worrying about how easy it would be to refactor a given piece of code.  We were building an MVP and that has a very different set of goals associated with it than a piece of software for a company that has, well… revenue.

The second, and in my opinion more significant one, was team size.  I think you reach a point at which, no matter what stage your company or product is at, some process is needed to manage the complexity.  Things like branching strategies and standups are very useful for any team larger than 2 engineers for example.  You get a greater degree of flexibility if the team members are developing on independent products.  However, within the same company, especially at a startup, that’s rarely the case.

 

Process Components

Here’s a short list of a few elements that made up our engineering processes.  There are several more I could add to the list (standups, backup schedules, etc.) but these stood out as being more significant.

Task/Bug Tracking – I can’t understate the importance of having a solid process in place for tracking on a task list (or backlog).  When things kicked off a Breezy I started by using a spreadsheet.  We also wrote tons of lists all over our walls.  At the time our office walls were covered in IdeaPaint so we had significant amounts of whiteboard square footage!  I eventually started using a combination of Pivotal and Asana, which are great solutions to this problem but support slightly different use cases (more on that in another post).

Automated Builds – As I mentioned earlier, setting up a Continuous Integration/Automated Build process was a huge process improvement that saved us significant amounts of time. One downside to CI though is that it’s expensive to setup and maintain, and I mean that from an “engineer-time” perspective.  I think our setup was pretty typical, EC2 + Jenkins, but when you factor in environment configuration and maintenance, it adds up.  While I would have liked to have had it earlier it was set up about 3 months into the game (post – MVP).

Unit Testing – Few things inspire crusade-like fervor within engineers quite like the debate over unit testing.  My humble opinion is that Unit Tests are very useful, but they’re also expensive.  For some products/teams they are affordable, however for some they are not.  When we were pre-MVP we could not afford to build unit tests and so none were written.  They were eventually retro-fitted to our Rails API but we never wrote them for our mobile applications.  I’ve been asked if looking back I feel like this was the right decision and I do.

 

Engineering Your Engineering Team

It seems to me that there are many approaches to building software.  In my opinion, different approaches simply seek to optimize different variables.  The best engineers I’ve seen are the ones that are able to shift between approaches at the right times.  Building a good software product (quickly) is a complex equation and there are no right or wrong ways to do it, only more and less efficient approaches.  I think the same goes for building an engineering team.

My Fight Against Homelessness – Apartment Hunting in San Francisco

Let’s face it, apartment hunting is one of those somewhat unpleasant things that perpetual renters have to do every once in a while, kind of like going to the dentist or spending the weekend with your parents (love you mom!). There’s the paperwork, the phone calls, open houses… If you’re shopping in San Francisco you’re probably putting more hours into your search than the realtors that are trying to sell the place to you! Admittedly it’s not all bad, the prospect of moving into a new place can be quite exciting. A new neighborhood means new restaurants and shops nearby, especially in SF, and your apartment is never as clean as when you first move in. Nevertheless, apartment shopping in SF right now is brutal!

The problem is there are way more people looking for apartments in SF than there are apartments, or bed rooms, or closets even. I have no idea how long this has persisted, as far as I know this may or may not, just be how it goes. Nevertheless, it’s not unusual to show up to an open house and find 30 other people there, luggage in tow, ready to stab anyone who gets in between them and their precious 1 bedroom with walk-in closet and brightly lit kitchen area. Like I said, brutal, it’s less apartment shopping and more like tenant shopping. The property owners get more applications than they need to fill the apartment so they’re at the advantage of picking and choosing the lucky winner of an exorbitant rent payment, 300 square feet and a parking space that only exists every other Tuesday at 1:00pm.

So maybe you’ve decided you’re ready to suck it up and damn it… you’re going to live in San Francisco. Well, I hear you, obviously that’s what I’ve done so I understand all the reasoning behind it. If that’s the case I have a few tips that just might make your search a bit less painful, provided you avoid getting stabbed by fellow applicants:

Tip #1: Credit Report With Credit Score. This is the best move I made. Get yourself over to annualcreditreport.com and get your free credit report. Then pay the extra $8 or so to get your FICA score. Why? For starters every place you visit will ask for it. It will save you money because you don’t have to pay a fee for each place to run your credit. This also means your credit doesn’t get dinged 50 times after you’ve submitted applications all over the city. Finally, it makes the process smoother for the property owner and anything you can do to make things easier for them is a gold star in your favor.

Tip #2: Be There First. With all the competition you’ve gotta set yourself apart from the masses and also beat them to the punch. One really good way to do this, and also say “Hi, I’m genuinely interested and responsible” is to show up first. At open houses get there early so you can be at the front of the line (cuz you know there’s a line). Also, check CraigsList multiple times a day. Posts are added throughout the day and if something’s more than 24 hours old, the masses are all over it by then.

Tip #3: Your Rental Resume. I already mentioned the credit report but there’s a few other things you should bring with you. The items that should make up your rental resume are as follows:

I’ve found that the SF Rental Application suffices for nearly everybody, even those companies that have their own application form. Having all of this on hand will make the application process smooth, and saves you and the property owner lots of time (especially you!). I printed out copies of each of these along with a coversheet that included my contact information and put it all in individual plastic folders. Now when I want to apply I just give them one of the folders with everything they need. I’m overly process oriented at times and I haven’t seen anyone else do this but it definitely shows you’ve got your shit together and has saved me enough time to write a blog post about it.

Tip #4: Dress It Up. When you go to an open house or a walk through dress it up a bit. You don’t want to look like you’re already homeless (even if you are), that only raises the question in their mind as to why you’re homeless. Maybe cuz this guy doesn’t pay his rent? Instead your clothes should say “Hi, I’m super responsible and always pay bills on time. I just came from a really responsible meeting where I was doing extremely responsible things. You know, like paying bills and getting paid lots of money.” Yeah, dress like that.

Tip #5: Follow Up. You don’t want to get lost in the shuffle. After the meeting follow up with an email or phone call and just ask if there’s anything else you can provide and make sure they know who you are. If it was an open house, tie it back to the meeting and refer to something recognizable. Part of this process is likability, you’re not very likable if they don’t know who you are.

Good luck with your search. If you’ll join me in following these few simple tips, together we can end homelessness. Probably not for the guy talking to the bushes and camping in Golden Gate Park but at least for ourselves.

World Domination Using Arduinos and Websockets

Arduino Websocket Client Arduino Pusher Client Pusher – Real Time Push Notifications Follow Me On Twitter: @kevinrohling

If you don’t have your very own Arduino yet you should get one. What exactly are you waiting for? Arduinos are tons of fun, especially once you hook up some servos and start driving them around. Add a few pieces of military grade weaponry and you have your very own deathbot!

One of the first things you have to figure out once you’ve decided to personally catalyze the robot apocalypse is how to remotely control your robots, i.e. tell them when to turn left, turn right, stop, and of course… fire rocket launchers. There’s a number of ways you could do this. One of the more common I’ve seen is to open up a server port on your Arduino, connect to it and send it messages directly. The problem I ran into doing this was two fold: 1) I have to know the IP address of the Arduino on my network to make the connection and 2) I have to be on the same network as the Arduino. None of these things are very convenient and IP addresses and networks can change.

The solution I came up with was to use Pusher, a real-time push notification service that runs over WebSockets. Since the native Arduino libraries come with support for TCP connections, making this work involved writing a WebSocket Client library, as one does not appear to have previously existed, and building a Pusher client on top of that. Because the Arduino is connected to a Pusher Channel I don’t have to know anything about the actual device to control it, I just send messages to the Channel. My mechanized Arduinos of destruction are free to roam around, switching networks and destroying civilization, meanwhile I can still control them with my iPad from a hammock in the Bahamas.

Building the WebSocket Client

WebSockets are an interesting hybrid between HTTP and raw TCP connections. They start life very much like a normal HTTP GET request. In the request the client sends a bit information asking for an “upgraded” connection. Once the server sees this, if WebSockets are supported it sends a response back with a status code of 101 indicating that the connection was successfully upgraded. Then, and here’s where things diverge from HTTP, nobody closes the connection. Both the client and the server remain connected to each other. Here’s what this looks like at the socket level:

Client Requests a WebSocket Connection

GET /app/yourpusherapikey?client=js&version=1.9.0 HTTP/1.1
Upgrade: WebSocket 
Connection: Upgrade 
Host: ws.pusherapp.com:80 
Origin: ArduinoWebSocketClient

Server responds indicating that the upgrade was successful

HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket 
Connection: Upgrade 
WebSocket-Origin: ArduinoWebSocketClient 
WebSocket-Location: ws://ws.pusherapp.com:80/app/yourpusherapikey?client=js&version=1.9.0 
Connected

Now that they’re connected both the client and the server can send each other messages any time they want using a process called Data Framing. Data Framing is a protocol for indicating the start and end of discrete messages on the socket. The Arduino Websocket Client Library currently only supports Text Frames, which use a 0×00 byte to indicate the start of a message, a 0xFF byte to indicate the end, and UTF-8 data in between. The WebSocket Specification also allows for Binary Frames, which use a length prefix followed by binary data. Here’s what the Arduino code looks like for sending a WebSocket message:

void  WebSocketClient::send (String data) {
     _client.print((char )0 ); 
     _client.print(data); 
     _client.print((char )255 ); 
}

Building the Pusher Client As I mentioned before Pusher is a real-time push notification service that operates over WebSockets. Like any WebSocket implementation they use Data Framing for passing messages back and forth but they’ve built their own messaging protocol on top of Data Framing. Each message sent to or received from Pusher is formatted as JSON. This is good for the Arduino because JSON is light weight and also easy to parse. Once the Arduino WebSocket Client was built developing the Arduino Pusher Client was a matter of implementing support for sending/receiving the right messages.

Sending a message is called “Triggering An Event”:

void PusherClient::triggerEvent(String eventName, String eventData) {
    _client.send("{\"event\": \"" + eventName + "\", \"data\": " + eventData + " }");
}

Receiving a message from Pusher:

 
void  PusherClient::dataArrived(WebSocketClient client, String data) {
     String eventNameStart = "event" ; 
     String eventName = parseMessageMember("event" , data); 

     if  (_bindAllDelegate != NULL ) { 
         _bindAllDelegate(data); 
     } 

     EventDelegate delegate = _bindMap.getValueOf(eventName); 
     if  (delegate != NULL ) { 
         delegate(data); 
     } 
}

Controlling our servos of destruction in response to events received from Pusher:

PusherClient client("your-api-key-here");

//Setup delegates for the Pusher Events
client.bind("forward", moveForward);
client.bind("backward", moveBackward);
client.bind("turn_left", turnLeft);
client.bind("turn_right", turnRight);
client.bind("stop", stopMoving);

//Subsribe to our Pusher Channel
client.subscribe("robot_channel");

void moveForward(String data) {
  leftServo.write(0);
  rightServo.write(180);
}

void moveBackward(String data) {
  leftServo.write(180);
  rightServo.write(0);
}

void turnLeft(String data) {
  leftServo.write(0);
  rightServo.write(0);
}

void turnRight(String data) {
  leftServo.write(180);
  rightServo.write(180);
}

void stopMoving(String data) {
  leftServo.write(95);
  rightServo.write(95);
}

All Wired Up

We’ve now solved what is likely the most challenging part of developing your Arduino army.

Pusher messages being received:



Tremble in fear of the Pusher Powered Arduino-Bot:



Polling is Evil, Start Pushing





It’s an exciting time to be working at Breezy right now. We’re past the initial rush to build our MVP and can finally loop back around and focus on making things more awesome. One of the biggest challenges we’ve had to solve is how we notify our Connector applications that documents are ready to print. A bit of context, the Connector is a piece of software that sits on desktop PC’s that have printers. When a user chooses to print to a printer that’s “connected” to this PC we notify the Connector and it does the work of actually sending the document to the printer.

It’s magic and it works. So what’s the problem? The problem is we currently solve this notification challenge by having the Connector poll our web service. This is less than optimal for a number of reasons: 1) This places a significant (seriously…) load on our backend infrastructure 2) This introduces latency because the Connector is polling on an interval. Finding a better solution is difficult because most of these Connector installations are sitting behind firewalls and are on a consumer’s home network. This means you can’t expect any additional setup other than installation of the software so any sort of direct connection initiating from the server is out of the question.

So what’s option 3? In a word Websockets. This nifty little protocol has silently made its way into web browsers and web servers over the last few years. It’s most common use case is allowing servers to send messages to web browsers, allowing the display of real time data and notifications. Web Sockets are similar to long lived HTTP connections except that they allow bi-directional messaging between both the client and the server. After the initial handshake the connection is “upgraded” after which time data is exchanged using a process known as Data Framing. Websockets also run over HTTP/S ports 80 and 443 so there’s no worry that they’ll be blocked by firewalls. For these reasons Websockets are also a great solution to our Connector’s polling problem.

Cool, so Websockets, now what? We could have built a Websocket server that’s capable of handling thousands of live connections at a time, implemented a nice security layer and defined our own messaging protocol but… that’s a lot of work. It’s a beautiful world we live in where people build these sorts of things for us and let us use them. That’s where Pusher came in.




Why did we choose Pusher?
Pusher didn’t just save us time it made refactoring our architecture possible. The work required to implement a notifications infrastructure that would handle our traffic requirements is simply intractable for us. Furthermore, out of the box it has many of the less obvious features we needed like security, presence information and a well documented messaging protocol.

What problems did Pusher solve?
Pusher allowed us to offload the vast majority of our backend traffic to their notifications infrastructure. This will result in significantly improved performance and dramatically lower costs as we scale. Furthermore, this adds value to our customers because we can print a document in “real-time” rather than forcing them to wait several seconds for the next poll.

What was missing from Pusher?
One feature I’d like to see added is the ability to receive callbacks when clients connect to a Channel. This would help us keep track of what Connectors are actively connected and ready to receive notifications. Currently our workaround is a process that is constantly checking with the Pusher API to see who’s active. This has been somewhat time consuming and challenging to develop, it’d be nice if we could remove this “moving part” in the future. I’ve talked to some of the Pusher guys and it sounds like this is on their near-term roadmap, definitely looking forward to seeing it.

Also, they seem to have their client libraries separated into Client and Server functionality. This provided a bit of a challenge for us because we needed some of the “client” functionality available from our backend which is written in Rails. This meant that we had to add this functionality to the Pusher gem, also a bit time consuming. For our scenario it would have been nice to see a single gem that encompassed both client and server functionality but frankly I’m not sure how common that is.


Using a Slide Transition with the Android ViewFlipper

Github Repo

If your app only has one View, your app is probably pretty boring. However, if you’re building an interesting app you’ll probably have to switch between multiple Views, maybe go back and forth and have some nice animations. You could write your animations and manually do the transitioning yourself but once you get more than 2 or so Views that’s gonna get tough to keep up with (and messy!). Fortunately the ViewFlipper solves this problem quite nicely.

Step 1.

Let’s start all the way at the beginning, File -> New Android Project. Feel free to use your own Application and Package Names but make sure you tell it to create a MainActivity. This will be the Activity that controls the transition between Views.

clip_image002

Step 2.

Once you get your project set up you’ll need to add a ViewFlipper to main.xml. In this example we’ll also add a couple of buttons that let us go back and forth between our Views.

main.xml

1 <?xml version=”1.0″ encoding=”utf-8″?> 2 <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221; 3 android:orientation=”vertical” 4 android:layout_width=”fill_parent” 5 android:layout_height=”fill_parent”> 6 7 <LinearLayout android:orientation=”horizontal” 8 android:layout_width=”fill_parent” 9 android:layout_height=”wrap_content”>10 <Button android:id=”@+id/previousButton”11 android:text=”Previous”12 android:layout_width=”wrap_content”13 android:layout_height=”wrap_content”/>14 <Button android:id=”@+id/nextButton”15 android:text=”Next”16 android:layout_width=”wrap_content”17 android:layout_height=”wrap_content”/>18 </LinearLayout>19 20 <ViewFlipper android:id=”@+id/viewFlipper”21 android:layout_width=”fill_parent”22 android:layout_height=”fill_parent”>23 <TextView android:layout_width=”fill_parent”24 android:layout_height=”wrap_content”25 android:text=”View 1″/>26 <TextView android:layout_width=”fill_parent”27 android:layout_height=”wrap_content”28 android:text=”View 2″/>29 <TextView android:layout_width=”fill_parent”30 android:layout_height=”wrap_content”31 android:text=”View 3″/>32 </ViewFlipper>33 </LinearLayout>34

Step 3.

Next in MainActivity ‘s onCreate method, wire up ClickHandlers to the Buttons and use the ViewFlipper’s showNext() and showPrevious() methods to move between Views.

MainActivity

1 publicvoid onCreate(Bundle savedInstanceState) { 2 super.onCreate(savedInstanceState); 3 setContentView(R.layout.main); 4 5 final ViewFlipper viewFlipper = (ViewFlipper)findViewById(R.id.viewFlipper); 6 7 Button nextButton = (Button) this.findViewById(R.id.nextButton); 8 nextButton.setOnClickListener(new OnClickListener() 9 { 10 11 @Override 12 publicvoid onClick(View v) { 13 viewFlipper.showNext(); 14 } 15 16 }); 17 18 Button previousButton = (Button) this.findViewById(R.id.previousButton); 19 previousButton.setOnClickListener(new OnClickListener() 20 { 21 22 @Override 23 publicvoid onClick(View v) { 24 viewFlipper.showPrevious(); 25 } 26 27 }); 28 29 }

Step 4.

Now, if all you wanted was a simple transition between Views you could stop now. However, that would be… boring and we can do a heck of a lot better by adding a nice slide transition. To make this work we’ll use the 4 animations below. These allow us to slide in and out from either direction depending on whether we’re going forward or backward and they also add a very subtle alpha fade in and fade out. If you’re interested in checking out other types of animations look no further than your Android SDK directory: Android_SDK\Platform\android-{version}\samples\ApiDemos\res\anim

view_transition_in_left.xml

1 <?xml version=”1.0″ encoding=”utf-8″?>2 <set xmlns:android=”http://schemas.android.com/apk/res/android&#8221;>3 <translate android:fromXDelta=”100%p” android:toXDelta=”0″ android:duration=”300″/>4 <alpha android:fromAlpha=”0.0″ android:toAlpha=”1.0″ android:duration=”300″/>5 </set>6

view_transition_in_right.xml

1 <?xml version=”1.0″ encoding=”utf-8″?>2 <set xmlns:android=”http://schemas.android.com/apk/res/android&#8221;>3 <translate android:fromXDelta=”-100%p” android:toXDelta=”0″ android:duration=”300″/>4 <alpha android:fromAlpha=”0.0″ android:toAlpha=”1.0″ android:duration=”300″/>5 </set>

view_transition_out_left.xml

1 <?xml version=”1.0″ encoding=”utf-8″?>2 <set xmlns:android=”http://schemas.android.com/apk/res/android&#8221;>3 <translate android:fromXDelta=”0″ android:toXDelta=”-100%p” android:duration=”300″/>4 <alpha android:fromAlpha=”1.0″ android:toAlpha=”0.0″ android:duration=”300″/>5 </set>

view_transition_out_right.xml

1 <?xml version=”1.0″ encoding=”utf-8″?>2 <set xmlns:android=”http://schemas.android.com/apk/res/android&#8221;>3 <translate android:fromXDelta=”0″ android:toXDelta=”100%p” android:duration=”300″/>4 <alpha android:fromAlpha=”1.0″ android:toAlpha=”0.0″ android:duration=”300″/>5 </set>6

Step 5.

Finally, we need to update MainActivity to set the ViewFlipper’s inAnimation and outAnimation properties. We’ll use a slide in from the left when the user clicks “Next” and we’ll slide in from the right when the user clicks “Previous”.

1 publicvoid onCreate(Bundle savedInstanceState) { 2 super.onCreate(savedInstanceState); 3 setContentView(R.layout.main); 4 5 final ViewFlipper viewFlipper = (ViewFlipper)findViewById(R.id.viewFlipper); 6 7 Button nextButton = (Button) this.findViewById(R.id.nextButton); 8 nextButton.setOnClickListener(new OnClickListener() 9 { 10 11 @Override 12 publicvoid onClick(View v) { 13 viewFlipper.setInAnimation(MainActivity.this, R.anim.view_transition_in_left); 14 viewFlipper.setOutAnimation(MainActivity.this, R.anim.view_transition_out_left); 15 viewFlipper.showNext(); 16 } 17 18 }); 19 20 Button previousButton = (Button) this.findViewById(R.id.previousButton); 21 previousButton.setOnClickListener(new OnClickListener() 22 { 23 24 @Override 25 publicvoid onClick(View v) { 26 viewFlipper.setInAnimation(MainActivity.this, R.anim.view_transition_in_right); 27 viewFlipper.setOutAnimation(MainActivity.this, R.anim.view_transition_out_right); 28 viewFlipper.showPrevious(); 29 } 30 31 }); 32 33 }

Finally, run your app and behold the wonder that is the ViewFlipper sliding your Views in and out!

Building an Android Splash Screen

Github Repo

Splash Screens are a common feature of many apps. They’re a nice way to show off the awesomeness that is your logo or maybe just dazzle your users with some eye candy while your app downloads things from the web, crunches numbers, or calculates the 2000th digit of the number pi. Whatever your reasons are for building a Splash Screen you’d probably like it to have a few nice features. This example shows how to build a Splash Screen that removes the title bar, fixes the screen in Portrait layout and prevents the user’s back button from returning them to the Splash Screen.

Step 1.

Let’s start all the way at the beginning, File -> New Android Project. Feel free to use your own Application and Package Names but make sure you tell it to create a SplashActivity. This will be the brains of our Splash Screen.

image_thumb2

Step 2.

We need to add another Activity to our application that we can transition to when our Splash Screen is done. Add a new Activity named MainActivity and create a new layout XML file named splash.xml. Then configure the SplashActivity to use the splash.xml file for it’s layout and the MainActivity to use main.xml. If you’d like to make changes to these layout files to spruce things up go ahead. For this example I’ve added an image to the SplashActivity and changed the text in main.xml to read “Hello World, MainActivity!”

Here’s what your package should look like.

image_thumb4

MainActivity

image

SplashActivity

image

Step 3.

Once your project is set up, open SplashActivity.java and we’ll make a few changes. Add a variable named splashDelay to hold the length of time to keep the Splash Screen up. Then we’ll use a Timer and a TimerTask to help us schedule the transition to MainActivity. Note that before starting the new Activity we call the finish() method on the SplashActivity. This prevents the user from being able to use the back button to return to this Activity.

image

Step 4.

Finally, we need to make two changes to AndroidManifest.xml. Set the application element’s theme attribute to Theme.NoTitleBar to get rid of the Title Bar and on the SplashActivity’s activity element, set the screenOrientation attribute to portrait to fix the SplashScreen to portrait layout.

image

And finally our Splash Screen.

image_thumb7

Social Smurf: A Social Media Plugin for SMF

Live Example
Source Code
SocialSmurf XAP (rename from .zip to .xap)
PluggableSmoothStreamingPlayer XAP (rename from .zip to .xap)

image

Intro

July 7th marked the release date of the 2nd version of the Silverlight Media Framework, aka SMF, aka the Smurf. It was such a big deal that everyone took Monday off of work and celebrated over the weekend with fireworks and BBQ’s! What? Didn’t hear about it? Busy celebrating some other holiday? Well then check it out, no it’s cool I’ll wait…

Ok, now that you’ve built your first Silverlight video player capable of handling huge online video events like SNF and the Olympics I think we can move on. So while technically this wasn’t a national holiday it was still a great day for a very cool framework. Of course I toss around words like “great” and “very cool” but admittedly I am a little biased given that I’m the project lead. Nevertheless, we’ve been getting some good feedback and I’m constantly hearing about new projects spinning up that are using SMF. Take a look at the forums, there are many smart folks building innovative video projects. One of the coolest I’ve seen recently is Nascar 3D. By the way, if you’re one of those folks who happen to post in the forums give me a shout via twitter some time. I try to reply quickly but, unfortunately I have to sleep sometimes, and I have a girlfriend, she prefers my eyes be glued to her and not the monitor sometimes J

One of my favorite new features in SMF v2 is definitely the plugin framework. SMF has a number of extensibility points you can plug into, like adding on screen UI elements, Logging, and supporting the playback of new types of media. What makes this really interesting to me is the built in ability to support downloading plugins over the network, thanks to integration with MEF. This allows developers to easily share and distribute plugins for SMF.

For a while now, I’ve had an idea of my own for a plugin that would integrate SMF with social media networks. What I want it to do is let users easily share a link to, not just the video, but the position in the video that they’re watching at that moment. Let’s take a quick look at how to do this.

Step 1. Build the Control

The control itself is pretty straight forward. It’s a horizontal StackPanel with a series of buttons, one for each network: Twitter, Facebook, LinkedIn, Delicious, and Email (not really a social network but still a cool way to share video). When the user clicks on a button, we build the URL that we’re going to share and launch a popup window that allows them to post to the network they clicked on. Each network has a different URL, I used this site to get the format needed to support each of the ones I’m using here.

Step 2. The SMF Plugin

As I mentioned, SMF supports a number of plugin types. Implementing a plugin has two parts: 1) Implement the interface and 2) Add the Export Attribute. In case you’re wondering what #2 is all about, SMF uses MEF (Managed Extensibility Framework) to discover and load plugins. A discussion of MEF is well outside of the scope of this post but it’s a very useful framework and I owe Glenn Block a public “thanks” for his guidance on using MEF to build a plugin framework.

For this example I’m implementing a Generic Plugin, which gives me a reference to the SMFPlayer instance. When my plugin gets a reference to the player I search the visual children for a Grid named PlayerRoot and add SocialSmurf to its children. To do this I need to implement the IGenericPlugin interface and add the ExportGenericPluginAttribute to my class. All SMF plugin attributes take as parameters the name, description, and version of my plugin.

Step 3. Supporting the PluginUrl InitParam and “Link To Position”

The SMF v2 release on CodePlex includes two prepackaged XAP files, one for Smooth Streaming and a smaller one that only supports Progressive Download. This allows you to easily embed the SMF player into your web site without having to write a line of code or even open Visual Studio. Instead you can configure the player using init params in your HTML file. One of my goals for this plugin was to make it as easy as possible to load into an SMF application and to do this I wanted a prepackaged XAP file that would support the loading of plugins via init params as well. Since this feature isn’t currently supported in the public version of SMF I decided to tweak the existing Smooth Streaming Player and add this feature.

Finally, I wanted to support “Link To Position”, letting users share specific positions within the video. Supporting this is pretty simple, I just check the query string for a variable named “position” and parse it the value into a TimeSpan.  After that, I wait for the Player’s MediaOpened event to fire and call SeekToPosition(…) on the player setting it to the specified position.

Summary

This was pretty quick and easy, I think I had a functional prototype up and working in about an hour.  The most time consuming part was, by far, doing the string parsing necessary to create the URLs that launch the different social media sites.  Also, adding the position to the URL was tricky as well given edge cases, like when there are already parameters on the query string.  There’s probably a better way to do this but it did the job.  The SMF integration was a piece of cake, however, I must admit that I do have an unfair advantage given my hand in writing it.  That said, I’d love to hear any feedback.  Is this really easy to the average dev?  How could something like this be made better??  Seriously, I’d love to know!   Also, if you think this is a generally useful plugin let me know if you have any feature ideas.

To add this plugin to your SMF application:

Uri pluginSource = new Uri(““http://www.enginexp.com/files/socialsmurf/socialsmurf.zip””)
player.BeginAddExternalPlugins(pluginSource);

To include this player in your site, add the following HTML snippet:

<object data=”data:application/x-silverlight-2,” type=”application/x-silverlight-2″ width=”100%” height=”100%”>
<param name=”source” value=”http://www.enginexp.com/files/socialsmurf/pluggablesmoothstreamingplayer.zip&#8221;/>
<param name=”minRuntimeVersion” value=”4.0.50401.0″ />
<param name=”InitParams” value=”pluginurl=http://www.enginexp.com/files/socialsmurf/socialsmurf.zip,
mediaurl=[Insert Your Video Url Here]“
/>
</object>

Geolocation Search with SQL Server

As some of you may know, as a side project, I’m building an app that involves geo-location and social media.  When I went to build the geo-location part of the app my requirements were pretty simple.  I have people in my application with lots of GPS data and given a specific GPS coordinate, maybe where I’m standing now, I need to search all those people and see who is nearby.  So how to do this?  Well, you obviously don’t want to do this in the application, right?  You’d have to pull all that data back and do a search in memory.  The database is a much better place, and fortunately SQL Server 2008 (and now SQL Azure) have geospatial support.  Here’s a great MSDN article with more information.  And this is a simplified version of the Stored Procedure I came up with that will search a database table (Location) for all records within a specified distance (meters) of a target lat/lon position:

CREATE PROCEDURE SearchLocation (
    @SearchLatitude decimal(12, 8),
    @SearchLongitude decimal(12, 8),
    @Distance decimal(12, 8))
AS
BEGIN
    SET NOCOUNT ON

    SELECT  l.UserId
    FROM    Location l
    WHERE   l.LocationPosition.STDistance(geography::Point(@SearchLatitude, @SearchLongitude, 4326)) < @Distance
END
Follow

Get every new post delivered to your Inbox.