Damian Mehers' Blog Evernote and Wearable devices. All opinions my own.

2Nov/140

Using the Evernote API from Swift

There is a fine Evernote iOS SDK complete with extensive Objective C examples.  In this blog post I want to share what I did to get it working with Swift.

First I created a new Swift iOS app (called “orgr” below), then I copied the ENSDKResources.bundle and evernote-sdk-ios sources ….

image

… into the new project, and added references to MobileCoreServices and libxml2 per the SDK instructions.

image

In order for the Swift code to see the Evernote Objective C SDK, I enabled the compatibility header and pointed it to a header in the SDK that included all the other headers I needed.

image

I also found (YMMV) that I needed to add a reference to the libxml2 path under Header Search Paths

image

Once I’d done this, I was able to build.  Next it was simply a question of translating the Object C example code to Swift.  This is the minimal example I came up with:

image

You’ll need to replace “token” and “url” parameters with the values you can obtain using the developer token page. This simple example just logs my notebooks.  Next steps are for you …

Filed under: Evernote, iOS No Comments
1May/142

Evernote on your Pebble: your desktop duplicated?

At first glance it might look as though Evernote on the Pebble is a simply a clone of Evernote for the desktop.  image  pebble-screenshot_2014-03-15_13-17-53pebble-screenshot_2014-03-15_15-01-35

That would make absolutely no sense whatsoever, given that the Pebble has an entirely different form factor, with very different uses.

I’d like to share some of the ways in which Evernote on the Pebble has been tailored to the wrist-based experience, and what you can do to get the most out of it.   But first …

A step back … why wearables?

Earlier this year at the MCE conference I presented a hierarchy of uses for wearable devices:

  • Notifications, especially smart notifications based on your context, for example based on your current location, or who you are with, such as those provided by Google Now;
  • Sensors, especially health sensors, but also environmental sensors. Very soon we will examine the devices of someone who just died, as a kind of black box to determine what happened.
  • Control of the environment around you, such as the music playing on your phone or your house lights. The key is that you have to be able to do it without thinking about it … maybe gesture-based controls.
  • Capture of information, such as taking audio notes, or photos from your watch or Glass.
  • Consumption of information, such as viewing Evernote notes.  The key to this being useful is that the effort to view the information on your watch must be significantly lower than the effort to pull out your phone, unlock it, start the appropriate app, and navigate/search for the information.  Ideally the information should be pre-prepared for easy consumption based on your context, such as where you are, or what you are doing.

How does Evernote fit in?

Notifications work without the Evernote Pebble app

The Pebble already provides notifications from apps, so that when an Evernote reminder notification fires on your Phone …

05  … you’ll see that notification on your watch… 07

As the Evernote phone apps become more sophisticated about providing smarter, context-based notifications, you’ll get that for free on your watch. 

The Evernote app for the Pebble is very much focused on the last item in that list: consumption.

Easy access to your most important information: Your Shortcuts

On the desktop and mobile versions of Evernote, you use Shortcuts to give you easy, instant access to your most important information. Perhaps its information that you always need to have at your fingertips, or that you are working on right now.

08

It stands to reason that on the Pebble we’d give you an easy way to access those Shortcuts, and we do:

09 10

But wouldn’t it be cool if you could access your most important information, your shortcuts, as soon as you start Evernote? 

]1112

We thought so too, which is why you can put your Shortcuts at the top level menu, before all the other Evernote menu items, so that you can see your most important stuff instantly:

131415

Context-sensitive information: nearby notes

If you are about to walk into a meeting, or into a restaurant, then nearby notes are your friend:

16

This shows the notes that you created closest to your current location (yes, you can toggle between miles and kilometers), so that if you are about to go into a meeting with someone …

17

… you can quickly remind yourself about the person you are about to meet:

1819

Activity-sensitive information: a custom checklist experience

Ideally Evernote for the Pebble would automatically detect that you are in the supermarket, and present you with your shopping list.  It doesn’t do that yet, but it does make it easy for you to check and uncheck checkboxes.

Specifically it looks for all your notes that have unchecked checkboxes in them, and presents them as a list.  If you choose one, then it just displays the checkboxes from the notes, and lets you check/uncheck them.

This makes for a super-convenient shopping experience.  If you’ve ever had to juggle a small child in one hand, a supermarket trolley in the other hand, and a mobile phone in the other hand, you’ll really appreciate being able to quickly and easily check items off, as you buy them:

pebble-screenshot_2014-03-15_15-02-202122

What’s more, if you remembered to use Evernote on your phone take a photo of the yoghurt pot back home, because you knew that you were likely to be overwhelmed when faced with a vast array of dairy produce at the shop …

24

… then you can navigate to that note on your watch, and glance at the photo:

25

The Pebble’s screen is quite small, and black-and-white, so you may need to squint a little to make out the photo!

Easy access to your most important notes: Reminders

If you don’t make much use of Reminders, then you might be a little puzzled to see a dedicated Reminders menu item on the Pebble:

26

The reason is that many many people use Reminders as a way of “pinning” important notes to the top of their notes list.  Reminders are always shown at the top of the note list on the desktop apps:

