Category Archives: Programming

I’ve Framed! my hosts

And it feels great!

For a couple of days I’ve been poking around with a small tool to ease the burdens of keeping track of different web development environments.

The problem

Nowadays a lot of developers have a number of different environments set up to improve the way they work. It’s often safe to tinker around and break things in a development environment, a little less so in a stage environment and absolutely potential high risk disaster to do anything at all in live/production!

In order to try and fix this, I, in the early days, went the way of directly editing files server side on the different hosts. This had an added benefit of making it clear to anyone that visited that host, that it was a special type of environment. But, there was a downside. And that was that it was visible to everyone and not just to me, when surfing around on the different hosts. Plus, editing files like this is a nightmare to keep track of when deploying.

The solution: a multi browser extension

So, I thought that it would be nice to have these visual cues available on the client side, in the browsers, instead. I started looking around in the different browser addon stores and sure, I found one or two tools, but they were all either low on features or tied to only one browser.
To fix this, I started developing an extension for Chrome that could take of this. Said and done, I’ve now created an extension, Framed!, that works on three browsers so far; Chrome, Firefox and Opera. Soon, there will be Microsoft Edge and Safari versions but they are super quirky to work with, so don’t expect it to be available for a little while.

What it does

Anyways, what the extension does is allowing you to paint a frame around your choice of host(s), customisable to what color, thickness, placement (top, right, bottom, left), opacity and Z-index. As an added bonus, you can import/export your frames by copying and pasting a human readable and editable JSON format between the browsers you use.

I hope you find this tool useful, and I’ll spend some more time working on it to make it even more useful and polished.

How to get it

Here are the links to the extension on all browsers:

Tunneling Gerrit

Tunneling and Gerrit was a really interesting happening, as it wasn’t all clear how to do the following things

  • Allow cloning and interaction with Gerrit Git
  • Allow interaction with Gerrit’s web UI

The first part was easier than the second. So let’s look at the second first.

Allowing interaction with Gerrit’s web UI

In order to set this tunnel up you need to know the port it’s running at. This can be stuck in a few places, depending on your configuration. Most obvious places to look are

  • Apache site configuration
  • /etc/gerrit/gerrit.config

Mine was residing in the config, which said

[httpd]
    listenUrl = http://*:8080

This is something we can use when we set up our tunnel. The tunnel setup is a bit opaque, but the general gist is:

ssh -L [local port number]:[remote host where gerrit web is running]:[remote port where gerrit web is running] [username]@[remote host] -p [remote ssh port]

So, a command would look like this:

ssh -L 3333:cerberus:8080 john@doe.com -p 1234

After having done this and logged in you will be able to reach the web ui through:

http://localhost:3333

Make sure you add your local SSH key so you can interact with Gerrit Git.

In parallel you can/need to set up another tunnel to Gerrit, which usually runs on port 29418…

Allowing interaction with Gerrit Git

The port Gerrit runs on was found in the /etc/gerrit/gerrit.conf file, looking like this:

[sshd]
    listenAddress = *:24918

So let’s use this for setting up the Git tunnel. The command follows the same pattern as for tunnelling the Gerrit web UI:

ssh -L [local port number]:[remote host where gerrit web is running]:[remote port where gerrit web is running] [username]@[remote host] -p [remote ssh port]

And the final tunnel would be something like this:

ssh -L 29419:cerberus:29418 john@doe.com -p 1234

In order to interact properly with Gerrit Git through this tunnel, you would for instance clone a repo like this:

git clone ssh://[gerrit user]@localhost:[tunnel port]/[git repo]

And the command itself would be similar to:

git clone ssh://john@localhost:29419/doe.git

Good to know!

Fixing permissions in a shared Git repo

I hate shared Git repos’. Especially when I forget to set them as shared ones. And I start inviting people to join in on the fun.

So, therefore, here’s a tip from a blog that tells you a way of fixing the mess you did, retroactively: https://blog.christophersmart.com/2014/01/10/permanently-fixing-permissions-on-a-shared-git-repo/

tl;dr TheRightWay

git init --bare --shared

tl;dr TheRadioactiveWay

