Friday, August 22, 2025

Home Assistant - Intel(R) Centrino(R) Ultimate-N 6300 AGN

After running Home Assistant on VirtualBox in Windows I wanted to install it on one of my older computers, a Dell Latitude E6410 laptop (11 years old now, Intel Core i5 560M @ 2.67GHz, 8GB RAM).

I went through all the trouble of learning the wrong ways to install it (boot with it's live boot, cannot install in a partition, in the end went with the Ubuntu Live with image restore method), got it working on a wired connection and wanting to make it later work on wifi, to notice in the Settings > System > Network that... there is no wifi.

Googling didn't help much, eventually talking about it with ChatGPT he suggested to use `dmesg | grep -i wifi` to find out that... it doesn't have firmware files for my wifi card! great.

➜  ~ dmesg | grep -i wifi
[    4.716708] Intel(R) Wireless WiFi driver for Linux
[    4.717648] iwlwifi 0000:03:00.0: enabling device (0000 -> 0002)
[    4.720872] iwlwifi 0000:03:00.0: can't disable ASPM; OS doesn't have ASPM control
[    4.729548] iwlwifi 0000:03:00.0: Detected crf-id 0xa5a5a5a1, cnv-id 0xa5a5a5a1 wfpm id 0xa5a5a5a1
[    4.731348] iwlwifi 0000:03:00.0: PCI dev 422b/1121, rev=0x74, rfid=0xd55555d5
[    4.732261] iwlwifi 0000:03:00.0: Detected Intel(R) Centrino(R) Ultimate-N 6300 AGN
[    4.733249] iwlwifi 0000:03:00.0: Direct firmware load for iwlwifi-6000-6.ucode failed with error -2
[    4.735987] iwlwifi 0000:03:00.0: Direct firmware load for iwlwifi-6000-5.ucode failed with error -2
[    4.738758] iwlwifi 0000:03:00.0: Direct firmware load for iwlwifi-6000-4.ucode failed with error -2
[    4.740960] iwlwifi 0000:03:00.0: no suitable firmware found!
[    4.741997] iwlwifi 0000:03:00.0: minimum version required: iwlwifi-6000-4
[    4.743000] iwlwifi 0000:03:00.0: maximum version supported: iwlwifi-6000-6
[    4.743002] iwlwifi 0000:03:00.0: check git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git 

You can find one of the firmware files at that location (https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/iwlwifi-6000-4.ucode) but it appears you cannot deploy new firmware manually and will not be persisted between boots.

Unfortunatelly, it appears the way to go is to create a GitHub ticket and try to convince them to add the firmware to the product, although changes to add drivers for such old devices is probably slim ("[...] Unlike other distributions we don't to that pre-emptively, as we need to cope with rootfs space constraints, but given that this WiFi cards doesn't seem to be an obscure one, adding support for it makes sense to me.").

 https://github.com/home-assistant/operating-system/issues/3643 

Tuesday, April 2, 2024

Eclipse ADT plugin with D8 dexer

If still developing with Eclipse for Android using Google ADT plugin you may encounter the error below when dexing some newer libraries:

processing archive U:\Workspaces\AndroidX Browser\github\android-androidx-browser\libs\androidx-browser.jar...
processing META-INF/androidx.browser_browser.version...
processing androidx/browser/trusted/splashscreens/SplashScreenVersion.class...
... Uncaught translation error: com.android.dx.cf.code.SimException: ERROR in androidx.browser.customtabs.CustomTabsService$1.newSessionInternal:(Landroid/support/customtabs/ICustomTabsCallback;Landroid/app/PendingIntent;)Z: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13) Uncaught translation error: com.android.dx.cf.code.SimException: ERROR in androidx.browser.trusted.ConnectionHolder.getServiceWrapper:()Lcom/google/common/util/concurrent/ListenableFuture;: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13) Uncaught translation error: com.android.dx.cf.code.SimException: ERROR in androidx.browser.trusted.TokenContents.createToken:(Ljava/lang/String;Ljava/util/List;)[B: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13) Uncaught translation error: com.android.dx.cf.code.SimException: ERROR in androidx.browser.trusted.TrustedWebActivityServiceConnectionPool.connect:(Landroid/net/Uri;Ljava/util/Set;Ljava/util/concurrent/Executor;)Lcom/google/common/util/concurrent/ListenableFuture;: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13)