27

On your Pebble you have quick and easy access to these important notes:

26pebble-screenshot_2014-03-15_21-57-31

You can view a reminder:

29

And you can mark it as “done” by long-pressing:

30

Information at a glance.  When is it a chore, and when is it a glance?

The ideal Evernote experience on your watch gives you instant access to your most important information.  Evernote on the Pebble does this by giving you quick and easy access to your shortcuts, nearby notes, checklists and reminders.

But sometimes, that isn’t enough.  Then you have a choice: do you pull out your phone, unlock it, start Evernote, and search or navigate to the information you want? Or, if it is a small text note, might it be easier to navigate to it on your watch?

Depending on what kind of a person you are, and on how you use Evernote, the idea of navigating to your notes on your watch, by drilling down using Tags (for example) might seem either laughably complex, or super-cool and powerful.  If you are an early-adopter of wearable technology, for example if you were a Pebble Kickstarter backer, then chances are you fall into the second camp.

This is the reason for the other menu items I have not discussed above: Notebooks, Tags, and Saved Searches.  For some people, it would be much easier to quickly drill down to a note on their watch, than to pull out their phone.

31343536

Glancability may not be a real word, but if it were, it would be in the eye of the beholder.

The future of Evernote on wearables

By providing you with a customized experience on the Pebble, Evernote serves you information based on what is most important to you (shortcuts and reminders), what makes sense based on your current context (nearby notes, checklist notes) as well as the more traditional ways of accessing your notes (notebooks, tags, saved searches).

These are very early days for wearable technologies.  Evernote for the Pebble is a start … as the capabilities of wearable devices evolve, so will your Evernote wearable experience.  Evernote is very much about working in symbiosis with you, completing your thoughts for you, providing information to you before you even know you need it.  There is so much more to come.

Filed under: Evernote, Pebble 2 Comments
25Jan/142

Evernote tip 9: Index the physical

Like a lot of people I rely on Evernote as my external brain, but my use of Evernote extends beyond the digital realm to the physical realm too.

But first, a quick quiz. Can you identify this?

image

No? You know what? Neither can I. But somehow this weird piece of plastic turned up in my home office one day, and I was left with a dilemma with which I am sure you too are familiar.

Throw it away?

On the one hand, I could throw it away. The thing is, if I did that, then you can be absolutely sure that within a week or so, it will turn out that that piece of plastic was absolutely vital to the functioning of a critical piece of household equipment.

image

“File” it?

On the other hand, I could decide to "file" it in that drawer I have. You don't know which drawer I mean? Oh yes you do, it’s the same one you have, filled with cables for phones you no longer have, remote controls , batteries that may or may not be charged, and yes, nameless pieces of plastic.

If I decided to put it in that drawer then I can be equally sure I would never need it, and the only time I might touch it again is when I move house, although even that isn't a sure thing. There is a fair chance it might follow me to my grave...

image

Evernote to the rescue

So what do I do? I choose the second option, BUT before I "file" it in that drawer or box, I also file it in Evernote by taking a photo and putting it in Evernote, and tag it to say where it is. This means that whenever I find out that I need that piece of plastic, all I need to do is scan through my "real world" notes and I can quickly and easily retrieve it.

image

image

Of course this use of Evernote isn't restricted to anonymous pieces of plastic. I also use it to file other small objects that I can't quite bring myself to recycle, but which I know I won't be needing in the near future:

image

Filed under: Evernote 2 Comments
10Nov/130

Evernote, JavaScript and the Pebble watch

Pebble just released a public beta of their new SDK,  version 2.0, and one of the more intriguing features is the ability to write JavaScript code that executes within the Pebble phone app.

No, that’s not a typo, the JavaScript executes on the phone.

Why would you possibly want to write JavaScript on the your phone?  For very good reasons:  Pebble watch apps can generally do very little by themselves.  Instead they communicate with a custom app that runs on the phone, and that custom phone app does stuff on behalf of the watch app.

For example if I wanted to write an Evernote client than ran on the Pebble watch, I’d code the watch app in C, and then create a custom Android app in Java.  My watch app could talk to my Android app, which could in turn talk to Evernote.  This is in fact what I did in an experimental client I talked about recently at a conference.

Android and iOS

But the Pebble doesn’t just support Android: it also supports the iPhone.  If I wanted to extend my app to iOS I’d need to write an equivalent app in Objective C, or C#. I’d have to duplicate my coding and testing.  There are also Bluetooth issues on iOS with the Pebble, which stop more than one app from communicating with the watch at a time, and the app needs to be whitelisted.

So when Pebble announced that they supported writing JavaScript apps that ran on the phone, hosted within a JavaScript engine that ran within the Pebble phone app on both Android and iOS, this seemed appealing.  I’d not need to write a custom Android app, and a custom iOS app.  Instead I could code up the phone functionality in JavaScript, and all would be good.

But first, I need to check that I could talk to Evernote’s cloud API using the Pebble JavaScript implementation ...

Evernote and Thrift

