New watchface for the Amazfit watch

Search This thread

turronet

Senior Member
Sep 5, 2012
58
11
hi all, here are reasonably easy instructions for all the process via OSX or Linux command line.
This requires that android sdk (21) and jdk are already installed.

Tools:
  1. wget http://repository-dex2jar.forge.clo...ooglecode/d2j/dex-tools/2.0/dex-tools-2.0.zip (for d2j-dex2jar.sh)
  2. git clone https://github.com/testwhat/SmaliEx (for oat2dex.jar)

Build (with amazfit connected via usb):
  1. adb pull /system/app/HuamiWatchFaces/mips/HuamiWatchFaces.odex
  2. git clone https://github.com/manuel-alvarez-alvarez/malvarez-watchface
  3. java -jar oat2dex.jar -a 22 odex HuamiWatchFaces.odex
  4. d2j-dex2jar.sh HuamiWatchFaces.dex
  5. cd malvarez-watchface
  6. mkdir app/libs
  7. cp ../HuamiWatchFaces-dex2jar.jar app/libs/
  8. ./gradlew app:clean app:build
  9. adb install app/build/outputs/apk/app-debug.apk

This is HUGE work by Manuel. thanks so much!!

Hello,

I'm struggling trying to run this apk, build is successful, the problem is that I get force close any time.

from logcat I get

Code:
09-11 23:16:39.974 19298-19298/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: es.malvarez.mywatchfaces, PID: 19298
                                                   java.lang.VerifyError: bad dex opcode
                                                       at com.huami.watch.watchface.util.Util.<clinit>(Unknown Source)
                                                       at com.huami.watch.watchface.AbstractWatchFace.onCreate(Unknown Source)
                                                       at android.app.ActivityThread.handleCreateService(ActivityThread.java:2761)
                                                       at android.app.ActivityThread.access$1800(ActivityThread.java:151)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1386)
                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                       at android.os.Looper.loop(Looper.java:135)
                                                       at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

It should be something related to deodexing process, the only strange thing is the output of dex2jar:

Code:
[email protected]:~/amazfit/Apps/sandbox/dex2jar-2.0$ ./d2j-dex2jar.sh --force HuamiWatchFaces.dex
dex2jar HuamiWatchFaces.dex -> ./HuamiWatchFaces-dex2jar.jar
GLITCH: zero-width instruction at Landroid/support/v4/media/MediaMetadataCompat;.<clinit>()V, @0x0026, op=0xe9
GLITCH: zero-width instruction at Lcom/huami/watch/watchface/DigitalSport4WatchFace$Engine;.onPrepareResources(Landroid/content/res/Resources;)V, @0x001a, op=0xe8
GLITCH: zero-width instruction at Lcom/huami/watch/watchface/DigitalWatchFaceSportEighteenSlpt;.createClockLayout()Lcom/ingenic/iwds/slpt/view/core/SlptLayout;, @0x004e, op=0xe3
GLITCH: zero-width instruction at Lcom/huami/watch/watchface/DigitalWatchFaceSportSix$Engine;.onPrepareResources(Landroid/content/res/Resources;)V, @0x0012, op=0xe9
GLITCH: zero-width instruction at Lcom/huami/watch/watchface/DigitalWatchFaceSportTwo$Engine;.onPrepareResources(Landroid/content/res/Resources;)V, @0x0016, op=0xe9
GLITCH: zero-width instruction at Lcom/huami/watch/watchface/util/SolarTermsUtil;.<init>(Landroid/content/res/Resources;)V, @0x001a, op=0xe6
GLITCH: zero-width instruction at Lcom/huami/watch/watchface/util/Util;.<clinit>()V, @0x005a, op=0xe9
GLITCH: zero-width instruction at Lcom/ingenic/iwds/HardwareList;.<clinit>()V, @0x01ec, op=0xe9
GLITCH: zero-width instruction at Lcom/ingenic/iwds/HardwareList;.<clinit>()V, @0x016a, op=0xe9
GLITCH: zero-width instruction at Lcom/ingenic/iwds/HardwareList;.<clinit>()V, @0x01cc, op=0xe9
GLITCH: zero-width instruction at Lcom/ingenic/iwds/HardwareList;.<clinit>()V, @0x0070, op=0xe9

Any suggestion?
 

drbourbon

Member
Mar 6, 2013
40
71
Trento
Hello,

I'm struggling trying to run this apk, build is successful, the problem is that I get force close any time.

It should be something related to deodexing process, the only strange thing is the output of dex2jar [...]

Any suggestion?

I've just tried with last image (from 1.2.37): I confirm the issue :(

Have you tried with an older HuamiWatchFaces.odex ?