Let's try to understand how Google ADT plugin works:
DexWrapper.java (ADT plugin) looks for ANDROID_SDK\build-tools\xx.yy.zz\lib\dx.jar and loads it, then calls run(Arguments) method in com.android.dx.command.dexer.Main through reflection.

Since those classes do not exist in newer D8 dexer you won't be able to use directly ADP with D8.

Unknown error: Unable to build: the file dx.jar was not loaded from the SDK folder!

But what if we create an adapter that sits in between and knows how to receive the dx.jar call and transfer it to d8.jar?
And that is exactly what dandar3/android-dx-d8-adapter does. 

1. Install `build-tools` version 33.0.3, that will come with D8 (and without DX) and is the last version that is built with Java 8 (runtime version used to run Eclipse and JDT):

> tools\bin\sdkmanager "build-tools;33.0.3"
done
> dir build-tools\33.0.3\lib\d*.jar
03.04.2024 00:03 8.190.549 d8.jar

2. Clone dandar3/android-dx-d8-adapter and build from sources (see README.md) or download the latest build from Releases page (right side).

3. Save as `dx.jar` next to `d8.jar` in build-tools\33.0.0\lib\

4. Restart Eclipse.

5. Rebuild your project, look in `Console` > `Android` view:

Android DX to D8 adapter
Version 1.0 (Feb 2023
https://github.com/dandar3/android-dx-d8-adapter

DX called with:
 verbose    = false
 forceJumbo = false
 jarOutput  = true
 outName    = U:\Workspaces\Android\[...]\demo\bin\dexedLibs\androidx-arch-core-common-95b383e1e508bb35b6c34b9ff46ba8ce.jar
 fileNames  = [U:\Workspaces\Android\[...]\android-androidx-arch-core-common\bin\androidx-arch-core-common.jar]

D8 called with:
  jar       = U:\Android\android-sdk-eclipse\build-tools\33.0.3\lib\d8.jar
  arguments = [--output, U:\Workspaces\Android\Eclipse [ADT]\__TESTS\AndroidX Browser\demo\bin\dexedLibs\androidx-arch-core-common-95b383e1e508bb35b6c34b9ff46ba8ce.jar, U:\Workspaces\Android\Eclipse [ADT]\__TESTS\AndroidX Browser\github\android-androidx-arch-core-common\bin\androidx-arch-core-common.jar]
  elapsed  = 00:00:00.794

Thanks to iRootS and Bolfish.

Wednesday, June 8, 2022

Updating `dx.jar` library to fix `Dx unsupported class file version 52.0`

If you're still developing with Eclipse & Google ADT plugin you may encountered this error when trying to use Java libraries compiled with JDK 1.8:

[2022-05-11 08:55:53 - demo] Using default Build Tools revision 25.0.3
[2022-05-11 08:55:53 - demo] Starting full Post Compiler.
[2022-05-11 08:55:53 - demo] Dx Using Pre-Dexed androidx-versionedparcelable-2b1eb8b8b275a1d7c02af96379c6a5af.jar <- R:\Workspace\androidx-versionedparcelable\libs\androidx-versionedparcelable.jar
[2022-05-11 08:55:53 - demo] Dx Using Pre-Dexed androidx-lifecycle-common-eb8ba09572c04143f806576a1b143ada.jar <- R:\Workspace\androidx-lifecycle-common\libs\androidx-lifecycle-common.jar
[2022-05-11 08:55:53 - demo] Dx Pre-Dexing R:\Workspace\androidx-annotation-experimental\libs\androidx-annotation-experimental.jar -> androidx-annotation-experimental-b634477a1038eeb097daf1a0fd5faecf.jar
[2022-05-11 08:55:53 - demo] Dx processing archive R:\Workspace\androidx-annotation-experimental\libs\androidx-annotation-experimental.jar...
[2022-05-11 08:55:53 - demo] Dx processing META-INF/androidx.annotation_annotation-experimental.version...
[2022-05-11 08:55:53 - demo] Dx processing META-INF/annotation-experimental_release.kotlin_module...
[2022-05-11 08:55:53 - demo] Dx processing androidx/annotation/OptIn.class...
[2022-05-11 08:55:53 - demo] Dx
PARSE ERROR:
[2022-05-11 08:55:53 - demo] Dx unsupported class file version 52.0
...while parsing androidx/annotation/OptIn.class
[2022-05-11 08:55:53 - demo] Dx 1 error; aborting
[2022-05-11 08:55:53 - demo] Conversion to Dalvik format failed with error 1
 

Looking at DexWrapper.java (Google ADT Plugin) it calls classes from android-sdk\build-tools\25.0.3\lib\dx.jar through reflection. 

public final class DexWrapper {

private final static String DEX_MAIN = "com.android.dx.command.dexer.Main"; //$NON-NLS-1$
private final static String DEX_CONSOLE = "com.android.dx.command.DxConsole"; //$NON-NLS-1$
private final static String DEX_ARGS = "com.android.dx.command.dexer.Main$Arguments"; //$NON-NLS-1$
...
public synchronized IStatus loadDex(String osFilepath) {
...
// get the classes.
Class<?> mainClass = loader.loadClass(DEX_MAIN);
Class<?> consoleClass = loader.loadClass(DEX_CONSOLE);
Class<?> argClass = loader.loadClass(DEX_ARGS);
...
// now get the fields/methods we need
mRunMethod = mainClass.getMethod(MAIN_RUN, argClass);

mArgConstructor = argClass.getConstructor();
mArgOutName = argClass.getField("outName"); //$NON-NLS-1$
mArgJarOutput = argClass.getField("jarOutput"); //$NON-NLS-1$
mArgFileNames = argClass.getField("fileNames"); //$NON-NLS-1$
mArgVerbose = argClass.getField("verbose"); //$NON-NLS-1$
mArgForceJumbo = argClass.getField("forceJumbo"); //$NON-NLS-1$

mConsoleOut = consoleClass.getField("out"); //$NON-NLS-1$
mConsoleErr = consoleClass.getField("err"); //$NON-NLS-1$

That dx.jar is an old version of Google Dex library (compiled 3 Apr 2017, version 1.12 if you decompile dx.jar\com\android\dx\Version.class) which didn't support Java 1.8 compiled classes back then. The support was introduced in 21 Feb 2017 but wasn't included in that release back then:

Commit: Allow version 52.0 class files (21 Feb 2017)

-   private static final int CLASS_FILE_MAX_MAJOR_VERSION = 51;
+ private static final int CLASS_FILE_MAX_MAJOR_VERSION = 52;

/**
* Does the actual parsing.
*/
private void parse0() {
...
if (!isGoodVersion(getMinorVersion0(), getMajorVersion0())) {
throw new ParseException("unsupported class file version " +
getMajorVersion0() + "." +
getMinorVersion0());
}

Since 25.0.3 is the last version of Android SDK Build Tools to work with Google ADT plugin for Eclipse in terms of having libraries and structure in a way that the plugin knows and understands, we update dx.jar in-place with a newer version that does support Java 1.8 binaries. Now this will not solve all the problems with newer Java 1.8 language constructs, but at least will give us a try at using newer Android library, maybe there have parts that we need and don't use newer language features.

Google DEX library sources are available on GitHub at aosp-mirror/platform_dalvik/dx/ and did gain support for version 52 class files, so we can in theory just compile it and drop it in. Unfortunately as support for Eclipse was dropped around 2017 some classes needed by Google ADT plugin (e.g. DxConsole) were shed with this commit: Make dx code re-entrant. Remove static state, clear biggest caches after running.

To reintroduce some of the support for the Google ADT plugin we forked the project on GitHub ( dandar3/platform_dalvik) and made some small changes to bring back DxConsole which is called from ADT plugin through reflection to supply stdout and stderr streams.
https://github.com/dandar3/platform_dalvik/commit/64e9c9b6dbb5606d2d61d0c512f3f7cc80b6788f    

You can clone and build the project yourself or download the JAR from the Release tab and place into your android-sdk\build-tools\xxx\lib

git clone https://github.com/dandar3/platform_dalvik.git
mvn clean package copy "target\dx-1.16-ADT.jar" "%ANDROID_HOME%\build-tools\25.0.3\lib\dx.jar*" 

Simply rebuild your project in Eclipse, it should work now.

Sunday, June 7, 2020

Android 8.1 Oreo on Nexus 7 2012 WiFi

Thanks to ud4, LineageOS team, TeamWin and everyone else that made this build possible.
  1. Backup / transfer personal data (texts, photos, videos, apps, etc)

  2. Read [ROM][grouper] [8.1.0] [UNOFFICIAL] LineageOS 15.1 [2020/05/22]
    • download lineage-15.1-20200522-UNOFFICIAL-grouper.zip (270 MB)
    • download MindTheGapps-8.1.0-arm-20180808-grouper.zip (53 MB)

  3. Download Android SDK / platform-tools

  4. Install TWRP (Team Win Recovery Project) for Nexus 7 2012 Wifi
    (twrp-3.3.1-0-grouper.img, 9.6 MB)

    Follow Fastboot Install Method (No Root Required) section.

  5.  Boot into recovery mode (TWRP) with:
    adb reboot-bootloader
    Use Volume Up or Down keys to select "Recovery Mode", then press "Power".

  6. (Recommended) In TWRP, choose Wipe > Advanced Wide > Change File System for cache and  Data from EXT4 to F2FS


  7. Back to TWRP main screen > Advanced > ADB Sideload > Swipe to Start Sideload


  8. Sideload new ROM from your PC:
    adb sideload lineage-15.1-20200522-UNOFFICIAL-grouper.zip

  9. Sideload GApps ROM from your PC:
    adb sideload MindTheGapps-8.1.0-arm-20180808-grouper.zip

  10. Reboot system




Friday, April 3, 2020

Android emulator with Windows Hypervisor Platform (WHPX)

You can run the Android emulator with Windows Hypervisory Platform (WHPX) starting with Windows 10 April 2018 Update (build 1803).

Check whether you have support for Windows WHPX by going to Control Panel > Programs and Features (appwiz.cpl) > Turn Windows features on and off (left):


If so, you have to uninstall Intel HAXM that you must likely used before for hardware acceleration and go ahead with Windows WHPX.

You can see all the details on Android's Configure hardware acceleration for the Android Emulator page > Configure VM acceleration on Windows.

You can run the AVD from command line to see what it uses:

> ANDROID-SDK\emulator\emulator.exe -list-avds
...

> ANDROID-SDK\emulator\emulator.exe -avd <avd_name>
...
Windows Hypervisor Platform accelerator is operational
...

~~~

Resources:


Friday, December 27, 2019

Eclipse Subversive (SVN) plugin installation

A tutorial on how to install Subversive SVN plugin + connectors for those who still use SVN as a source repository for their projects or used to easily pull into your project the Google AAR libraries from GitHub.

  1. Use your exiting Eclipse installation or download and extract the latest version available.
    Eclipse IDE for Java Developers 2019-12
    https://www.eclipse.org/downloads/packages/

  2. Go to Help > Install New Software
    Click Add... button a add a new Subversive repository pointing to
    http://download.eclipse.org/technology/subversive/4.0/update-site/


    Select at least the Subversive SVN Team Provider entry, continue de installation with the Next button, accept the license and Finish the installation.


    Restart now when prompted, to apply the software updates.

  3. Once restararted, go to Windows > Preferences > Team > SVN and select the SVN Connector tab.


    SVN Connector dropdown is empty so let's click the Get Connectors... button to download a connector.

    You can choose between the SVN Kit pure Java connector (SVN 1.8 compatible) and Native JavaHL system binary connectors (SVN 1.8 and 1.9 compatible). I for one prefer the first one as it - read this thread if you want to better understand the differences. https://stackoverflow.com/a/7703748/308836


    Finish the installation following the software updates dialogs presented, accepting the license and choose to Install Anyway if presented wih a dialog telling you the software was not signed.


    Restart now when prompted, to apply the software updates.
* * *

And that's it, you can now pull projects down from SVN using File > Import... > SVN > Projects from SVN




Sunday, December 8, 2019

Eclipse Android Manifest merger

The Android manifest merger is available starting with SDK Tools, Revision 20 (June 2012) and it merges your application AndroidManifest.xml with the AndroidManifest.xml's defined in the libraries added to your application.
General notes:
  • Build system
    • Added automatic merging of library project manifest files into the including project's manifest. Enable this feature with the manifestmerger.enabled property.

Also checkout the Google I/O 2012 - What's New in Android Developers' Tools starting at 48:59




Here is an example with dandar3/android-google-play-services-ads 18.3.0 library added to your application.

1. Your application.properties:
...
target=android-28
manifestmerger.enabled=true
android.library.reference.1=../google-play-services-ads

2. Your AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    package="com.example.googleplayservices.ads"
    android:versioncode="1"
    android:versionname="1.0">

    <uses-sdk
        android:minsdkversion="15"
        android:targetsdkversion="29">

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">
    <uses-permission android:name="android.permission.INTERNET">

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:label="@string/app_name"
            android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713" />

    </application>   

</manifest>

3. Check out the resulting bin\AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.example.googleplayservices.ads">

    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="29"/>

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <application android:allowBackup="false" android:icon="@drawable/ic_launcher" android:label="@string/app_name">
        <activity android:label="@string/app_name" android:name="com.example.googleplayservices.ads.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
        <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-3940256099942544~3347511713"/>

        <!-- Include the AdActivity and InAppPurchaseActivity configChanges and themes. -->
        <activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:exported="false" android:name="com.google.android.gms.ads.AdActivity" android:theme="@android:style/Theme.Translucent"/>

        <provider android:authorities="com.example.googleplayservicesads.mobileadsinitprovider" android:exported="false" android:initOrder="100" android:name="com.google.android.gms.ads.MobileAdsInitProvider"/>
        <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>

    </application>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>    

</manifest>

Tuesday, September 17, 2019

ADB.exe crashing 0xc000005 on winusb.dll

An issue I've had on my work laptop with adb.exe crashing with 0xc000005 for last couple of months, I finally managed to fix it today after several attempts in various ways.


Monitoring the process with Process Monitor would reveal that is crashes after working with WINUSB.dll (ignore the highlight in blue, that was on the first attempt checking, the file should not be there)


SFC scan shows no problems with the file.
sfc /SCANFILE=C:\Windows\SysWOW64\winusb.dll

Trying the same Android SDK installation in the Windows Sandbox VM shows it working correctly, so it must be something on my physical system. The winusb.dll files on both systems show the same version, although on copying to the phyical system in te mporary location and comparing with FC /B clearly shows differences.

Now with the new version of SysWow64\winusb.dll at hand, I would try to replace the original on the physical system without success as it is owned and protected by Trusted Installer service.

Searching the web for a tool that would allow to run a process (e.g. cmd.exe or explorer.exe) as TrustedInstaller user found ExecTI from WinAero.


This would allow me to rename the old file and copy the new one in from the clean Sandbox image.

cd /D %WINDIR%\SysWow64
rename winusb.dll winusb.dll.BROKEN
copy WHERE_YOU_COPIED_IT_FROM_SANDBOX\winusb.dll winusb.dll

Running ADB again would show it working succesfully now!

adb --version
Android Debug Bridge version 1.0.41
Version 29.0.4-5871666
Installed as D:\Program Files\Android\android-sdk\platform-tools\adb.exe

Friday, May 18, 2018

Mounting OSFMount RAM drive on boot

Updated: 16 Apr 2020

I have used a number of RAM drives over time and more in the recent years with the increase in amount of RAM available to store user temporary files (autoclean on power down) and even projects build output directories (try and reduce some build times).

PassMark OSFMount might still be missing some features compared to other available RAM drive software out there, but it is free and it has received a number of improvements lately.

Install software

Download OSFMount (v3.0.1005, 29 Jul 2019 at the time of writing) and follow the installation instructions, nothing special there.

Create automount script

The script will mount the drive if the letter is available and it uses its internal format command which can only format FAT32 at the moment. Adjust the settings to fit depending on your needs and available free RAM (check with Task Manager > Performance > Memory). Save in a system (e.g. "%WINDIR%\Create RAM Drive + TEMP directory.cmd") or user location.
@ECHO OFF
SET RAMDISK_DRIVE=R:
SET RAMDISK_SIZE=1G
SET RAMDISK_LABEL=RAM Disk
IF NOT EXIST "%RAMDISK_DRIVE%" (
  "%PROGRAMFILES%\OSFMount\OSFMount.com" -a -t vm -s %RAMDISK_SIZE% -o format:fat32:"%RAMDISK_LABEL%" -m "%RAMDISK_DRIVE%
  MKDIR "%RAMDISK_DRIVE%\TEMP"
)
If you test run it in an elevated Command Prompt it should output like below:
"%WINDIR%\Create RAM Drive + TEMP directory.cmd"
Creating device...
Created device 0: R: -> VM image
Formatting drive with volume label RAM Disk
Notifying applications...
Done.


Task Scheduler

Create a scheduled task in Task Scheduler (taskschd.msc),  the important parts are to run At system startup and to Run whether user is logged on or not.




Finishing notes

Reboot and confirm RAM drive is there on startup.



IMPORTANT NOTE:

If you intend to change your user TEMP and TMP environment variables to point to R:\TEMP with a small RAM drive you can run into all sorts of weird issues when installing large applications or with anything that takes large amounts of temporary disk space for operating like Android sdkmanager update or anything like that.

If you still want to go this way cause you think you know what you're doing, any time something weird happens like that happens I would remember to change your TEMP and TMP environment variables back to default %USERPROFILE%\AppData\Local\Temp, logoff and try the operation again.

I have never considered changing system's TEMP or TMP environment variables, just the user ones.

Tuesday, April 17, 2018

Android SDK for development with Eclipse ADT

If you are still using Eclipse ADT for Android development, this is a tutorial to help you with installing the latest possible Android SDK / Tools that would work with last Eclipse ADT plugin.

  1. Eclipse IDE for Java Developers 4.7.3a
    http://www.eclipse.org/downloads/packages/eclipse-ide-java-developers/oxygen3a
  2. Eclipse ADT plugin - 23.0.7.2120684 (Aug 2015)
    https://dl-ssl.google.com/android/eclipse/
  3. Java JDK 1.8.0_172
    http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
Now onwards to Android SDK & Tools.

Standard choice 

  1. SDK Tools 25.2.5 (Jan 2017)

    Extract into your chosen location e.g. android-sdk (note: do not extract on top of an existing installation, you can have as many Android SDK installations you want - create a new location or backup the old and remove / rename).
    Open a command line / shell and test by calling sdkmanager:
    tools\bin\sdkmanager --list | more
    
  2. Build Tools 25.0.3 (Apr 2017)

    tools\bin\sdkmanager "build-tools;25.0.3"
    Accept? (y/N): y
    
  3. Platform Tools 28.0.0 (May 2018)

    tools\bin\sdkmanager "platform-tools"
    Accept? (y/N): y 
  4. Platform(s) and sources

  5. tools\bin\sdkmanager "platforms;android-25"
    tools\bin\sdkmanager "sources;android-25"
    
    tools\bin\sdkmanager "platforms;android-27"
    tools\bin\sdkmanager "sources;android-27"
  6. Emulator 27.2.9 (May 2018)

  7. tools\bin\sdkmanager "emulator"
    Accept? (y/N): y
    
  8. Emulator images

    Downloading the image with sdkmanager may produce a 'broken' unusable image. Dowload using the the graphical version of Android SDK Manager. Additionally, API 27 images did not seem to work for me (emulator image stuck at boot with a blank screen). Recommending to try the API 25 images (or whichever versions you need).
    tools\android

  9. Check installed components

    tools\bin\sdkmanager --list | more
    
    Installed packages:
      Path                              | Version | Description                       | Location
      -------                           | ------- | -------                           | -------
      build-tools;25.0.3                | 25.0.3  | Android SDK Build-Tools 25.0.3    | build-tools\25.0.3\
      emulator                          | 27.2.9  | Android Emulator                  | emulator\
      patcher;v4                        | 1       | SDK Patch Applier v4              | patcher\v4\
      platform-tools                    | 28.0.0  | Android SDK Platform-Tools        | platform-tools\
      platforms;android-25              | 3       | Android SDK Platform 25           | platforms\android-25\
      platforms;android-27              | 1       | Android SDK Platform 27           | platforms\android-27\
      sources;android-25                | 1       | Sources for Android 25            | sources\android-25\
      sources;android-27                | 1       | Sources for Android 27            | sources\android-27\
      system-images;a...s_playstore;x86 | 9       | Google Play Intel x86 Atom Sys... | system-images\a..._playstore\x86\
      tools                             | 25.2.5  | Android SDK Tools 25.2.5          | tools\
  10. Intel HAXM 7.2.0 (May 2018)


    Read installation guide, download & install from:
    https://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager-intel-haxm

  11. Start Eclipse

    To be detailed
  12. Create AVD

    To be detailed


     
Publishing early as a draft for my friend Enzo :-) to be continued tomorrow.

Tuesday, January 2, 2018

AppCompat runtime error: "android.content.res.Resources$NotFoundException: File res/drawable/abc_vector_test.xml from drawable resource ID #0x7f020052"

Developing an Android app with the latest Support Library versions you may encounter this crash at startup on devices running Android < 5.0 (API 21):
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.googleplayservicesdemo/com.example.googleplayservicesdemo.MainActivity}: android.content.res.Resources$NotFoundException: File res/drawable/abc_vector_test.xml from drawable resource ID #0x7f020052
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
       at android.app.ActivityThread.access$600(ActivityThread.java:141)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:5041)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
       at dalvik.system.NativeStart.main(Native Method)
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/abc_vector_test.xml from drawable resource ID #0x7f020052
       at android.content.res.Resources.loadDrawable(Resources.java:1953)
       at android.content.res.Resources.getDrawable(Resources.java:660)
       at android.support.v7.widget.VectorEnabledTintResources.superGetDrawable(VectorEnabledTintResources.java:74)
       at android.support.v7.widget.AppCompatDrawableManager.onDrawableLoadedFromResources(AppCompatDrawableManager.java:435)
       at android.support.v7.widget.VectorEnabledTintResources.getDrawable(VectorEnabledTintResources.java:67)
       at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:353)
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:200)
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:188)
       at android.support.v7.widget.AppCompatDrawableManager.checkVectorDrawableSetup(AppCompatDrawableManager.java:755)
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:193)
       at android.support.v7.widget.TintTypedArray.getDrawableIfKnown(TintTypedArray.java:87)
       at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:128)
       at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:149)
       at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:29)
       at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:54)
       at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:202)
       at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:183)
       at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519)
       at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:70)
       at com.example.googleplayservicesdemo.MainActivity.onCreate(MainActivity.java:19)
       at android.app.Activity.performCreate(Activity.java:5104)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
       ... 11 more
Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #17: invalid drawable tag vector
       at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:881)
       at android.graphics.drawable.Drawable.createFromXml(Drawable.java:822)
       at android.content.res.Resources.loadDrawable(Resources.java:1950)
       ... 33 more