The Evernote service API is exposed using a technology called Thrift.  Originally developed at Facebook, and now hosted by the Apache Foundation, you define your API using a Thrift Interface Definition Language (IDL).  This IDL is consumed by Thrift code generators which generate language-specific bindings allowing you to access the interface from Java, C#, PHP, and many other languages, including, of course, JavaScript.  The generated code talks to a Thrift runtime, which sends and receives bits over the wire to the corresponding service.

I thought I’d start off by making the Pebble phone-based JavaScript app talk to Evernote, and then once I had that working, I could make it talk in turn to my C watch app.

I downloaded the Evernote JavaScript SDK from GitHub which contains both the generated “proxy” classes generated from the Thrift IDL, and the Thrift Runtime classes, both in JavaScript.

I decided to start simple, and just list my Evernote notebooks:

// Get these by creating an account and logging in to sandbox.evernote.com and then
// going to https://sandbox.evernote.com/api/DeveloperToken.action
var authTokenEvernote = "...";
var noteStoreURL = "https://sandbox.evernote.com/shard/s1/notestore";

// We want to talk the Thrift Binary protocol over HTTP. These classes are in the
// Thrift runtime
var noteStoreTransport = new Thrift.BinaryHttpTransport(noteStoreURL);
var noteStoreProtocol = new Thrift.BinaryProtocol(noteStoreTransport);

// We want to talk to Evernote's NoteStore service. This is generated code
var noteStore = new NoteStoreClient(noteStoreProtocol);

// Ask Evernote what notebooks I have
noteStore.listNotebooks(authTokenEvernote, function (notebooks) {
console.log(notebooks);
});

I put this into a file I called main.js but I also needed to include the Thrift runtime (thrift.js and pebble-js-app.js) and the generated Evernote proxies (including NoteStore_types.js and NoteStore.js).

Since this release of the Pebble SDK only supports a single JavaScript file, named pebble-js-app.js, I borrowed a script volunteered by Matthew Tole that validated the JavaScript and merged all the files together in a single file, and built and ran the Pebble app:

clear
jshint js/main.js || { exit 1; }
jshint pebble/appinfo.json || { exit 1; }

#uglifyjs js/libs/evernote-sdk-js/evernote-sdk-js/thrift/lib/thrift.js ... js/main.js -o pebble/src/js/pebble-js-app.js
cat js/libs/evernote-sdk-js/evernote-sdk-js/thrift/lib/thrift.js ... js/main.js > pebble/src/js/pebble-js-app.js
cd pebble
pebble clean
pebble build || { exit 1; }
if [ "$1" = "install" ]; then
pebble install --logs
fi
 

The first error I hit when I tried running the code, is that the Thrift JavaScript runtime expects to be able to use the DataView class, which is part of the JavaScript Typed Arrays mechanism, a work in progress:

[INFO    ] * :0 JS: pbnote: JavaScript app ready and running!
[INFO ] * :0 Error: pbnote: ReferenceError: Can't find variable: DataView at line 819 in pebble-js-app.js

It turns out although it is not documented, or supported, that there is a partial Typed Array implementation: the Pebble JavaScript Engine has an implementation of the ArrayBuffer type, as well as Int8Array, Uint8Array, etc.  There are some peculiarities, such as the ArrayBuffer supporting the slice method, but not the byteLength property.

So I went looking for an ArrayBuffer implementation I could use, and came across Joshua Bell’s implementation on GitHub.

I included it in the build script, but it did nothing.  Upon further examination, I discovered that it looks to see if there is an existing implementation and (very politely) does nothing if it finds one.  I didn’t want that:

global.ArrayBuffer = ArrayBuffer;
// global.ArrayBuffer = global.ArrayBuffer || ArrayBuffer;

I ran once again, but this time I hit a brick wall.  This is the code flow for the call to noteStore.ListNotebooks above:

  • My code calls listNotebooks which is in the NoteStore.js generated class
  • listNotebooks calls send_listNotebooks in NoteStore.js
  • send_listNotebooks writes out a listNotebooks message to the BinaryProtocol Thrift Runtime type I initialized in my code above
  • listNotebooks continues with a call to send in the BinaryHttpTransport Thrift Runtime type I also initialized above
  • the BinaryHttpTransport initializes an XMLHttpRequest and sends off the message that was built up previously.

The trick though, is how it sends the message, which you can see in the last line of this code:

var xhr = new XMLHttpRequest();
xhr.open('POST', this.url, /*async*/true);
xhr.setRequestHeader('Content-Type', 'application/x-thrift');
xhr.setRequestHeader('Accept', 'application/x-thrift');
xhr.responseType = 'arraybuffer';

xhr.onload = function (evt) {
this.received = xhr.response;
this.offset = 0;
try {
var value = recv_method.call(client);
} catch (exception) {
//console.log(JSON.stringify(exception));
value = exception;
callback = onerror;
}
callback(value);
}.bind(this);

xhr.onerror = function (evt) {
//console.log(JSON.stringify(evt));
onerror(evt);
};

xhr.send(postData.buffer);