ssh server
chown -Rf root:git /path/to/bare/git/repo
cd /path/to/bare/git/repo
git config core.sharedRepository group
find /path/to/bare/git/repo -type f | xargs chmod 664
find /path/to/bare/git/repo -type d | xargs chmod 775
find /path/to/bare/git/repo -type d | xargs chmod g+s

SmartWatch2+3 in one apk

So, I got into this thing when I developed a watch face for the SmartWatch 2 and wanted to see if I could combine it in any way to work with a SmartWatch 3 as well.

My route was a bit more strangled than the one I am about to present, but if nothing else, now that I’ve done that, you don’t have to!

Primary setup

The ingredients list, as of this writing, is straight forward. This is what you need before moving on:

  • Android Studio 1.0.2
  • Android SDK Tools 23.0.5
  • Android SDK Platform-tools 21
  • Sony Add-on SDK 3.0
  • Android SDK 5.0 (API21)

Step 1: Create a Wear (API21: Android 5.0) project

This is for the SmartWatch 3 part of this SmartWatch 2 and 3 mashup.

It is actually as simple as that sounds. In Android Studio, choose the File-menu -> New Project and decide what you’d like to name it along with all the other settings you’d like to use for your SmartWatch 3 project. NOTE! The package name is going to be extra important, as you will have to use that later on in this guide.

When you have ran through the wizard and managed to find yourself with a Wear project that compiles, let’s import a SmartExtensions project.

Step 2: Import one of the SmartExtension samples as a module

Using a sample project is a quick and easy way of getting the right dependencies in place for the SmartWatch 2 part of this mashup.

Importing a sample project is done by clicking the File-menu -> Import-module, browsing to the SmartExtensions sample folder directory (usually located in ANDROID_SDK/add-ons/addon-sony_add-on_sdk_3_0-sony-19/samples/SmartExtensions) and selecting one of the samples. The import wizard will automatically present you with the option of also importing the “SmartExtensionUtils” and “SmartExtensionAPI” projects. Make sure that you include these, or you will run into build issues because of missing dependencies.

NOTE! I chose the “HelloLayouts” sample during my tests. Any other sample should work but avoid importing the “SmartExtensionAPI” and “SmartExtensionUtils” projects, unless you want to create a project from scratch without any boiler plate setup from the samples.

Step 3: Do a bit of modifications to project files

Here’s the tricky part. It’s not that tricky though. You will need to:

  • Modify the SmartExtension sample package name
  • Creating release build signing configs

and do some edits to the following files:

  • The SmartExtension sample gradle file
  • The SmartExtension sample AndroidManifest

Modifying the package name

This took a bit of trial and error but in the end, the recipe I would use:

  1. Create a new package in the SmartExtension sample module that has the same name as the Wear module package name
  2. Drag-and-drop all the classes from the old package “com.example….hellolayouts” to the new package
  3. Delete the old package
  4. Open the AndroidManifest file in the SmartExtension sample and replace the old package name “com.example….hellolayouts” the new name
  5. Open the SmartExtension gradle file and replace the package name here as well, referenced as applicationId

Try to build (a clean may also be required) your SmartExtension sample module to see whether everything seem to be in the right places and don’t contain errors. I got some minor issues with imports to “com.sample….R” that had not been cleaned out. Deleting those manually worked out perfectly fine for me.

Modifying the gradle files to update references and build configs

To lay the last stones in the process, you will need to do some additional updates to gradle files, both the SmartExtension sample and the Wear app.

NOTE! These steps require you to have an Android keystore and the secrets that go with them:

  1. Open the Wear app gradle build file
  2. Add the signingConfigs declaration and reference as shown below:
android {
  signingConfigs {
    release {
      keyAlias 'YOUR_KEY_ALIAS'
      keyPassword 'YOUR_KEY_PASSWORD'
      storeFile file('PATH_TO_YOUR_KEYSTORE_FILE')
      storePassword 'YOUR_KEYSTORE_PASSWORD'
    }
  }
  ...
  buildTypes {
    release {
      ...
      signingConfig signingConfigs.release
    }
  }
  ...
}
  1. Open the SmartExtension sample gradle build file
  2. Add the same declarations and references as in step 2 above, but also include the following (replace ‘:app’ with the module name of your Wear module):