Force finishing activity com.example.googleplayservicesdemo/.MainActivity

Cause

Android Developers documentation (Vector Drawables Backward Compatibility Solution) mentions having to add --no-version-vectors AAPT parameter for older versions of Gradle plugin.

Running android-sdk/build-tools/xx.y.z/aapt with no parameters tells us more about the parameter:
   --no-version-vectors
       Do not automatically generate versioned copies of vector XML resources.
If we look at the AppCompat library it contains only one res/drawable/abc_vector_test.xml, but if you dissamble your APK with Apktool (apktool d your.apk) you will notice that during preparing and packaging the Android tools have created two versions from the original: res/drawable/abc_vector_test.xml and res/drawable-v21/abc_vector_test.xml.

Eclipse Andmore

Eclipse Andmore brought support for --no-version-vectors with version 0.5.1 (bug 509663)
  1. Go to your app project > Properties
  2. Check the '--no-version-vectors' option
  3. Project > Clean

Eclipse ADT

Eclipse ADT plugin is no longer supported by Google, but if you are still using it and you haven't migrated to Eclipse Andmore or Android Studio yet there is a solution that involves replacing aapt with a wrapper tool that will add --no-version-vectors when called with package option.

That is because if you enable verbose (Preferences > Android > Build > Build output = Verbose) the path and name of aapt tool is pretty much hardcoded so for this to work we will need to rename the original and replace it with this wrapper program I wrote for this.

  1. Download the latest from Github dandar3/android-aapt-wrapper releases
  2. Go to android-sdk\build-tools\xx.y.z\
  3. Rename aapt.exe to aapt-original.exe (Windows) and aapt to aapt-original (Linux) 
  4. Save aapt-wrapper.exe as aapt.exe (Windows) and aapt-wrapper as aapt (Linux) 
  5. Verify the pass through by running aapt - you should see the wrapper info followed by the real aapt output:
    Android Asset Packaging Tool - Wrapper
    Version 1.0 (31 Dec 2017)
    https://github.com/dandar3/android-aapt-wrapper
    
    Command:
      aapt-original.exe
    
    Android Asset Packaging Tool
    
    Usage:
     aapt l[ist] [-v] [-a] file.{zip,jar,apk}
       List contents of Zip-compatible archive.
    
     aapt d[ump] [--values] [--include-meta-data] WHAT file.{apk} [asset [asset ...]]
       strings          Print the contents of the resource table string pool in the APK.
    ... 
  6. Project > Clean