It attempts to send a Uint8Array’s buffer.  I hacked up a dummy web server, and it turns out I was receiving the result of a toString call, which was something like “object ArrayBuffer”…

The Pebble JavaScript engine’s XMLHttpRequest only supports sending string data, not binary data.  It doesn’t support sending Typed Arrays.

I tried all kinds of things, but finally admitted defeat, for now.

The concept of having your watch app talk to JavaScript code, which in turn talks to the outside world is very appealing.  It means that you don’t have to write, test and maintain separate iOS and Android “companion” apps for your watch app.

I am sure that for most web based services what Pebble provides will be more than enough.  Unfortunately for binary based interfaces, such as the Evernote interface, the current XMLHttpRequest support isn’t quite rich enough.

Yet.

Filed under: Evernote, Pebble No Comments
28Oct/130

Constraints foster creativity: Pebble watch app development

This is a recording of the presentation I gave at the Softshake Conference in Geneva in October 2013.

In this presentation I live-code a Pebble app from scratch and send it messages from a corresponding Android App. I share my experience and insights creating an experimental Evernote client for the Pebble watch. How do you deal with writing code in C, with no malloc available?

What do you do when the maximum message size between your phone and your watch is 120 bytes? What does it mean to create a useful app for your watch?

Filed under: Evernote, Pebble No Comments
13Oct/133

Evernote tip 8: How I use Evernote Tags

Disclaimer: Although I do work for Evernote, this is my personal opinion.  I believe there is no one true way to use Evernote.  What matters is that however you use Evernote, it should work for you.

I only have a couple of Evernote Notebooks, but I have many Tags.

image

My love affair with Labels and Tags

When I moved from using Microsoft Outlook to Gmail, my eyes were opened.  No longer did I have to think about which one folder I should select to file an email, instead I could use Gmail Labels to file a single email into as many "folders" as I liked.

I feel the same way about Evernote Notebooks and Tags.  Why on earth would I organize my notes into Notebooks, when I can use Tags to the same thing, and more?  With Tags I can file a note into multiple Tags, and Tags can be organized hierarchically to many levels. 

Why would I persist in thinking of Notebooks as being note "containers" and Tags as being "metadata", when they are both virtual concepts - Evernote may well store my notes in physical "notebook" files, but it is just as likely that the note's notebook is just another attribute, similar to tags.  To me they are both containers, its just that one kind works well for me.

Tags are so much more powerful than Notebooks that I'm hard-pressed to think of many reasons to prefer Notebooks over Tags.  To me Notebooks are clunky, whereas Tags are elegant. 

Notebooks are good for just two things for me: grouping content to be shared, and to group content I want to make available offline on mobile devices.  For everything else I use Tags.

A step back

But first, a step back.  Why would I want to do any organizing at all?  Certainly with Gmail my initial enthusiasm for filing my emails quickly dissipated as I got into the habit of simply archiving emails, relying on the coupling of essentially infinite storage with powerful instantaneous search to quickly find old emails.  If this works so well for Gmail then why not for Evernote too?

As with Gmail, Evernote places no limit on the size of your Evernote account (although there are monthly upload limits, and individual notes have limits), and its search capabilities are legendary

So why do I persist in using Tags for Evernote?

Tagging takes time

I definitely don't tag all my notes, maybe 70% of them.  And tagging notes costs me time.  It takes time to choose the right tag, and apply it.  Why would I invest this time?

I get to my notes quicker

One answer is that investing this time upfront saves me time in the future, for certain kinds of notes.  When I tag my notes I’m betting that that investment will pay off later.  If it didn’t pay off, then I’d stop.

If I'm searching for my June 2013 Amex statement, I have to invest the time to think about how to formulate the search string that will find that one for me, and then spend time scanning through the mixed bag of results and try to find the right one.  Can you see it?

image

Alternatively, I can jump to the Amex tag, and then scan down the list of statements to find the right one:

image

This makes it much quicker for me to find certain kinds of notes: Notes that I’ve categorized.

Grouping is goodimage

There is another benefit, perhaps purely psychological, but a real benefit nonetheless. 

At the start of 2012 I went paperless, and replaced binder after binder with Evernote. 

The physical binders did have one advantage though – I could pick up a binder and quickly see their contents. 

I could quickly see all my water bills, my kids school reports, my 2013 bank statements. 

To replicate this in Evernote I use Tags.  Here is my “Office” Tag hierarchy, which replicates the set of physical binders and categories within those binders, that I used to have in my office.

Of course with Evernote Tags it is much much better.  I can file something in both the “Gardening” tag and the Household repairs” Tag – something I could never do with physical folders.

In addition any of these notes in my “Office” Tag hierarchy can also be tagged with cross-cutting tags, such as “Tax 2013”.  That way I can quickly and easily find all my notes related to my 2013 taxes, no matter where they sit in the “Office” Tag hierarchy.



Tagging works for me

Investing in tagging some of my notes works well for me because it helps me find my notes quickly, and it is comforting to be able to see my notes grouped together in the same way as they used to be grouped in physical files, before I went paperless.

