Eclipse, Android and Maven: Part 7 - Global properties and settings for Maven

For those who work on projects with multiple developers such as open source projects, you'd realise that the way I've currently set up Maven is not very good for multi-developer projects.

It's also not a good idea to have passwords or computer specific SDK locations in your pom.xml file because each developer will need to change the pom.xml in order to compile the code.

If you're fine with using script files to pass arguments to Maven then that's fine. Otherwise, you can set up the Maven global settings.xml file.

Contents

Machine specific Maven settings

It can be located in either:

  • %M2_HOME%/conf/settings.xml
  • %USERPROFILE%\.m2\settings.xml (aka ~/.m2/settings.xml)

Either way, the guts of it looks the same.

Open up your settings.xml file (you may need to create it for the user specific one).

I use this to store the location of my Android SDK home folder, Android SDK Maven repository and information such as keystore file and passwords.

The profile named "variables" sets up some properties for us which is automatically filled into your pom.xml file when needed.

The Android Maven repository is set up so you don't have to do it in every pom.xml file you work on.

And lastly, active profiles tells Maven to always use these the variables profile.

Once you're done, you'll need to reload the settings into Eclipse (if you don't want to restart).

  • Preferences
  • Maven
  • User settings
  • Click "Reindex" to update the settings

And that's it! We've finally reached the end of the Maven journey!

ostrich-skiing

Time to go full pro at Maven now! I mean if an ostrich can ski that good, what's YOUR excuse?

Source

Eclipse, Android and Maven: Part 6 - Sign your Android app APK for release

And now its time to sign your APK for release. This took a while to figure out due to all the conflicting information about ways of setting this up.

I've determined that the easiest way of doing this is to simply create a "toggle variable" that skips the signing process unless specified by the calling script / command line argument.

Contents

Setting it up

Open up your pom.xml file for editing, go to project > properties and add in:

<sign.skip>true</sign.skip>

This, by default, will skip the signing process.

Now scroll down to find the project > build > plugins and add in this:

<!-- Sign the APK with release signature -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<!-- Required because it's initially signed with a debug cert -->
<removeExistingSignatures>true</removeExistingSignatures>
<skip>${sign.skip}</skip>

<keystore>${sign.keystore}</keystore>
<storepass>${sign.storepass}</storepass>
<alias>${sign.alias}</alias>
<keypass>${sign.keypass}</keypass>
</configuration>

<executions>
<execution>
<id>sign</id>
<goals><goal>sign</goal></goals>
</execution>
<execution>
<id>verify</id>
<goals><goal>verify</goal></goals>
</execution>
</executions>
</plugin>

You may have noticed in the configuration that <skip> is controlled by ${sign.skip}, as defined above in the properties. You can override this by passing in command line arguments to mvn.

Similarly with the keystore, storepass, alias and keypass, they're all configured with properties or command line arguments. This is a good way of keeping your passwords out of the pom.xml file and source control.

Another point to make clear is that you NEED removeExistingSignatures. When the jar/apk is initially created, it's signed with a debug certificate. You have to REMOVE that before signing with your own, otherwise the verification goal will fail with this error:

[INFO] jarsigner: java.lang.SecurityException: invalid SHA1 signature file digest for res/drawable-xhdpi/abc_ic_go_search_api_holo_light.png

How to sign your APK

Normally, you'd just run this to create a debug APK:

mvn package

To create the release APK, type the following to begin the build process:

mvn package -Dsign.skip=false -Dsign.keystore=X:\your\cert.keystore
-Dsign.storepass=STOREPASSWORD -Dsign.alias=KEYALIAS
-Dsign.keypass=KEYPASS

The "-Dvarname=value" specifies it's a variable being passed to your build script, which overrides any instances of ${varname} in your pom.xml file.

It's also a good idea to enable verbose output to test your configuration until it's working properly. Place this under the jarsigner plugin > configuration:

<verbose>true</verbose>

You'll probably also run into this warning message:

[INFO] Warning:
[INFO] No -tsa or -tsacert is provided and this jar is not timestamped. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (2068-08-23) or after any future revocation date.

Don't worry, it's not too bad. The date is the expiry date of your certificate so it's fine if your certificate expires in an extraordinarily long period of time.

By now you should be able to produce a signed APK file, ready for release.

Sources

Eclipse, Android and Maven: Part 5 - How to debug your Android app with Maven?

We can see the light at the end of the tunnel now. I'll tell you the steps required, and then describe the nitty gritty details after for those who are interested.

Contents

How to debug with Maven?

  • First of all, connect your test Android device or start the emulator (preferably Genymotion)
  • Place this command into a batch/shell file called "mvn-debug.bat" because you'll run it quite regularly.
mvn package android:deploy android:run -U
  • While you're waiting for it to finish compiling and deploying, set Eclipse into DDMS perspective mode so you can see stuff like the activity log and devices tabs.
  • Each time you start a new Eclipse session, you'll have to tell it once (manually) to debug your app. (I haven't found a way around this yet)
  • Find the "Devices" tab.
  • When your app starts it'll display a message "Waiting for debugger" and wait there.
  • Find and select your app in the devices tab. If you enabled debugging in your app manifest file, it should have a red debug icon next to it, circled in red.
  • Click on the green debug icon in the devices tab toolbar circled in orange. You'll only need to do this the first time debugging.
  • Now you should be debugging like you were before Maven.
  • When you need to debug again in the same session, just run the "mvn-debug.bat" script and it'll start itself. No need to enable debugging again for this session.