Saturday, December 30, 2017

How to update ProGuard for Android SDK

If still using Eclipse for Android app development and targeting newer Android SDK versions you may find ProGuard failing with this error message:
Can't process class [junit/runner/Version.class] (Unsupported class version number [52.0] (maximum 51.0, Java 1.7)) 
Proguard returned with error code 1. See console
Proguard Error 1 
Output: 
java.io.IOException: Can't read [U:\Android\android-sdk\platforms\android-27\android.jar] (Can't process class [junit/runner/Version.class] (Unsupported class version number [52.0] (maximum 51.0, Java 1.7))) 
 at proguard.InputReader.readInput(InputReader.java:230) 
 at proguard.InputReader.readInput(InputReader.java:200) 
 at proguard.InputReader.readInput(InputReader.java:178) 
 at proguard.InputReader.execute(InputReader.java:100) 
 at proguard.ProGuard.readInput(ProGuard.java:196) 
 at proguard.ProGuard.execute(ProGuard.java:78) 
 at proguard.ProGuard.main(ProGuard.java:492) 
Caused by: java.io.IOException: Can't process class [junit/runner/Version.class] (Unsupported class version number [52.0] (maximum 51.0, Java 1.7)) 
 at proguard.io.ClassReader.read(ClassReader.java:112) 
 at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:87) 
 at proguard.io.JarReader.read(JarReader.java:65) 
 at proguard.io.DirectoryPump.readFiles(DirectoryPump.java:65) 
 at proguard.io.DirectoryPump.pumpDataEntries(DirectoryPump.java:53) 
 at proguard.InputReader.readInput(InputReader.java:226) 
 ... 6 more 