Whether tagging is worth it for you depends to a large extent on what makes you tick.  Are willing to throw stuff into Evernote and rely on its search capabilities, or do you want to invest up-front to make searching simpler?  Does it bother you to just see a mass of notes, or do you like to see some structure?

There is no one true way – just whatever works for you.

31Mar/133

Evernote integration with Pebble

Pebble

I signed up for the Pebble Kickstarter for a couple of reasons.

Firstly I actually wanted the watch – a waterproof watch that I could use to receive notifications without having to get the phone out of my pocket, and which I could use to control podcasts, audiobooks and music.

Secondly I wanted to be able to program it.  The full SDK is not yet available, so I can’t write programs that run on the watch, but it is possible to write Android apps that communicate with the watch.

I’ve spent some time today writing a small app that integrates the Pebble device with Evernote.

Evernote

One of the great things about Evernote is that it is very simple and easy to use at one level, but as your usage becomes more sophisticated, and your requirements deepen, you’ll find that it is much more powerful and capable than it first appears.

An example of this is that notes you create can optionally contain geolocation information, and you can view your notes on a map to see which ones you created on a particular vacation or business trip.

The idea

Vacation Location

I thought I’d use this Evernote Note geolocation capability to create an app that reminds you when you get close to the location associated with certain notes.

ColosseumAtEvening

Imagine going on vacation and creating a series of notes in Evernote for particular locations that you want to visit.  Whenever you get close to one of those locations your Pebble buzzes and you are reminded to visit it.

Evernote Food graphicRestaurant Reminder

Or imagine using Evernote Food to remember restaurants you want to visit, and your watch buzzing with a reminder if you happen to be close to one of those restaurants when it is meal time

I decided to implement it by having my app look for notes that have geolocation information (lat/lon) and are tagged with a particular tag (“pebble”).

When the app starts, it looks for those notes and uses the Android proximity service to set up proximity alerts for the note locations.  Then when the app receives the proximity alert it sends the note title as notification to the watch and could launch that note in Evernote.

image

The app

 

photo

This code uses the raw Evernote API, however there is an excellent Evernote Android SDK available, and if you are building an Android app that uses Evernote you should definitely check it out.

package com.everpebble;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.*;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import com.evernote.edam.notestore.*;
import com.evernote.edam.type.*;
import com.evernote.edam.userstore.UserStore;
import com.evernote.thrift.protocol.TBinaryProtocol;
import com.evernote.thrift.transport.THttpClient;
import org.json.*;

import java.util.HashMap;
import java.util.Map;

public class Main extends Activity {

  private static final String evernoteHost = "sandbox.evernote.com";
  private static final String userStoreUrl = "https://" + evernoteHost + "/edam/user";
  private static final String TAG = "EverPebble";

  private static final String PROX_ALERT_INTENT = "com.everpebble.ProximityAlert";

  // Available from https://sandbox.evernote.com/api/DeveloperToken.action
  private static final String authToken = "TBS";

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // Register for proximity events off the UI thread
    new Thread(new Runnable() {
      @Override
      public void run() {
        registerEvernoteProximityNotes();
      }
    }).start();
  }

  /**
   * Finds all notes tagged with a particular tag that have geolocation information, and registers for
   * Android proximity alerts when the phone gets close to those note locations
   */
  private void registerEvernoteProximityNotes() {
    THttpClient userStoreTrans;
    try {
      // Connect to Evernote to discover the note store URL
      userStoreTrans = new THttpClient(userStoreUrl);
      TBinaryProtocol userStoreProt = new TBinaryProtocol(userStoreTrans);
      UserStore.Client userStore = new UserStore.Client(userStoreProt, userStoreProt);
      String notestoreUrl = userStore.getNoteStoreUrl(authToken);

      // Set up the NoteStore client
      THttpClient noteStoreTrans = new THttpClient(notestoreUrl);
      TBinaryProtocol noteStoreProt = new TBinaryProtocol(noteStoreTrans);
      NoteStore.Client noteStore = new NoteStore.Client(noteStoreProt, noteStoreProt);

      // Find notes Tagged with "pebble" that have geolocation information
      NoteFilter noteFilter = new NoteFilter();
      noteFilter.setWords("tag:pebble latitude:* longitude:*");
      NoteList result = noteStore.findNotes(authToken, noteFilter, 0, 50);
      Log.i(TAG, "Found: " + result.getTotalNotes());

      // Register for proximity alerts
      LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
      for(Note note : result.getNotes()) {
        NoteAttributes attributes = note.getAttributes();
        if(attributes != null) {
          Intent intent = new Intent(PROX_ALERT_INTENT);
          
          // Save the note title and guid in the intent so that when we are close
          // we can send the title to the Pebble
          intent.putExtra("Title", note.getTitle());
          intent.putExtra("Guid", note.getGuid());
          PendingIntent proximityIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
          
          // We want to be notified when we are within 100 meters of the location
          double lat =attributes.getLatitude();
          double lon = attributes.getLongitude();
          locationManager.addProximityAlert(lat, lon,  100, -1, proximityIntent);
        }
      }

      // Ensure we receive the event intents
      IntentFilter filter = new IntentFilter(PROX_ALERT_INTENT);
      registerReceiver(new ProximityIntentReceiver(), filter);

    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Sends alerts to the pebble phone when entering within range of a note's geolocation
   */
  public class ProximityIntentReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
      Log.d(TAG, "Received proximity alert");
      boolean entering = intent.getBooleanExtra(LocationManager.KEY_PROXIMITY_ENTERING, false);

      final String title = intent.getStringExtra("Title");

      if(entering && title != null) {
        new Thread(new Runnable() {
          @Override
          public void run() {
            sendAlertToPebble("Evernote", title + " is nearby");
          }
        }).start();
      }
    }
  }


  public void sendAlertToPebble(String title, String body) {
    Log.d(TAG, "sendAlertToPebble invoked");
    final Intent i = new Intent("com.getpebble.action.SEND_NOTIFICATION");

    final Map<String, Object> data = new HashMap<String, Object>();
    data.put("title", title);
    data.put("body", body);
    final JSONObject jsonData = new JSONObject(data);
    final String notificationData = new JSONArray().put(jsonData).toString();

    i.putExtra("messageType", "PEBBLE_ALERT");
    i.putExtra("sender", "EverPebble");
    i.putExtra("notificationData", notificationData);

    Log.d(TAG, "About to send a modal alert to Pebble: " + notificationData);
    sendBroadcast(i);
  }
}