dependencies {
  ...
  wearApp project(':app')
}

Step 4: Configure the Build Variants

This is the last step before making the final build. Find the “Build Variants” panel in Android Studio (it’s usually located at the bottom left of the UI) and select release for the Wear app and the SmartExtension sample. Leave “SmartExtensionUtils” and “SmartExtensionAPI” on debug.

Select the SmartExtension sample as your build configuration, compile, run and deploy! (If the “Edit configuration” dialogue shows up, choose to not launch an Activity, as the sample does not have a Default one declared)

Step 5. Done!

Congratulations! You should now, given nothing breaks down on you, have a SmartWatch 2 and 3 combined Android Studio project!

Musings about going from Eclipse to Android Studio 0.3.7

So, the first time around when Android Studio was announced I was pretty excited. Seeing that something tightly connected to Android in the shape of a Google pushed IDE, well that should bring a lot of nice things!
But alas, after a few hours of tinkering and trying to import projects exported from Eclipse by following the it’s-supposed-to-be-this-easy guides, I gave up. Too many issues with importing my projects and also, not having really used IntelliJ and even less Gradle, it was just too many issues at hand to keep track of that I chose to postpone.
So, here we are, version 0.3.7 later and I must say it seems a lot more straight forward (in most cases).

¤ One thing that I really have to stress is Android Studios way of not helping out how to import projects based on bare Android source code. The guides talk a whole lot about Maven and Gradle, but it took me actually testing out an import where I ignored all those keywords and reading the IntelliJ documentation on importing code, to be able to deduce that yes, it is possible to import bare Android code.
Really, this should have been much more clearly stated/supported because now, there is no clear way at all whether this kind of import is supported or not.

¤ Another thing. In Eclipse it was possible to mark projects as libraries and then chain the dependencies in a way that your project can reference a library that in turn references another library. With Android Studio it seems that your project has to refer to all the libraries it needs, in effect not being able to chain the dependencies.

¤ Oh, a third thing. It seems like the terminology “project” in Android Studio is an umbrella for keeping track of one or more “modules”. The Eclipse “projects” seem to map to “modules” in Android Studio and I guess Android Studios “projects” are most likely “workspaces” in Eclipse.

setTag, getTag sitting in a tree…

Jag knåpar ihop en app som ska hålla koll på antalet slag man gör under en Frisbeegolf-runda och ganska oundvikligt hamnade jag i arbetet med att lägga till och ta bort View:s dynamiskt. Dessutom behövde jag på något sätt sitta och klura ut hur layouten av dessa View:s skulle se ut, vilket obönhörligen gjorde att jag snabbt kom i kontakt med getTag och setTag tillsammans med LayoutParameters.

En liten kodsnippet på hur det kan se ut

TextView textScore = new TextView(this);
textScore.setText("" +currScore.getScore());
textScore.setId(3);
RelativeLayout.LayoutParams paramsScore = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
paramsScore.addRule(RelativeLayout.BELOW, textPlayer.getId());
row.addView(textScore, paramsScore);

Enkelt förklarat kommer denna kod att lägga till en View relativt positionerat under View:n textPlayer. Guld och gröna skogar, men vad man måste se till att hålla reda på är att setTag inte gillar att man använder id:t 0, som i setTag(0), för då kommer den View man vill positionera relativt att inte hamna just relativt till något annat än, så vitt jag kan förstå, till föräldern.

Alltså, se till att använda setTag med 1-indexering: setTag(1), setTag(2), …!

Starta en aktivitet i en app från en annan app

Det här “tricket” kan vara användbart om man skapar en liten svit med appar som är tätt bundna till varandra, men inte nödvändigtvis måste leva under samma tak/app.

I appen vars aktivitet du vill starta utifrån, gör

Ändringar i Manifestet

Leta upp den aktivitet-tag, <activity>, som du vill kunna nå utifrån och lägg antingen till ett <intent>-filter, eller en rad

