Debugging Android over Wifi

Super simple:

  1. Connect your device via USB and ensure debugging is working (e.g. make sure Android Monitor in Android Studio is displaying live logs).
  2. At a terminal / command prompt, type adb tcpip 5555
  3. Disconnect the USB and proceed with wifi debugging.
  4. Then type adb connect DEVICE_IP:5555 (you can get your device’s IP address from your Wifi connection properties – advanced settings)
  5. [Optional] To disconnect Wifi debugging when you’re done, type adb -s DEVICE_IP:5555 usb

If you experience adb hangs when executing these commands, try with another android device. if that works, try disabling / enabling wifi on the problematic device. You may also need to adb kill-server and adb start-server to reset things.

Can’t scp using git-shell

I recently created a new Android app on my local dev box, but when I went to copy it to my git server using:

scp -r -P 9876 AppProjectFolder.git git@myserver.address.com:/opt/git

I got this:

fatal: unrecognized command ‘scp -r -t /opt/git’
lost connection

After researching, I found it is due the git user on my server using git-shell (to restrict commands that can be used). However, I’m sure I used to be able to use the scp command even when using git-shell. I couldn’t find the root cause, so I just modified /etc/passwd to set the git user to use /bin/bash temporarily, then switched it back after the files were copied. My server is running Fedora 19, if anyone knows what can cause this and/or how to fix it please post a comment.

Run unit tests in a batch loop

We had a case where a tests was randomly crashing the MSTEST agent process, leave no trace of the root cause. So to reproduce, we ran the test in a loop in both MSTEST and xUnit frameworks using the following scripts, posted here for future reference:

rem Run unit tests in an assembly in a loop using xUnit (build 1705).
FOR /L %%i IN (1,1,5000) DO (
xunit.console.clr4 UnitTests.dll /xml C:\xunit-results\output%%i.xml
)

rem Run unit tests in an assembly in a loop using MSTEST.
FOR /L %%i IN (1,1,5000) DO (
mstest /testcontainer:UnitTests.dll /resultsfile:c:\mstest-results\output%%i.xml
)

Starting a legacy animation with delay from script in Unity

Applies to: Unity 4.5.5f1 (and possibly other versions)

Unity has introduced a new animation system called Mecanim, but the existing animation system is still available to use. If you are using the old animation system you’ll be using an ‘animation’ component rather than an ‘animator’ component on your gameobject. And when you do so, you’ll likely see at least one of these warnings:

The AnimationClip ‘x’ used by the Animation component ‘y’ must be marked as Legacy.
Default clip could not be found in attached animations list.

There are two ways to solve this, depending on whether you have a model (e.g. via a prefab) or not.

You have a model
Select the model and on the Rig tab of the import settings, change the animation type to ‘legacy’.

rig-tab

You don’t have a model
In this case, select the animation and then in the inspector, RIGHT-click the ‘Inspector’ tab and choose ‘Debug’.

inspector-debug

Then change the animation type value from 2 to 1. Then change back to ‘Normal’ mode on the Inspector tab and when you run your app, this warning should be gone.

It is simple to apply your legacy animation to a gameobject by simply adding an ‘animation’ compoment and dragging the animation to appply onto that component. In this case, the animation will by default play on startup of your app. But what if you want to start the animation after some delay via a script, for example. To do this, uncheck ‘Play automatically’ in the animation component, then add a new script component to your game object. You can use the following code to start the animation after a 3 second delay. This also demonstrates how to achieve a fixed delay from a script.

public class startanim : MonoBehaviour {

	private bool started = false;

	// Use this for initialization
	void Start () 
	{
	}
	
	// Update is called once per frame
	void Update ()
	{
		if (!started)
		{
			executeWait();
			started = true;
		}
	}

	private void executeWait()
	{
		StartCoroutine(Wait(3.0f));
		Debug.Log("This line runs *immediately* after starting the Coroutine");
	}
	
	private IEnumerator Wait(float seconds)
	{
		yield return new WaitForSeconds(seconds);
		Debug.Log("3 seconds has passed, animation is now starting.");
		this.animation.Play ();
	}
}