image

What actually happened?

  • package: This goal compiles your app and spits out an APK to the "target" folder.
  • android:deploy: This goal uploads your newly compiled APK to the connected device. If there is no device, the build status will be "FAILED" so don't be alarmed if you see that.
  • android:run: This command runs your app on the device.
  • -U: As mentioned in the last tutorial, the -U flag tells Maven to fetch dependencies from the source. This is optional, so use it depending on your circumstances.
  • Because the build and deploy is done outside of Eclipse, it doesn't really have a way of knowing when to attach to ADB for debugging. That's why you have to tell it to debug separately.

Sources

Eclipse, Android and Maven: Part 4 - Share a library project using a local Maven repository

While you're converting your app to a Maven project, you'll soon realise that you need to tackle any shared libraries first. If you've got more than a couple of apps, it's likely you've created a common library between them to keep your code DRY (don't repeat yourself).

(Sorry for interlinked Part 3 and Part 4, but it's just the nature of this process)

Contents

The problem with Maven (and Gradle)

The way Maven works is it downloads shared libraries from a repository of code and attaches it to your code when needed. The problem with privately shared libraries is that you need to push it to a place that Maven can access.

A few answers on StackOverflow say you have to push your private library to a public Maven repository. To me, that's just not acceptable! A workflow should not force private code to be accessible to the public. Not to mention you'll clutter up public repos with code that should not be there in the first place and waste good namespaces. In short no, this is a shit solution.

A other sources suggested making a local repository. That sounds much more reasonable but how do I make that available across multiple dev machines?

Using Google's Support library from the Android SDK local repository

Most likely you're using Google's Android support libraries, so you'll also need to include the SDK local repository as a source for Maven.

First of all, make sure you have the files in the first place.

  • Fire up the Android SDK Manager
  • Scroll down to Extras and make sure "Android Support Repository" is ticked
  • Click Install

image

To include the local repository as a source, paste this under the <project> element.

<project ...>
<repositories>
<!-- Include Android Support Repository so we can access support-v4 and appcompat-v7 aar -->
<repository>
<id>google-sdk-support</id>
<url>file://D:/Android/sdk/extras/android/m2repository/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
</project>

As you can see in  the <url>element, the value can also be a local file system. If we can somehow replicate that structure we can safely share our code, privately.

To gain some inspiration, I studied the local Maven repository found in the Android SDK under "android-sdk\extras\android\m2repository\" and found an answer!

Setting up a local repository for your library

Knowing that Google can make their libraries accessible locally, I decided to make my own library accessible to other projects using this local repository method.

The only difference is that I'm creating a folder called "local-repo" within the root of the library project. This way, projects that use this shared library can refer to it using relative paths.

Initially I tried using the exec-maven plugin to manually move the main artefact to a common folder, but it just wouldn't work from within the Eclipse IDE. It'd work from the command line, but it's too much work compared  to install:install-file" which does just that with far less configuration. Gotta use the right tool for the right job!

So I set up the goals so it'd run "package" to first create the APK, and then using the "install:install-file" goal from the Maven Install plugin, pushes the main artefact (AAR, JAR, etc) into the local-repo repository in a structure which Maven can use.

I stored this command into "mvn-update-local-repo.bat" (excuse the poor naming) in the root folder of the project and run it whenever I need to push something to the local repo.

mvn package install:install-file -DlocalRepositoryPath=local-repo
-DcreateChecksum=true -Dpackaging=aar
-Dfile=target\twig-android-library.aar
-DgroupId=org.twig.common -DartifactId=twig-android-library
-Dversion=1.0.0-SNAPSHOT

The script pushes the file target\twig-android-library.aar to the repository "local-repo". It specifies that it's v1.0.0-SNAPSHOT.

This should be made more flexible by reading the pom.xml file, but haven't found a way yet.

Snapshot builds and caching

Snapshot builds are fetched only once a day. If you're testing and making multiple changes in the same day, use the -U arg to any mvn command to force Maven to fetch from the source, rather than once a day.

Why is this important?

Because each time you build your APK project, the shared library's AAR files from your local-repo are automatically cached in %USERPROFILE%\.m2\repository (aka ~\.m2\repository).

If fixing bugs in your library, Maven is going to use the cached copy so your changes won't be compiled into the APK unless you specify the -U option.

Using your shared library from an app project

So now you're ready to use the shared library in your APK project.

Edit your pom.xml file and look under <projects><repositories>.

Add another <repository> entry for your shared library.

This example assumes that your app project and shared library projects are on the same folder level.

<repository>
<id>twig-android-library</id>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
<url>${project.baseUri}../twig-android-library/local-repo</url>
</repository>

And there you have it, we've safely passed another hurdle without breaking any monitors.

Now you're ready to debug!

Figuring out the cryptic ClassNotFoundException: Didn't find class on path: DexPathList [zip file], nativeLibraryDirectories=[ /vendor/lib, /system/lib]

Fortunately this is a simple one. It's due to the incompatible versioning of libraries used between the Android Support Library and the Android Support v7 Compat library.

Make sure the support library project you've associated with your APK project is the same version as the support library you declared in the pom.xml dependencies.

This should clear you of any more cryptic errors.

Sources

Eclipse, Android and Maven: Part 3 - Converting an existing Android project to a Maven project

Once you get the hang of creating and compiling a Maven project, it's pretty easy to convert an existing project to a Maven one. Just follow a few basic steps and make sure the code compiles properly before continuing.

You'll need a "pom.xml" file in the root of your project. Just use the generic pom.xml file I shared earlier in Part 2 - Compiling and building your APK .

Contents

Steps to convert your project

The first thing you should do is replace as many lib/jar files as you can with their Maven dependency equivalent as covered in Part 2 of the tutorial. Visit the project's website and find the details as most of them will be available on Maven.

If you're using a shared library project then skim the points below before reading Part 4, which explains how to share library projects. You'll need to convert library projects first.

Once the pom.xml file is ready:

  • Right-click on your project > Configure > Convert to Maven project
  • It will now do things to your project and touch it in strange places.
  • Project > Clean to remove all the extra crud.
  • Maven > Update project to sync the settings and download dependencies
  • Run the mvn-debug script

OR

  • Build by right clicking on the project > Debug > Maven build
  • As before, enter in "package" as the goal.

 

You'll probably get some project specific errors so fix them as they come. Keep at it. Make sure it validates within Eclipse before continuing!

I know these steps are fairly generalised, but that's the main things to look for.

Women, children and library projects first

The pom.xml file for your library project should be very similar to the pom.xml for an APK project, with two minor differences.

Rather than using the <packaging> type "apk", we'll use "aar" instead which compiles to an Android ARchive format.

The other small difference is that it doesn't need to be signed for release builds.

Once your library projects are compiling cleanly, skip forward to the next tutorial to Part 4 for a moment to see how to include them into your APK project using local Maven repositories.

The tutorial also covers how you should include Google's support library in your code from the Android SDK.

Sorry for interlinked Part 3 and Part 4, but it's just the nature of this process.

Eclipse, Android and Maven: Part 2 - Compiling and building your APK

Now that you have Eclipse set up properly, you're ready to start building a project!

You should create a new project and learn how it works before you start migrating an existing project.

Contents

Creating a new Maven Android project

  • File > New > Other > Maven > Maven Project > Next > Next.
  • For "Catalog", select  Android (You'll need to be online for this to work)
  • Select "android-quickstart"
  • Next
  • Group ID is the package name portion of your app, such as "org.companyname"
  • Artifact ID is your app's compilation name, such as "codepeeker".
  • Version is pretty much the SEMVER version number. Snapshot indicates it's a dev build of sorts that's constantly pushing a compiled library to a repo. I usually set my version to 1.0.0 for new projects.
  • For more on naming conventions, see Maven – Guide to Naming Conventions
  • Package is prefilled as you enter in your Group and Artifact information.
  • Change platform to the Android API version needed.
  • Click finish when done.

image

  • And the result is this... a broken project.
image Same as regular Android development
gen: As before, this is the generated files folder.
src: Where your source files go
assets: Asset files
bin: Binary files. APK file no longer goes here!
res: Resource files. Feel free to remove all the ones you don't need. 

New folders
target: This is where you can find your APK file once it has been compiled.

New files
pom.xml: The configuration file which tells Maven how to build your project.

 

Ignoring the consume-aar goal

The pom.xml file generated for you is broken by default. At the bottom of pom.xml, you'll see this lint error:

Plugin execution not covered by lifecycle configuration: com.jayway.maven.plugins.android.generation2:android-maven-plugin:3.8.2:consume-aar (execution: default-consume-aar, phase: compile)

image

You can use the suggestions by clicking the red cross on the left to either:

  • Option 1: Mark it as ignored in pom.xml (preferred, but makes the XML messy)
  • Option 2: Ignore permanently in Eclipse (not advised if you work with other people or compile with command line)

Note: If neither of these options are available to you, close pom.xml, right-click it in the file explorer and select Open With > Maven POM Editor.

image

Choosing Option 1 will add the following <plugin> XML to ignore the consume-arr build goal (under build > pluginManagement > plugins). Don't copy paste, just let Eclipse do it for you.

This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.

Here's one I prepared earlier

I've created a generic pom.xml that works great as a base for most Android app projects. Just fill in the important parts and the rest should be fairly straight forward. Main things to change are:

<groupId>org.twig.apps</groupId>
<artifactId>d2_runewords</artifactId>
<version>1.0.0</version>
<name>Diablo 2 Runewords</name>
  • The platform version (Android API level).
<sdk>
<platform>16</platform>
</sdk>
  • Make changes to anything under <properties> to suit your system setup such as "android.sdk.path". These are Maven variables which you can access using ${varname}.
  • Added a jarsigner plugin so the Android APK is signed when we're ready to release.

A few other things I had to configure are:

  • Java version 1.6 as a minimum for annotation processing (butterknife, parceler, android annotations, etc)
  • I've configured the Android SDK local repository so you can easily use the support libraries. (More about that in Part 3)
  • The way you include dependencies is via dependencies > dependency
  • defaultGoal tells the script what to do and in what order. The "package" goal creates the APK and "android:deploy" pushes it to the device for testing.

Here's the file:

Whenever you make changes to pom.xml, you may need to keep the project in sync with it. Right click on your project > Maven > Update project (or Alt+F5 for those keyboard savvy users). This ensures the Eclipse project has the same configuration as the Maven pom.xml file, dependencies are pre-downloaded ready for compilation and stuff like that.

Compiling from command line

Personally I much prefer compiling from command line. It avoids a lot of the unnecessary complexities and repetitive confirmations involved with the Eclipse UI when it comes to debugging.

I created a script/batch file that contains the following command:

mvn package android:deploy android:run

What this does is compile your APK (package), push the APK to the emulator (android:deploy) and then start it (android:run).

I saved it in the same folder as your project and named it "mvn-debug.bat". Just run that whenever you want to debug your app. It's a lot less trouble than going through the "Eclipse way".

At this point you should be able to compile an APK file and find it in the "target" folder.

Compiling the Eclipse way

Now the Eclipse way...

  • Right-click on your project > Debug > Maven build.
  • Type in "package android:deploy android:run" as a goal.
  • Click "Debug"
  • Check the Maven console to see the log.
  • If everything went according to plan, you should now have a healthy baby APK sitting in your target folder.

image

image

Adding dependencies

Now the main purpose of this lengthy exercise is to easily add new dependencies and removing the complicated mess involved with annotation settings.

The best way of finding the dependency groupID and artifactID is looking up the project homepage and copying the install instructions. For example Butterknife. Here's the Gradle version:

compile 'com.jakewharton:butterknife:6.0.0'

Compared to the Maven version:

<dependency>
<groupId>com.jakewharton</groupId>
<artifactId>butterknife</artifactId>
<version>6.0.0</version>
</dependency>

It's pretty easy to translate the Gradle version to Maven, so if the project doesn't provide the Maven dependency XML you can just convert it yourself.

Under the <dependencies> tag, add in your dependency.

<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>${platform.version}</version>
<scope>provided</scope>
</dependency>

<!-- New dependency here -->
<dependency>
<groupId>com.jakewharton</groupId>
<artifactId>butterknife</artifactId>
<version>6.0.0</version>
</dependency>
<!-- /copy -->
</dependencies>

Optional: For some libraries which require multiple dependencies to be the same version (support-v4 and appcompat-v7), I like to have a dependency version under <properties>, so it's easy to find and change:

<android.support.version>19.1.0</android.support.version>

And replace the dependency version with:

<version>${android.support.version}</version>

Once you save pom.xml, update your project and it should automatically fetch any files needed from the Maven repository.

Perform a build to confirm everything is working fine.

Sources

Eclipse, Android and Maven: Part 1 - Installing Maven for Eclipse

Sadly, this tutorial series is far longer than it should be because of the sheer number of things that can go wrong during this process. I spent about a few days all up getting the whole process ironed out smoothly enough for A to Z Android APK development and release.

Some people may be wondering why I don't just use Android Studio because Gradle is awesome. I do, at home and yes, Gradle is good and I love the update process but I feel Android Studio still isn't quite there yet. There's still no one-button deploy+debug (something so trivial that happens so often in Android development) and it's constantly destroying my CPU/battery life while I'm travelling. That's just not feasible.

Note: Before you start, back up your Eclipse folder. If history is anything to go by, something may go wrong even if you did everything correctly. This quick backup can save you hours of configuration if something does go pear shaped.

Contents

Downloads

  • Eclipse v3.8.2 (I've found these instructions don't work for Eclipse below 3.8, unsure about v4.x+)
  • Java 7 JDK (not JRE. Java 6 is ok, but not Java 8)
  • Download Maven 3.2.3 (Binary zip).
  • While that's downloading, using the Eclipse software installer: Download Maven for Eclipse (m2e-apt) via http://download.eclipse.org/technology/m2e/releases
  • Untick "Show only the latest versions of available software"
  • Install "m2e - Maven Integration for Eclipse v1.4.1.20140328-1905".
    Don't use the latest version 1.5.0, it'll cause this error:

Cannot complete the install because one or more required items could not be found.
  Software being installed: m2e - Maven Integration for Eclipse (includes Incubating components) 1.5.0.20140606-0033 (org.eclipse.m2e.feature.feature.group 1.5.0.20140606-0033)
  Missing requirement: Maven Integration for Eclipse 1.5.0.20140606-0033 (org.eclipse.m2e.core 1.5.0.20140606-0033) requires 'bundle com.google.guava [14.0.1,16.0.0)' but it could not be found
  Cannot satisfy dependency:
    From: Maven Integration for Eclipse (Editors) 1.5.0.20140606-0033 (org.eclipse.m2e.editor 1.5.0.20140606-0033)
    To: bundle org.eclipse.m2e.core [1.5.0,1.6.0)
  Cannot satisfy dependency:
    From: m2e - Maven Integration for Eclipse (includes Incubating components) 1.5.0.20140606-0033 (org.eclipse.m2e.feature.feature.group 1.5.0.20140606-0033)
    To: org.eclipse.m2e.editor [1.5.0.20140606-0033]

  • Restart Eclipse when done.
  • Again using the Eclipse software installer: Download Android for Maven (Android Connector) from http://rgladwell.github.io/m2e-android/updates/. This lets you create Android projects using Maven.
  • Restart Eclipse when done.

Setting up Eclipse for Maven

The plugin com.jayway.maven.plugins.android.generation2:android-maven-plugin:3.8.2 requires Maven version 3.1.1

The android-maven-eclipse plugin has an implementation of Maven built into it. That implementation is for an older API and no longer compatible with the builds that we need (AAR support is needed for Android's appcompat-v7 and shared libraries).

  • Extract "apache-maven-3.2.3.zip" to "C:\Development\Java\apache-maven-3.2.3\" (You can put this anywhere, but adjust the instructions to match your folder)
  • In Eclipse, go to Preferences > Maven > Installations > Add > C:\Development\Java\apache-maven-3.2.3\
  • OK to save

Make sure you're using the right runtime environment.

  • Open up Preferences > Java > Installed JREs
  • If "JRE" is ticked then you've got the wrong runtime environment installed. What you need for development is a JDK, and Java 7 (or 6) is the version you need (Android doesn't support Java 8 yet).
  • Click on Search and find your Java installation folder, normally C:\Program Files\Java
  • Search should now fill in some JREs for you.
  • If no JDK's appear, you'll have to download a Java7 JDK and repeat the search after it's installed.
  • Select the JDK and click OK to save.

image

If you didn't set this up correctly, it will cause the following error:

No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?

This might sound silly, but open up Preferences again. This step needed the JDK to be set up properly in order to work.

Now we're going to select which environment is executed. This prevents the stupidly undescriptive "The method of type new must override a superclass method" error when trying to compile your code.

  • Go to Preferences > Java > Installed JREs > Execution Environments.
  • Make sure that you have "JavaSE-1.7" (or JavaSE-1.6 if you're using Java 6) and that the "Compatible JREs" column shows the JDK option.
  • Tick it, then OK to save.

image

System environment variables

One final step for the future is to set some system environment variables.

  • Start menu > type in "system environment variables"
  • Click on "Edit the system environment variables"
  • Click on "Environment variables"
  • Click new on either user or system variable
  • Firstly, set "M2_HOME" to "C:\Development\Java\apache-maven-3.2.3" (no trailing slash)
  • Now edit "Path" and add "%M2_HOME%\bin" at the end.

This will let you run "mvn" from any command prompt, which is needed for building, deploying and debugging later on.

Now you're finally to start converting your Android project to Maven.

Sources

Django: Export comments to Disqus WXR / XML format

With the help of the django-disqus module, it's pretty easy to export our comments out to Disqus.

First you'll need to install the module django-disqus (v0.4.3 at time of writing).

The example provided was used when I switched www.thatawesomeshirt.com over to Disqus. The class used is loosely based off the regular class used in the syndication module.

urls.py

from tas.feeds import ShirtCommentsWxrFeed

urlpatterns += patterns('',
('^export/comments/', ShirtCommentsWxrFeed()),
)

feeds.py

As you can see, this is where all the heavy lifting happens.

Once you have the output, you can import it more than once without creating duplicates. I believe duplicate detection is done using the value from comment_id().

image

In your Disqus admin:

  • Go to Discussions > Import > Generic (WXR) (using WordPress one will give you strange errors regarding the thread)
  • Upload the WXR file generated
  • Wait until it's done

I've noticed that files which are less than 10mb are processed rather quickly. Anything closer to the 50mb limit will take almost 24hrs to process.

All in all, it's probably one of the best processes for migrating comments that I've used so far.

like-a-boss_o_177339

Almost as good as this guy.

Sources

Disqus: Detect when comment count has loaded

With Django deprecating their contrib comments module, they suggested that we switched to Disqus as an alternative. It's pretty good, but I found that it was a little tricky to configure stuff on the Javascript side of things.

Sometimes we get a nice callback option to know when values have been filled in. That way we can tweak the output to suit our site if needed.

Not in the case with Disqus' count.js script. It populates any elements with a URL ending with "#disqus-thread" or the attribute "data-disqus-identifier" with the count values fetched from the Disqus server.

The only problem is we don't know when that's done, and it also fills in "0 comments" for us when we may not want it to.

The tl;dr solution

Here's the default unmodified script they tell you to paste in:

<script type="text/javascript">
var disqus_shortname = 'YOUR_SITENAME';
(function () { var s = document.createElement('script');
s.async = true;
s.type = 'text/javascript';
s.src = 'http://' + disqus_shortname + '.disqus.com/count.js';
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
}());
</script>

And this is what I'm telling you to paste in:

Explanation

If you haven't noticed already, the modified version uses jQuery in two places. If you don't want to use jQuery, then you should be able to port this code to any other Javascript library fairly easily.

The first place is via $.getScript(). This loads the count.js script file, executes it and then calls the callback function disqus_counts_loaded().

When the script is done with whatever it needs to do, it inserts another script called count-data.js into your page to fetch the data.

When count-data.js is loaded, DISQUSWIDGETS.displayCount() is automatically called to fill the elements full of the new luscious data.

Because we overridden displayCount() with our own function, it now fires an event afterwards to any elements wishing to know when the "disqus-counts-loaded" occurs.

Example usage

<script type="text/javascript">
$('.comments').bind('disqus-counts-loaded', function() {
var obj = $(this);

if (obj.text() == "0 Comments") {
obj.text("");
}
else if (obj.hasClass("user-review")) {
obj.text(obj.text().replace("Comments", "User reviews"));
}
});
</script>

This snippet hides anything that says "0 Comments". Why? Because it's distracting. It also changes "Comments" with "User reviews" on certain elements.

Spot the difference between the before/after screenshots.

imageimage

The layout on the right is much cleaner with  the "0 comments" clutter hidden away.

Sources

Java / Android + Retrofit: IllegalArgumentException: Only one HTTP method is allowed. Found: POST and POST.

What a terribly strange and cryptic error message to come across and totally undescriptive, so of course you've Googled it.

The source of the problem is actually quite easy to fix.

Take a look at your RetrofitAPI class. It'll probably look something like this:

@POST("/rest/events/event/{id}/")
Item saveEvent(@Path("id") int id, @Field("type") String type, @Field("title") String title, @Field("details") String details);

Well you're missing one more thing, the @FormUrlEncoded decorator!

That should fix up your problems.

Wl4AJzx

Android: Starting Genymotion virtual machine from command line

I got sick of seeing the GenyMotion launcher, so I looked for a way to start the device without actually having to click extra things.

image

If you know what your virtual machine "name" is, you can skip this step.

  • Go to the folder that VirtualBox is installed in command prompt and type:

VBoxManage list vms

  • That'll give you the list of virtual machines and their names. Copy the one you want to quick-start.

Now to create the one-click starter.

  • Create a shortcut to Genymotion's "player.exe" file.
  • Edit the shortcut and add in the --vm-name argument:

"C:\Program Files\Genymotion\player.exe" --vm-name "Google Nexus 7 2013 - 4.4.2 - API 19 - 1200x1920"

Where "Google Nexus 7 2013 - 4.4.2 - API 19 - 1200x1920" is the name of my virtual machine.

That's all you need to do.

anigif_enhanced-12037-1405373303-9

Now your dev-build apps can crash even sooner!

Source

Adobe Acrobat: Fix for "Error: undefined; OffendingCommand: setdistillerparams; ErrorInfo: CalCMYKProfile U.S. Web Coated (SWOP) v2"

%%[ Error: undefined; OffendingCommand: setdistillerparams; ErrorInfo: CalCMYKProfile U.S. Web Coated (SWOP) v2 ]%%
%%[ Flushing: rest of job (to end-of-file) will be ignored ]%%
Error accessing color profile: U.S. Web Coated (SWOP) v2
%%[ Warning: PostScript error. No PDF file produced. ] %%

For a while now, my PDF creation has been broken and I never really bothered to read the error message. When I finally did, I thought what a strange error to come across.

Somehow, the colour profile "U.S. Web Coated (SWOP) v2" has gone missing.

Good thing Adobe has these up on the internet for us to download.

  • Go to the "ICC profiles for Windows" page to grab "Adobe ICC profiles".
  • Click "Proceed to download"
  • Click "Download Now" (So many steps to download a bloody file)
  • Now extract "AdobeICCProfilesWin_end-user.zip"
  • Go to "Adobe ICC Profiles (end-user)\CMYK Profiles"
  • Right click "USWebCoatedSWOP.icc" and click "Install Profile".
  • That should now fix your problems.

9825_5765
Well, okay just one of them.

Source

Survey Monkey: The comment you entered is in an invalid format.

Spent some time trying to figure out what was wrong with this due to vague emails from staff saying "teh surveh iz broke, plz fix kthx".

e7448566054fc83051a5cdc5efaee22c
"Everything is urgent! Please fix immediately! I'm so important!"

After a bit of trial and error, the horribly worded error is due to a character limit imposed on the input field.

If your field is limited to 100 characters and the user inputs 101 or more characters, they'll get this vague error.

Just be sure to let them know of the limit in the description or something.

Source

Good old trial and error.

Windows 10 Tech Preview: Remove live tiles from the Start menu

If you're completely uninterested in any offerings from the Windows app store, then Microsoft have heard our cries and made them... OPTIONAL! Yes that's right!

For each tile that's been annoyingly preinstalled, you can remove unpin them from the start menu or even uninstall them until you get a nice clean start menu.

To hide or remove them, right click on each tile until satisfied. There will be some apps that you can't uninstall (such as PC settings), so you'll have to make do with using "Unpin from Start".

image

image

Oh sweet simplicity has never been so sexy!

Installing Windows 10 Tech Preview on Virtual Box

Downloads

First of all, you'll need the Windows 10 Tech Preview ISO. You can get it from Microsoft's download page. I grabbed English 64-bit (x64), which was "WindowsTechnicalPreview-x64-EN-US.iso"

Setting up the VM

Back over in Virtualbox-land, as per usual you just create a new virtual machine for Windows 8.1 and matching the build you've got (x86 or x64). I'll assume you got the x64 build. Everything is per usual, create a new hard-drive, etc.

Once you're done, go to "System" settings for that VM. Despite what another guide has wrongfully stated, make sure that "Enable EFI (special OSes only)" is OFF and under the Processor tab that "Enable PAE/NX" is OFF as well. If these are left on, you won't be able to enter the installation process.

Lastly, go to "Storage" and select the CD icon from "Storage tree". Click on the CD icon on the right and select "Choose a virtual disk file", then select your Windows 10 ISO file.

Installation

Nothing out of the ordinary here. Takes about half an hour on a regular non-ssd HDD.

It installs smoothly just like Windows 8.1 and even has the same wizard process during the first boot.

1 2 

Yay, store apps. Exactly what I didn't want.

3 
That bloody "Almost ready" was there for a frikken long time!

5

Unfortunately, there isn't any visible way of getting rid of that list of apps from the start menu.
I'll find a way by reworking my BreadCrumbKiller or SPASM programs.

To get rid of the live tiles from your Start menu, see here.

VirtualBox Guest additions

Majority of it works, but if you wanted the whole she-bang you can extract the drivers and manually install the video drivers.

  • Go to Devices > "Insert Guest Additions CD image"
  • Then open up command prompt in your VM.
  • Type:

cd /d D:

# If x64

VBoxWindowsAdditions-amd64 /extract /D=C:\Drivers

# If x86

VBoxWindowsAdditions-x86 /extract /D=C:\Drivers

  • Wait for it to finish.

image

  • Open up Device Manager and find the "VirtualBox Graphics Adapter".
  • Right click it and select "Update driver software"
  • Browse my computer for driver software
  • Click Browse
  • Select C:\Drivers\
  • Next
  • Done!

XBMC / Kodi: List files not found in library

One of the biggest hurdles for people setting up their first XBMC/Kodi machines is getting content to scan correctly.

Although the scanner supports a number of different naming conventions, there's still no built-in way of checking which files have been ignored by the library scanner.

That's why "null_pointer" created "Missing Movie Scanner". It checks your library and finds any movie files which have been ignored by the library, so you know which ones to rename properly.

image

Installation

  • Load up XBMC
  • Settings
  • Add-ons
  • Get Add-ons
  • XBMC.org Add-ons
  • Video Add-ons
  • Scroll down to "Missing Movie Scanner"
  • Select install
  • Go back to the home menu
  • Access Add-ons from your home menu (you may need to enable this, depending on your skin)
  • Select "Video Add-ons"
  • Missing Movie Scanner
  • Now you can select between movies or TV shows
  • The next screen will list the files which aren't included in your library.

anigif_enhanced-buzz-14424-1386607752-4
No, sadly this won't fix any high-5 misses

Source

Python: Visualise your class hierarchy in UML

Sometimes it's handy to graph out the way your classes are arranged, either for training purposes or simply to help you plan your next move.

There's always the option of doing it manually, or you can use some handy tools to do so.

To get the ball rolling, grab pylint and graphviz

sudo apt-get install graphviz libgraphviz-dev python-dev
pip install pylint pygraphviz

If you don't have python-dev installed, you'll run into the error below:

pygraphviz/graphviz_wrap.c:124:20: fatal error: Python.h: No such file or directory
#include <Python.h>

Now back in your project folder, type:

pyreverse -my -A -o png -p test **/classes.py

Replace "classes.py" with "**.py" if you want all python files.

Another example is if you wanted to graph all the form classes:

pyreverse -my -A -o png -p test **/forms.py

Once it's done, you'll now have classes_test.png and packages_test.png in the folder. The packages image allows you to determine if your code modules are properly decoupled. The classes files shows you how twisted your class inheritance may be.

classes_test

Django models

For Django specific projects, you can install a module called "django_extensions". It also uses graphviz to generate some cool charts but is very Django friendly so you don't have to manually remove Meta classes from your models.

The syntax for graphing models is:

python manage.py graph_models -g -e -l dot -o my_project.png module_a module_b module_c
  • -g groups the models into their respective apps for easier viewing
  • -e shows the inheritance arrows
  • -l uses the "dot" rendering layout by GraphViz (possible values are: twopi, gvcolor, wc, ccomps, tred, sccmap, fdp, circo, neato, acyclic, nop, gvpr, dot, sfdp. I found dot to be the only legible one, and most of them didn't work for me)
  • "-o my_project.png" is the output file
  • module_x includes all the modules which you want to draw

directory_listing

Nintendo 3DS: Transferring your emuNAND to another SD card

Sometimes you need to bump up the size of your SD card to get a game like Super Smash Bros Demo to work. I got a download code from Club Nintendo but it kept freezing on a black screen when I tried to run it!

People eventually figured out you need an SD card 4gb or larger in order to run it. I was only using the 2gb one given with the 3DS so what the hell, time to find a spare SD card laying around the house.

Just copying the files directly from one SD card to another won't work. Fortunately, some smart cookie developed "emuNAND Tool" that does all the hard work for you.

  • Have a working emuNAND as the source SD card.
  • Create an extra emuNAND on the target SD card (see "Creating your EmuNAND" section of a previous tutorial)
  • While your 3DS is creating an emuNAND, grab "emuNAND Tool v1.0.1".
  • Open "emuNAND Tool" and click "Extract emuNAND" to extract the emuNAND from the source SD card to a file (it doesn't take that long, probably a minute or two at most)

emuNAND tool

  • By the time your target SD card is done creating a new emuNAND, take it out of your 3DS and put it into your computer.
  • Click "Inject NAND to emuNAND" and select the file you saved from the source SD card earlier.
  • It will now copy the emuNAND files across to the target SD card.
  • Once it's done, you've now got a replica of your previous emuNAND.
  • Put it back into the 3DS and use it as you normally would.

Note: Games downloaded from the eShop won't be copied. You'll have to re-download those.

nyanimefest08_42
Time to brawl!

Sources

XBMC / Kodi: (Amber Skin) Adding a custom menu item to the main menu

Changing skins isn't easy, but I was getting a bit annoyed at Aeon Nox and the excessive CPU usage when idling in menus. Eventually I went with Amber, a super light weight skin with some pretty good customisation.

For this example, I'll show you how to add Steam games and a custom playlist to your main menu. I used the Steam Launcher addon by Teeedubb, so you'll need that first (or whatever addon you're using).

To begin make sure you have Amber skin installed, along with any addons you wish to add to the main menu.

  • Settings
  • Home Menu
  • Enable "Add-ons"

image

  • Go back to the main menu
  • Select "Add-ons"

image

  • Select Programs
  • Select Steam
  • Press "C" on the keyboard to bring up the context menu
  • Select "Add to favourites"

image

  • Likewise with the custom playlist, I'm going to add "Anime" to the main menu.
  • Go to TV Shows > Playlists (submenu) > Highlight your playlist of choice and press "C"
  • Select "Add to favourites"

image

  • Now go back to Settings
  • Home menu
  • And pick an empty slot where you want to put your new custom menu

image

  • Select it
  • Pick Steam
  • Call it "Games"
  • Your menu item should now appear as "Games", but activate the "Steam" addon!
  • Do the same with your custom playlist

image

  • Before moving on, be sure to hide the Add-ons menu if you don't need it anymore.
  • Go to Settings > Backgrounds to customise the background for your new Games menu item
  • And there you have it! You've now got custom menus working on your XBMC menu.

image

Source

Honda Jazz/Civic: Fix for auto-down or auto-up on driver power windows not working

It was a bit strange but after the battery was replaced on my car, the auto-down on the window no longer worked. Luckily it's a known quirk and it's an easy fix.

You just need to reset the window control unit by:

  • Winding it down all the way
  • Winding it all the way back up
  • When it reaches the top, keep holding up for another 3 seconds.

The window should now have auto-up/auto-down enabled again.

6-bizarre-car-Exhausts
Now go forth and fix the other problems with your car!

Sources

Sony Xperia Z1 Compact (D5503): Stock Firmware / ROM Flashing Guide

Every time I buy a phone, it's because I want the phone and the software that comes with the phone... WITHOUT the pre-bundled carrier rubbish. I simply just don't trust carriers tinkering with software and adding bugs. Plus it's always better to get it from the manufacturer because you can get updates right away.

The process is sometimes referred to as "debranding", but quite simply all you're doing is flashing the stock firmware back onto the phone.

Sometimes it's easy to get rid of, other times it's not. Fortunately for us, the guys who made Flashtool has made our lives VERY easy (compared to the loops I had to jump through with Samsung Galaxy phones...)

image
Boot animations of the bastardised branded phone vs the stock firmware (before/after)

What you'll need

What you should NOT use is Sony's "Flash tool for Xperia™ devices". It requires registration and well...

Fo-Dat[1]

  • Flashtool - Xperia device flashing is what you want. The speeds were slow, so I got mine from here. It's a big download (176mb) at slow speeds so leave this downloading while you set up the rest. At time of writing, I used v0.9.18.1.
  • You'll need at least 4.3gb of FREE space for the process. (mine took 4.11gb)
  • It's useful to know the region ID and carrier branding for your device before-hand. This isn't necessary, but helpful when deciding which firmware to download (carrier specific vs generic without branding). You can find more information about regions on this page.

In my case, for Australia you have Generic (1281-3422) vs Telstra (1281-1039). The Telstra one is the branded one that came with my phone, so I will choose the generic one to remove all the extra crud.

Setup

  • Run the "flashtool-0.9.18.1-windows.exe" installer
  • Install it to C:\Flashtool\ (or any folder of your choice, but my instructions will assume this)
  • Go to that folder and run flashtool.exe (or flashtool64 if you're on a 64bit o/s)
  • Let the program update itself with the latest settings from online

Getting the stock firmware

  • Click on the Devices menu > Check updates
  • Double click the phone model "D550X Sony Xperia Z1 Compact"
  • Double click your region to check for the latest version (v14.4.A.108 at time of writing)

The wording may be a little confusing, but "(1281-3422 Customized AU)" is the stock firmware, also known as generic Australian firmware without carrier branding.

  • Right click > Download > Wait. Best tool ever!
  • When the "Bundler" window appears, select everything EXCEPT for the .ta files (should be cust-reset.ta and fota-reset.ta, and maybe simlock.ta)
  • Click the right arrow button
  • Click Create and wait.
  • When it's done, you'll have your TFT file!

image

Flashing the stock firmware

  • Turn off your phone
  • Click on the flash icon in Flashtool
  • Select flashmode
  • Select your firmware from before (14.4.A.108 Customized_AU)
  • Hold the VOLUME DOWN and plug in the phone to get into flash mode
  • Should be a green LED light on the phone (briefly)
  • Check the status logs to see that it connected in flash mode properly
  • Click Flash (If you wait or take too long, the phone just boots up normally and you'll have to restart the process)

image

  • Now just wait a few minutes until it finishes flashing.
  • Unplug
  • Turn on phone
  • Enjoy your new firmware!

If needed, here's my guide on how to root a Sony Xperia Z1 Compact (D5503) and unlocking your Sony Xperia Z1 Compact (D5503) bootloader.

Sources

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog