Idea intellij “USB device not found” Android problem

Lately I’ve been really frustrated with this message. I don’t know when it has started to pop up, but every time I’m in the middle of important debugging, and want to restart the app I get this message when starting the app:

USB device not found

I’ve read bunch of blogs and stackoverflow questions and answers but nothing helped. Then I tried one very simple trick:

adb kill-server
adb devices

After that I’ve got this response:

* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
37329B0B96FD00EC    device

After that intellij worked without problems.

Advertisements

Passing objects from one Activity to another

When you want to transfer some parameters (String, int, whatever) in Android you can pass it via one of the Intent.putExtra methods. It’s simple as that. You can say:

int parameter = 42; // just an example

Intent intent = new Intent(currentActivity, newActivity.class);
intent.putExtra("myParameter", parameter);
startActivity(intent);

But what happens when you want a pass your custom made class instance? You can pass:

  1. it’s id and gather it from db or web service for example. That’s OK, but it’s a bummer if you have already have it, why do the same thing again?
  2. your class could implement Serializable interface. This is a perfectly working solution, but as many people said, it’s not an optimal solution (just take a look at stackoverflow)
  3. or use android’s Parcelable interface :)

Just to be clear, I don’t like implementing additional serializing/deserializing code, but as it turns out, it’s pretty simple to implement it, and it improves performance. So why not? :)

To make your class Parcelable, you have to implement the following methods:

int describeContents();
void writeToParcel(Parcel dest, int flags);

And you have to define a public static field named CREATOR (that implements Parcelable.Creator<T>)

Just take a look this example:

import android.os.Parcel;
import android.os.Parcelable;

import java.util.Date;

public class ExampleParcelable implements Parcelable {

   private String stringValue;
   private Integer integerValue;
   private char charValue;
   private boolean boolValue;
   private Date dateValue;

   @Override
   public int describeContents() {
      return 0;
   }

   @Override
   public void writeToParcel(Parcel dest, int flags) {
      dest.writeString(stringValue);
      dest.writeInt(integerValue);
      dest.writeInt(charValue); // yup, it's actually a char
      dest.writeInt(boolValue ? 1 : 0); // can't store bools, but we can do it this way
      dest.writeLong(dateValue.getTime()); // same here, can't write date's, but we can get time in long
    }

    // Added this default constructor in case you are using some JSON/XML whatever parsers that require no-arg constructor
    public ExampleParcelable() { }

    /**
    Just to make life easier, I've added a constructor that creates our ExampleParcelable from a Parcel (of course, you don't have to do it that way)
    */
   public ExampleParcelable(Parcel parcel) {
       // The only important thing is to read them in the same
       // order as you wrote them (take a look at writeToParcel)
       stringValue = parcel.readString();
       integerValue = parcel.readInt();
       charValue = (char) parcel.readInt();
       dateValue = new Date(parcel.readLong());
   }

   public static final Parcelable.Creator CREATOR = new Creator<UserContentInfo>() {

    @Override
    public ExampleParcelable createFromParcel(Parcel source) {
       return new ExampleParcelable(source);
    }

   @Override
   public ExampleParcelable[] newArray(int size) {
      return new ExampleParcelable[0];
   }
};

}

It’s pretty much straight forward. In writeToParcel method you need to write fields that you need (in case you don’t want to pass every field), and later in CREATOR’s createFromParcel read every field in the same order you’ve written to Parcel in the first place.

I’ve added an example how can you write, and later read char and date types. Because can’t write everything (but it can write other Parcelables in case you need it).

Using it is the same thing as in the first example

ExampleParcelable test = new ExampleParcelable(); // just an example, set fields you need

Intent intent = new Intent(currentActivity, newActivity.class);
intent.putExtra("myParameter", test);
startActivity(intent);

Also, in case you are super-lazy to implement your own Parcelables, I’ve found this awesome project (source code: https://github.com/dallasgutauckis/parcelabler).
It creates them for you :)

Mavenizing android projects

I must confess, I like building my java apps with maven because I really hate managing all the dependencies, and on the other side I can use great tools like sonar and jenkins/hudson out of the box.

So the goal was to build my android project with maven.  First stop was of course the official android-maven url: http://code.google.com/p/maven-android-plugin/

In the getting started it was pretty clear to install jdk, android sdk, maven and that’s about it. I’ve created my pom file like they said:

<dependency>
   <groupId>com.google.android</groupId>
   <artifactId>android</artifactId>
   <version>1.6_r2</version>
   <scope>provided</scope>
</dependency>

In the project I’m talking about, I’m using android 1.6. After mvn clean install I had my first problem.

1. Maps not found

package com.google.android.maps does not exist

So that was pretty clear that I only have “clean” android installed (or at least in my mvn repo). After a quick google search, I’ve found out about mvn android sdk deployer (https://github.com/mosabua/maven-android-sdk-deployer). That seemed to be the answer to my problems. Yup, just clone the repo, mvn clean install it and you’re ready to go. But after running mvn clean install (for maven android sdk deployer) I’ve got the following error:

2. addon-google_apis-google-3/source.properties not found

Failed to execute goal org.codehaus.mojo:properties-maven-plugin:1.0-alpha-2:read-project-properties (default) on project google-apis-3: Properties file not found: /Users/vuknikolic/dev/android-sdk-mac_x86/add-ons/addon-google_apis-google-3/source.properties -> 

This one confused me, I knew that I had google add-on installed for v3, I’ve checked the path, but it wasn’t there. Then I saw on maven-android-sdk-deployer’s github page:

Platforms and Add on folder names changes in SDK

When updating an existing android sdk install the add-ons subfolder can sometimes be reused and their contents be updates so you could end up with e.g. the google maps-4r2 in a folder named google_apis-4_r01. To work around this just uninstall the affected add-on and reinstall it with the android sdk tool.

After that android mvn deployer worked like a charm, great works guys. So I’ve returned to my project, started mvn clean install… and…

3. JSON not found?

package org.json does not exist

This one seemed weird, cause why on earth would I miss something inside of android sdk? If it is installed already… My good friend Google saved me again (http://code.google.com/p/maven-android-plugin/issues/detail?id=77), there seems to be a problem with 1.6_r2 package as well, so I had to upgrade it to 2.1.2 as advised in that issue.

After that I was finally building my android project with maven. So here are the five easy steps to start building your android project (that uses google maps) with maven:

  1. Create pom.xml and set version to 2.1.2 or above in maven dependency
  2. Clone maven-android-sdk-deployer
  3. Uninstall old installed versions with Android SDK manager and install them again (just to make your life easier)
  4. Start mvn clean install in maven-android-sdk-deployer
  5. Start mvn clean install in your project