Summary

It is very early days for the Pebble, but its been great fun using it, and even more fun programming to it by integrating it with Evernote

Disclaimer: I do work for Evernote, but this blog is entirely my personal private work.

25Mar/130

By:Larm Tech – Scandinavia’s new conference and networking arena for tech & digital change

Earlier this year, the 2013 South By Southwest Interactive Festival took place. It wasn’t the first of these kinds of events this year though. In late February I had the pleasure of keynoting at Europe’s equivalent in Oslo, Norway.

clip_image001The By:Larm music conference is well established and extremely popular. This was the first year they decided to run the technology conference alongside, called By:Larm Tech.

I’ve spoken at many similar events, and found it can be tricky to get the technical balance right. If I go too deep I’ll lose some of the audience that don’t care so much for the technical nitty-gritty. On the other hand if I stay too high-level I’ll bore the techies in the audience.

I decided to start with a story, then talk about Evernote’s approach to app development, and finally talk about how you can build on Evernote’s success by taking advantage of the Evernote’s platform to build apps that integrate with Evernote.

The conference organizers were smart. They knew that the audience would have been up late listening to music and drinking. My presentation was one of the first, beginning around 11am.

Starting with a story

clip_image002Instead of immediately diving into details of Evernote’s technology platform, I decided to start with a story.

Even if you’ve been using Evernote for a while it can be easy to forget the power at your fingertips from Evernote’s search capabilities.

Imagine you are out at a restaurant.

It’s a great restaurant with great wine. It’s so good that you and your friends are well into your second bottle. In fact it’s so good that you decide you want to remember this bottle of wine for all time, and you know just how you’ll do it.

You whip out Evernote on your phone, and take a photo of the label. Given that it’s the second bottle the photo is a little blurred, and not exactly straight.

Time passes …

clip_image003Six months later you are thinking back to that night, and you dimly remember taking that photo. You don’t remember much about the evening, but you do remember that the wine’s name had the word “saint” in it, so you search in Evernote.

Because Evernote recognizes the words in photos you put into it, you quickly find the note you took that night, despite the label being blurred and at an angle.

 

 

 

 

But it’s even better than that. Look at the text at the top of the label. The text that is written in and arc, an even more blurry. Evernote can find that too:

clip_image004

Evernote’s text recognition and image search capabilities are just a couple of many subtle yet powerful features that like beneath the deceptively simple User Interface. As many a student has found to their delight, you can even take photos of hand-written text and Evernote will search it. Imagine that: searchable hand-written notes!

That’s too easy though. Instead let’s imagine that the night was such a good night that you don’t even remember a word from the label, but you do remember that it took place in Paris. You are pretty sure of that.

When you take notes on mobile phones, Evernote can optionally embed location information in the note.

Instead of searching for text, you can view your notes on a map, using the Atlas feature in Evernote for Mac, and quickly zoom in to the notes you’ve taken in Paris.

 clip_image005

Being able to quickly and easily capture notes is one half of the story. Even more important is being able to find your notes later, whether by searching for content, or by drilling down to when or even where they were created.

Evernote’s approach to building apps

If you are looking to build great apps that integrate with Evernote, its worth understanding Evernote’s approach to app development.

In two words: Experience First. I’m mildly allergic to meaningless buzzwords, but this concept actually makes sense. What does it mean?

It comes down to creating an experience that people will love, that they will come back to time after time. It emphasizes ease of use, especially for first time users. We focus on the overall experience of using an Evernote app.

To do this Evernote invests very heavily in design, and we create native apps for most OSes, whether it’s Android, Windows Phone, or iOS. We want an app that feels native, and takes advantage of each platform’s unique capabilities.