<activity
  android:name=".activities.OpenMeActivity"
  android:exported="true" >
</activity>

Som exempel kan ett helt Manifest se ut

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="nu.opentest"
 android:versionCode="1"
 android:versionName="1" >
  <uses-sdk android:minSdkVersion="7" />
  <application
    android:name=".OpenTest"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name">
    <activity
      android:name=".activities.OpenTest"
      android:label="@string/app_name">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <activity
      android:name=".activities.OpenMeActivity"
      android:exported="true" >
    </activity>
  </application>
</manifest>

I appen du vill kalla på en annan epps aktivitet, gör

Följande i kod

Intent intent = new Intent();
intent.setComponent(new ComponentName("nu.opentest", "nu.opentest.activities.OpenMeActivity"));
startActivity(intent);

Med detta kan man nu alltså inifrån en app få upp en specifik aktivitet i en annan app. Jag rekommenderar starkt en massa try/catches för att inte åka på en nit under produktion.

Samsung Galaxy Tab (P7300), virtuellt tangentbord och emulatorn

Jag har ingen egen SGT men jag har däremot fått låna en. Mitt mål nu är att (på ett så våldsamt sätt som möjligt) bryta ut det virtuella tangentbordet och försöka installera det på emulatorn, så jag inte är strikt bunden till att ha tab:en varje gång jag vill felsöka tangentbordsproblem.

Det är en process i stegen

  • Skaffa en kopia av SGT:ns original-operativ
  • Skaffa simg2img för att kunna montera de system-images som finns i SGT:ns original-operativ
  • Ta ut filerna
    • T9DB folder (from csc.rfs file)
    • AxT9IME.apk and AxT9IME.odex (from system.rfs file in app folder)
    • touchwiz.xml (from system.rfs file in etc->permissions folder)
    • libdhwr.so and libXt9core.so
    • android.policy.odex
    • bouncycastle.odex
    • core.odex
    • core-junit.odex
    • ext.odex
    • framework.odex
    • services.odex
  • Ta hem baksmali och smali för att kunna deodexa tangentbordet
  • Ta den deodexade tangentbordsfilen, döp om till classes.dex, lägg in i AxT9IME.apk
  • Placera alla de filer (förutom odex-filerna) som togs från operativet och lägg dem i sina respektive korrekta mappar
  • Be till Cthulhu

Android NoClassDefFound komma-ihåg

Denna bara måste jag lägga in i dataminnet för att se till att jag inte måste leta upp den igen: http://android.foxykeep.com/dev/how-to-fix-the-classdefnotfounderror-with-adt-17

Internationalisera WordPress… wth

Det märks att WordPress är något av ett monster att ha att göra med när man sitter och moddar och har sig.
Jag försökte vara ett så gott stöd som möjligt till Emma Ekberg i hennes strävan att få en svensk blogg. Jäklar i min låda vilket härke det är att försöka navigera sig mellan WordPress, internationalisering och temastruktur.
Några nyckelord

  • WordPress
  • Translation
  • Themes
  • Domain
  • __([String])
  • __(String, Domain)
  • Översättningsfiler (.po, .mo)

Egentligen är det __() och Domain som är de absolut viktigaste där. Vad jag lyckades slutleda mig till efter ett par timmars parprogrammerande var att man måste hålla på att latja lite med översättningsfunktionen __() och de argument man skickar in. Om en översättning inte ser ut att fungera till kommandot __(“Översätt den här strängen”, “Korv”), då kan man behöva skriva in nyckelorden man försöker översätta i .po/.mo-filerna som tillhör temat, eller ändra argumenten som man skickar in i __(), eller en kombination av båda. Ibland kan det vara enklare att helt enkelt strunta i att inkludera en domän och sätta in översättningen direkt i WordPress egna .po/.mo-filer. Givetvis med en risk att det kan försvinna när man uppgraderar WordPress, men hell, det som funkar, det funkar.
Det är enastående vad rörigs saker kan bli när det inte sätts in några strikt upprätthållande regler för tex översättning när temaskapare sitter och knackar hemma på kammaren.