Caused by: java.lang.UnsupportedOperationException: Unsupported class version number [52.0] (maximum 51.0, Java 1.7) 
 at proguard.classfile.util.ClassUtil.checkVersionNumbers(ClassUtil.java:140) 
 at proguard.classfile.io.LibraryClassReader.visitLibraryClass(LibraryClassReader.java:89) 
 at proguard.classfile.LibraryClass.accept(LibraryClass.java:301) 
 at proguard.io.ClassReader.read(ClassReader.java:86) 
 ... 11 more 

Cause

Newer versions of Android platform are compiled as Java 8 binary and ProGuard 4.7 coming with Android SDK Tools doesn't support it (last updated with SDK Tools Revision 17, March 2012).
> cd \android-sdk\tools\proguard\bin
> proguard
ProGuard, version 4.7
Usage: java proguard.ProGuard [options ...]

Solution

Java 8 support is available with Proguard 5.x onwards, so we will update to the latest version available, in my case 5.3.3 from Apr 2017.
  1. Move / rename the old version:
    rename \android-sdk\tools\proguard\ proguard.old
  2. Download the zip file from SourceForce
     
  3. Extract the contents into \android-sdk\tools\ renaming the new folder to proguard
    rename \android-sdk\tools\proguard5.3.3\ proguard
  4. Check the new version:
    > cd \android-sdk\tools\proguard\bin\
    > proguard
    ProGuard, version 5.3.3
    Usage: java proguard.ProGuard [options ...]
  5. Copy the Android configuration files over:
    > cd \android-sdk\tools\
    > copy proguard.old\proguard-*.txt proguard\
    proguard.old\proguard-android-optimize.txt
    proguard.old\proguard-android.txt
    proguard.old\proguard-project.txt
            3 file(s) copied.
Exporting the APK package again should work now.

Monday, December 11, 2017

Fix: Wireless Display "Your display couldn't connect"

 You may find when trying to project to an wireless display Windows will fail with the following error message, even though other similar computers on your network can project just fine:

    Something went wrong.
    Your display couldn't connect.



Intel ProSet/Wireless Software > Modify > Wireless Software Extensions





Windows Defender Security Center > Firewall & network protection > Restore firewalls to default





Try again projecting and confirm it is working fine now.


Sunday, November 19, 2017

Inateck FE2010 USB 3.0 Portable 2.5" HDD Enclosure


Inatek FE2010 HDD Enclosure  (11.99 GBP on Amazon.co.uk):
  • USB 3.0
  • UASP transfer protocol
  • JMS578 chipset
  • supports 2.5" SATA-I, II, III HDDs and SSDs.

Tested with:

1. Internal SATA III



 

2. Inatek FE2010 - USB 3.0 port




3. Inatek FE2010 - USB 2.0 port



4. Kingston SNA-DC/U - USB 2.0 port