Finally, the debug output can be viewed at the bottom of the unity window:

debug-output

Auto-Complete not working in Eclipse

After upgrading from Linux Mint 13 to 17 (and Eclipse from Juno to Luna) I noticed that auto-complete (also called content assist) which is normally invoked using Ctrl+Space is not working anymore. After searching I found it is not actually caused by Eclipse, but instead the IBus (Keyboard) preferences eat Ctrl+Space so Eclipse never receives it! This is a very poor choice of global shortcut and it has been reported as a bug here. You can confirm Eclipse is not receiving it by going into Window->Preferences->General->Keys and attempting to enter Ctrl+Space for a key.

Until it is fixed, you can work-around it by right-clicking the keyboard icon in the system tray (next to the clock), choose ‘Preferences’ and select a different shortcut for ‘Next Input Method’.

USB Driver for Nexus 5 on Windows 7

When I plugged in my Nexus 5 to my Windows 7 PC, it was not recognised, even after I used the Android SDK Manager to install the latest Google USB Driver. I finally worked out that there is a manual step you must take: Check the tooltip to find out where the USB driver was downloaded to (I found one under Program Files folder that was not installable – make sure you refer to the tooltip), and use Device Manager to update the driver, pointing to this folder. Then you can debug on your Nexus using ADB.

usb-driver

Confusing A .Net Assembly

UPDATE: I no longer recommend using Confusor (or any other obsfucator tool) after I have discovered that many anti-virus programs detect obsfucated assemblies as false-positives. If that is a deal-breaker for you (as it is for me) then it seems there is no good way to secure (ok, make it slightly more difficult to reverse engineer) a .Net app. Which sucks.

Recently I had to obsfucate a .Net (C# WPF) project that was a license generator, and after researching it seems that the best free tool to use for this is Confuser. It comes in both a GUI and console version, so you can try it, and then integrate it as a post-build step if you’re happy. And I was. IlSpy showed pretty much everything was replaced with foreign / non-printable characters. FYI the console version (Confusor.console.exe) takes a crproj file, which you is created by first running the GUI app and then pressing save on that tool. Then it’s a simple matter of adding a post-build step to call the console version passing the path to the crproj file and you will have your obsfucated assembly created in a subfolder called ‘Confused’.

Two gotchas:

  1. The generated CRPROJ file contains absolute paths, which of course need to be replaced (manually) with relative paths. Remember that the current directory will be the build output directory. My CRPROJ file looks like this:
    
    <?xml version="1.0" encoding="utf-8"?>
    <project outputDir=".\Confused" 
       snKey="" 
       preset="normal" 
       xmlns="http://confuser.codeplex.com">
       <assembly path=".\LicenceGenerator.exe" isMain="true" />
    </project>
    
  2. The generated CRPROJ file contains the path to the executable to obsfucate, which usually includes a debug / release identifier. To fix this issue, you can simply conditionally call the post-build step by doing this:

    if $(ConfigurationName) == Release $(SolutionDir)Confuser\Confuser.Console.exe $(SolutionDir)$(SolutionName).Confusor.crproj

  3. Note that this post build step needs to be all on one line in your project properties field in Visual Studio.

Happy with that!

Setting LinearLayout background on activity launch

Just came across an issue where on one device (HTC Desire X) I was unable to set the background resource for the root LinearLayout of my activity’s view, even though it worked fine on multiple other devices. The code I was using:

setContentView(R.layout.background);
LinearLayout appBackground = (LinearLayout)findViewById(R.id.appBackground);
appBackground.setBackgroundResource(someResourceId);

The above code was called from onCreate(), and a call to invalidate() didn’t help. To fix it I had to post a delayed runnable to set the background a little later:

setContentView(R.layout.background);

new Handler().postDelayed(new Runnable() {
  @Override
  public void run() {
    LinearLayout appBackground = (LinearLayout)findViewById(R.id.appBackground);
    appBackground.setBackgroundResource(backgroundResourceId);
  }
}, 200);

Yes it sucks, but it works and the delay is not noticable. Variation between Android devices sucks :S