It pays off. The day before the presentation I looked into the various app stores and found we were the top free app in the Mac App Store, an Editor’s Choice in the Google Play Android store, recommended by Apple for new users in the iOS store, and listed in the top free apps on the Windows 8 store.

clip_image006

This doesn’t happen by accident. It’s not just about features or looking pretty. It comes from a relentless attention to getting the overall experience of using our apps as great as possible.

When you are building apps that integrate with Evernote you want to benefit from the “hallo effect” of Evernote’s popularity – invest in design.

Building on Evernote

Before I joined Evernote I was an Evernote user. I wanted to create my own Evernote client to do some things the standard Evernote client I was using didn’t do. Being a hacker at heart, I delighted in thinking about how I’d have to reverse-engineer the Evernote API calls, to understand how to interact with the Evernote service.

You can only imagine my disappointment when I discovered that Evernote provides a public API, and extensive documentation and support to help you successfully build on the Evernote platform.

When you look at Evernote’s client apps, such as the Mac or Windows desktop clients, or the Android or Windows Phone mobile clients, it’s tempting to think that those apps can only work the way they do because they were created by Evernote. You’d be wrong to think that though. Evernote’s apps use the same public API as everyone else. There are no secret API calls available only to Evernote.

There are many reasons why you’d want to build an app that integrates with Evernote. Perhaps your users want to be able to export and import their information to their Evernote account. Most likely you want to take advantage of the 50 million or so Evernote users.

You have several Evernote integration points to choose from. The right one for you depends on what your app does. You can create a web site that in turn talks to Evernote’s service API, or you can create mobile or desktop apps that talk to Evernote’s API. Alternatively your apps can talk to Evernote’s Apps. This can often be much easier and quicker to implement. For example on Android your app can send Android messages called Intents to the Evernote Android app to ask it to create a note on your behalf.

The Evernote Trunk is a great please to see what kinds of apps people have already created, and it’s where you can get Evernote to showcase your app, once you’ve built it, if you want to.

clip_image007

Making Money

The question people are often wondering, the elephant in the room, is often “how does Evernote make money?”

How does Evernote make money by offering a free service? Evernote is free to use, however if you do want to take advantage of additional features, such as storing your notes offline in our mobile apps, then you can pay for a premium subscription. You don’t have to, and you should never feel any obligation to do so, but it’s well worth checking out the Evernote Premium features since it’s pretty compelling.

We have also started an Evernote Business offering. Evernote Business lets you use Evernote as you always have done, with your stuff staying private in your own notebooks, but it adds Business Notebooks that belong to your company. Suddenly your “external brain” is expanded to include everyone in your company, making it easy to share and discover information previously locked away in your colleagues’ minds (or files).

In Summary

I’ve only scratched the surface of what I covered, but overall the presentation seemed well received.

I was asked several times afterwards to tell the wine story by people that were not at the presentation but heard about it afterwards.

I did get the feedback that I was “eulogizing” Evernote. It means “to speak or write in high praise of”. Guilty!

Many thanks to Cristina Riesen, Director Market Development Europe at Evernote, and Torgeir Waterhouse, Director Internet & New Media at IKT-Norge for giving me the opportunity to speak at By:Larm Tech.

Damian is a Senior Software Engineer at Evernote, based out of Geneva, Switzerland. He created the original Evernote Windows Phone client, and works on Evernote Food for Android. He has founded and eventually sold several successful software product companies, and loves the magic that is programming: turning something imagined into something real.

Filed under: Evernote No Comments
28Oct/122

Automatically generating Evernote note titles from text in images

Once a month I scan my physical mail and receipts into Evernote, and then rename each of the new notes to something meaningful.

Before I rename them, the new notes have titles such as “CCE272012_00003.pdf” and “CCI282012_00029.jpg”:

image

I wondered whether it might be possible to write a program to automatically generate a title from the text that Evernote finds within the scanned image …

It turns out that it is possible.  These are exactly the same notes as shown above, with their new titles automatically generated from the text Evernote found in the scanned images.

image

This is just a proof-of-concept although if you are interested in using it then please let me know in comment to this post, so that I can look at making it available as a web-based utility.

How does it work?

If you are not a developer then this won’t mean much to you – feel free to bail now!

Essentially the program looks for all notes with a single resource which has recognition data, and which matches specific search criteria (for example in a specific notebook and with a specific title).  It concatenates the best-match words from the first couple of lines of text in the image, if the search-weight is above a certain level.