(the one from 1.2.37 doesn't even compile: I had to patch es.malvarez.mywatchfaces.AbstractWatchFaceSlpt (trivial patch, anyway))
 

turronet

Senior Member
Sep 5, 2012
58
11
I've just tried with last image (from 1.2.37): I confirm the issue :(

Have you tried with an older HuamiWatchFaces.odex ?

(the one from 1.2.37 doesn't even compile: I had to patch es.malvarez.mywatchfaces.AbstractWatchFaceSlpt (trivial patch, anyway))

Thanks for answer
Got the same on 1.3.0 and 1.2.36
That's why I thought something wrong in deodexing
 

michalz

New member
Oct 18, 2008
2
0
Hello,

Where can I get HuamiWatchFaces.jar
When converting d2j-dex2jar.sh does not receive the classes.dex file

Ok i found answer... Sory for post ;/
 
Last edited:

thmrsl

New member
Nov 14, 2017
1
0
Hi 'yall,

did anyone succeed with getting this or another custom android app to run on the newer firmware versions by now?

I have the latest firmware (1.3.4f), followed the instuctions and I get the same "bad dex opcode" error turronet described.

EDIT: building the app works fine, but running it creates this error noticeable via logcat. So same as turronet...

Cheers
Thomas
 
Last edited:

michalz

New member
Oct 18, 2008
2
0
I have some problem .....


Error:Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'.
> java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex

In Android studio 3.0

Any suggestions ?
 

kingofdevils

Senior Member
Feb 26, 2010
51
7
When I try to complile this with Android studio return me an error:

Error:(30, 5) error: method does not override or implement a method from a supertype
C:\malvarez-watchface-master\app\src\main\java\es\malvarez\mywatchfaces\AbstractWatchFaceSlpt.java

Any idea?

This is the original code:

Code:
package es.malvarez.mywatchfaces;

import android.util.Log;

import com.huami.watch.watchface.AbstractSlptClock;
import com.ingenic.iwds.slpt.view.core.SlptAbsoluteLayout;
import com.ingenic.iwds.slpt.view.core.SlptLayout;
import com.ingenic.iwds.slpt.view.core.SlptViewComponent;

import java.util.Arrays;
import java.util.LinkedList;

import es.malvarez.mywatchfaces.widget.ClockWidget;
import es.malvarez.mywatchfaces.widget.Widget;

/**
 * Splt version of
 */

public abstract class AbstractWatchFaceSlpt extends AbstractSlptClock {

    final ClockWidget clock;
    final LinkedList<Widget> widgets = new LinkedList<>();

    protected AbstractWatchFaceSlpt(final ClockWidget clock, final Widget... widgets) {
        this.clock = clock;
        this.widgets.addAll(Arrays.asList(widgets));
    }

    @Override
    protected final SlptLayout createClockLayout() {
        SlptAbsoluteLayout result = new SlptAbsoluteLayout();
        for (SlptViewComponent component : clock.buildSlptViewComponent(this)) {
            result.add(component);
        }
        for (Widget widget : widgets) {
            for (SlptViewComponent component : widget.buildSlptViewComponent(this)) {
                result.add(component);
            }
        }
        return result;
    }
}

Thanks in advance
 

suryateja8

New member
Feb 25, 2018
4
0
Can you please share the APK file for the watch face ?

Dear Pmos69,

Can you please share the APK file for the watch face you have compiled.

Thanks
Surya


I imported the project into Android Studio and downloaded HuamiWatchFaces.apk from the watch with adb.
But I'm having trouble with the step "Add the HuamiWatchFaces application as a jar dependency into the libs folder".
No matter what I do I always get "error: package com.huami.watch.watchface does not exist".

(I simply put the apk in ./malvarez-watchface-master\app\src\main\java\es\malvarez\mywatchfaces\libs but I doubt that would be correct)

It's been a long time since I compiled something for Android, so I must be making something really dumb.
Can you help?

EDIT: Managed to compile it. Although I had to strugle to deodex HuamiWatchFaces and then turn it into a jar. I don't think I did it correctly, but it worked.
Very nice. Thanks Manuel.
 

LOTG

Senior Member
Oct 24, 2007
105
19
Maastricht
So I have been looking in to this, I don't have a pace but a Stratos and used the APK from this. Reading through the issues I think the problems with the latest firmware are the same.
My laptop battery died so this is of the top of my head.

createClockLayout has been split in to two separate methods: createClockLayoutWc26 (something with a 6 at least) and createClockLayoutW8 (yes no C in the 8 one) (I might have switched the C an W but I don't think it matters for the explanation).
I'm not sure what the difference is, but my first guess would be low power for the 8 one.

Then they changed the Utils API that was used to get bytes from images, this is gone. I dug a little through the official watchfaces and found they are using a SimpleFile call that takes a context instead of a service. Seems like an easy fix as we can get the context from the service. A better way would be to use the config method (also new and has to be implemented, easy to do) but I'm just looking to get it working.

Now the one thing I could not figure out was the digits. They seem to have ditched the option to use text for linear layouts, all the official ones seem to use images for digits. It is still possible to use text but only for widget types it seems. It's not possible to use a widget layout as there is no way to set the hour thing (forgot the name) on it.
I'm guessing it would be easy to take a lot of it from the Pace watchface (time travel?) As it looks mostly the same on the digit front but as I have no Pace I can't copy the APK. The other way would be to use the images.

I'll look into it some more tomorrow (when I have my laptop charger). I'm not entirely convinced my patch jobs will work but I do thing I can at least modify an existing design to do something similar.

Edit:
So, laptop is plugged in and I can make the whole a bit more accurate.

- createClockLayout has been split in to createClockLayout26WC and createClockLayout8C. I've been digging through the assets of the official watchfaces and 26WC is active and 8C is passive display.
- Util.assetToBytes is gone, it seems to have been replaced with SimpleFile.readFileFromAssets. Instead of passing a service I passed it service.getApplicationContext() as this is what Huami seems to do.
- initWatchFaceConfig has been added on AbstractSlptClock and has to be implemented, this is where Huami stores the context from service.getApplicationContext()
- setStringPictureArrayForAll on SlptHorizontalLayout is gone and has no replacement, at least I could not find any. I don't have the old code so I can't see how it used to work.

I'll look in to it some more later and maybe figure out how to fix the last issue and it should compile.
Then it is fingers crossed that it will work.

Edit 2:
Ok I downloaded the DrBourbon APK (has some nice fancy watchfaces, does not work on my stratos. It is quite anoying when a watchface keeps throwing errors and you are trying to get out of the error message), decompiled it and now I can see the difference.
Bottom line, there is no reason why they removed the setStringPictureArrayForAll. It should work, the none picture one has the same flow and it boils down to a SlptNumView child component. This has the option to use strings and it is still used by the power/step/etc. components.
You put an SlptHourHView component on it and this implements the SlptNumView.
Strange...

Edit 3:
Managed to work around the last error, however I have been trying to get it to build but I'm stuck with "mismatched stack depths". Great error that I can find nothing about. It seems the execution stacks have a different size but where this comes from is beyond me. Google was not my friend on this.
 
Last edited:

LOTG

Senior Member
Oct 24, 2007
105
19
Maastricht
I managed to get it working. Sort of.
full.jpg


What did I do? I figured out the error occured in the dex2jar process, as mentioned a few posts back it throws a few GLITCH: zero-width instruction errors.
The one that gave me the "mismatched stack depths" was HardwareList, so I swapped it out with a file from the DrBourbon APK. (it was about 200 bytes bigger) and then it compiled. I don't know if the other files with zero-width instructions were important for this, but it worked.

So what do I mean with sort of? Well, as you can see in the picture the backlight is turned on. As soon as it turns off and goes to passive mode it shows Everest again.
Probably something that is fixable through some of the new configuration options.

But if some one is interested, this fixes most of the errors and I think I can port some of the pace watchfaces over to Stratos.

O yeah, the way I worked around setStringPictureArrayForAll issue. I copied the method from the DrBourbon APK that still had the method, placed it in the MalvarezClock class as private and replaced the this.list with a nice nasty reflection to get the list from the layout. It works, but I'm not proud of it.

Edit:
And I've fixed it!
It is working lovely now.

What was wrong? Well I had overridden the low power (createClockLayout8C) layout a level higher again (can't remember doing it) and returned null there. So the effect is that it will then display the previously set clock. Maybe a nice (and dirty) way to set two different clocks but that was not the target here.

I think I will set up a repo with the fixed code, and a guide on how to compile your own version. I know a lot of people wan't the APK version but I don't want people from Xiaomi/Huami's legal department knocking at my door for spreading their code (because you have to include the original watchfaces code for this method). It is a bit less neat then the original method as you will need to replace the HardwareList file in the jar, unless someone can figure out a way to dex2jar it without the glitch errors.
 
Last edited:

LOTG

Senior Member
Oct 24, 2007
105
19
Maastricht
@GreatApo
That was the plan, I'll do that tomorrow.

However, while I thought I fixed the issue with the screen turning back to everest, that is still happening. It doesn't lock while connected to the PC, it just turns off the backlight.

I did manage to get the DrBourbon ones to work though (with the same issue). I really like the Fuzzy Text and Text Time ones.

Edit:
@GreatApo
I created a new thread with everything in it, let me know if you have questions or sugestions.
 
Last edited:

Top Liked Posts