Here is the program (in C#):

using System;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Evernote.EDAM.NoteStore;
using Evernote.EDAM.Type;
using Evernote.EDAM.UserStore;
using Thrift.Protocol;
using Thrift.Transport;

namespace AutoTitleEvernote {
  internal class Program {
    // Get this from https://www.evernote.com/api/DeveloperToken.action
    private const string AuthToken = "...";

    // Change this as appropriate
    private const string SearchString = @"Notebook:Inbox intitle:CC*";
    private const int MaxNotes = 1000; // Max nr of notes we will process
    private const int LineFudge = 10; // Used to determine if words are on the same line 
    private const int Lines = 2; // How many lines of text to read
    private const int MinWeight = 50; // How good a match do we need on words
    private const string HostUrl = "https://www.evernote.com/edam/user";

    private static void Main() {

      var noteStoreClient = GetNoteStoreClient(AuthToken);

      // Find notes with the required title in the required notebook
      var filter = new NoteFilter { Words = SearchString, 
                                    Ascending = false, 
                                    Order = (int)NoteSortOrder.CREATED };
      var notes = noteStoreClient.findNotes(AuthToken, filter, 0, MaxNotes);

      // For each note with a single resource and recogition data
      foreach (var note in notes.Notes.Where(n => n.Resources != null &&
                                                  n.Resources.Count == 1 &&
                                                  n.Resources.First().Recognition != null)) {
        // Download and parse the recognition XML
        var recoXmlBytes = noteStoreClient.getResourceRecognition(AuthToken,
                                                                  note.Resources.First().Guid);
        var recoXml = XElement.Parse(Encoding.UTF8.GetString(recoXmlBytes));

        var items = recoXml.Elements("item").ToList();
        var title = new StringBuilder();

        var lineY = -1;
        var line = 0;

        // For each word
        foreach (var item in items) {
          // Keep track of the current line
          var y = int.Parse(item.Attributes("y").First().Value);
          if (lineY == -1) {
            lineY = y;
          }
          else {
            if (y > lineY + LineFudge) {
              if (++line > Lines) {
                break; // We've moved beyond the number of candidate lines
              }
              lineY = y;
            }
          }

          // Find the word's text and weight if the weight is above the criteria
          var word = (from t in item.Elements("t")
                      let weight = int.Parse(t.Attribute("w").Value)
                      orderby weight descending
                      where weight > MinWeight
                      select new { Weight = weight, Text = t.Value }).FirstOrDefault();

          if (word == null ||
              title.Length + word.Text.Length + 1 >=
                     Evernote.EDAM.Limits.Constants.EDAM_NOTE_TITLE_LEN_MAX) {
            break;
          }
          if (title.Length > 0) {
            title.Append(" ");
          }
          title.Append(word.Text);
          // title.Append("[" + word.Weight + "]");
        }
        Console.Out.Write("Rename " + note.Title + " to " + title + "? ");
        Console.Out.Flush();
        var input = Console.In.ReadLine();

        if (input == null || input.ToLower() != "y") {
          continue;
        }

        note.Title = title.ToString();
        noteStoreClient.updateNote(AuthToken, note);
      }

    }

    private static NoteStore.Client GetNoteStoreClient(string authToken) {
      var userStoreUrl = new Uri(HostUrl);
      var userStoreTransport = new THttpClient(userStoreUrl);
      var userStoreProtocol = new TBinaryProtocol(userStoreTransport);
      var userStore = new UserStore.Client(userStoreProtocol);

      var noteStoreUrl = userStore.getNoteStoreUrl(authToken);

      var noteStoreTransport = new THttpClient(new Uri(noteStoreUrl));
      var noteStoreProtocol = new TBinaryProtocol(noteStoreTransport);
      var noteStore = new NoteStore.Client(noteStoreProtocol);
      return noteStore;
    }
  }
}

image

A word about Evernote’s text recognition

One of the many cool things about Evernote is that it automatically finds text in scanned images and PDFs so that when you subsequently search for that text, you can find the corresponding notes.

Evernote’s text recognition is incredibly powerful. It finds text that is at an angle, hand-written, and in various languages.

It is powerful, but it is not designed to provide a text version of a scanned document. Instead it is designed to make searching for words work very well. For example for each part of an image where it detects a word, it has a series of words that might match, each with a “weight” indicating how good a match it thinks it is.

What I’m doing here is not really in line with Evernote’s text recognition capability’s goals … but it does work …

Filed under: Evernote 2 Comments
20Sep/120

Evernote tip 7: Seeing the wood from the trees: unclutter the Evernote toolbar.

I’ve been using Evernote since November 2009, so you’d think I ‘d know how to use it by now.

You’d think that, but I swear I recently spent a good ten seconds staring at the Evernote Windows toolbar, trying to find the button to add a new note.  Try to quickly spot the button to add a new note, without reading the text:

image

If you cheated and read the text you can probably saw it immediately, largely because it says “New Note” right next to it.

But I was scanning the icons, and the “New Note” icon didn’t jump out at me.  In fact my eyes were drawn to the one icon that screams “Add something” to me.  Can you guess which one it is? (hint, the one with the big “+”).

It turns out I only ever use the toolbar for two things: for syncing, and creating new notes.  Everything else, such as sharing, I do by right-clicking on a note.

My solution: If you right-click the toolbar, and select “Customize toolbar”, then you can drag all the items you never use off the toolbar.  You can also take away the text labels.

This is my new simple toolbar:

image

The icon still doesn’t say “Add Note” to me, but since I’ve only got a choice between that button and the sync button, I’m pleased to report I create new notes without hesitation.

You can do this with both the Windows and Mac clients.

Next up: How I use Evernote Tags

Filed under: Evernote No Comments