Adding Google Voice Assistant back to MIUI 9

I have a XiaoMi 6 running Chinese MIUI9 (developer ROM) but installed with Google frame with the backup/restore method described on the Internet. Everything was fine except a few months ago, the Google Voice Assistant (GVA) stop working. I could use the Chinese Voice Assistant (it is quite good) but most of my contacts were written in English which cannot be recognized by the Chinese Voice Assistant.

Every time when MIUI has a new update, I tried to reinstall the GVA just to see whether the bug was fixed or not, and every time, I got the same error message.

java.lang.RuntimeException: Unable to create service java.lang.SecurityException: Failed to find provider for user 0; expected to find a valid ContentProvider for this authority

I think the main problem may be caused by some missing “partner” app. Today, I finally find the way to fix it. I installed an app named and slove the program.


Upgrade to Xiaomi Mi 6

I have been using Xiaomi 2S for a long time without upgrading. It is still usable but getting slow on task switching. I like Xiaomi because of its OS support. Up to now, my 2S still getting software upgrade every now and then.

As for my new Mi 6. The one I get is Chinese version which does not have Google Play. So, the first task I had was to try to install Google framework on the phone. After some search on the Internet, I found two ways to do so:

  1. Flash the official “global” ROM from the MIUI website ( This ROM contains the Google framework in it. However, Mi 6 is a locked phone which means I need to unlock the phone first before I can directly flash any ROM to it. There is instruction on MIUI website ( and the Internet showing to apply and perform the unlocking. After unlocking, you can flash the global ROM to gain the Google framework.
  2. The second option is using the local restore option which provided on the Internet. The idea is to restore the set of apps which form the Google framework. The backup of this set of apps is available for download from the Internet. The advantage of this approach is you do not need to unlock or root your device at all. However, if you want to root your device, you do need to unlock it first.

I tried the global ROM approach first. I found it has very good support of Google framework include the use of “ok Google” to unlock or activate voice command. However, even I used the developer version of ROM, it does not support rooting the device. This means I have to use some third-party apps for both flashing and rooting the device. Even worse, after each MIUI upgrade, I have to do the flashing and rooting again.

This brings me to try to reverse the device back to the Chinese ROM and try the restore approach for installing the Google framework. It works out fine. I can use Google Play and all other Google apps. However, the “ok google” cannot be activated in the same way as in the Global ROM. But now, I have the MIUI rooting support back!

In my opinion, if you want to root the device, the Chinese ROM together with the restore approach is a better choice.

“symbol(s) not found for architecture x86_64 error” when compiling OpenCV example program in Mac OS X 10.12

I just completed the installation of OpenCV 3 in my Mac (running OS X 10.12) after a long search of various installation methods.  However, when I tried to compile a sample C++ program, the following error was resulted:

Undefined symbols for architecture x86_64:
  "cv::imread(cv::String const&, int)", referenced from:
      _main in DisplayImage-6f69a1.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [DisplayImage] Error 1

So, once again, the search is on. After searching for the entire morning for solutions, I came across many “solution posts” that did not work!

Finally, I reached a post that mentioned “imread has been moved in the opencv_imgcodecs library.” and should “Try to add -lopencv_imgcodecs to your linker flags.” This solved my problem.

This case made me wonder how many people who posted “incorrect solution” had actually tried to replicate the error and actually solved the problem? Or did they just “think” what may be the problem and provide “guesses” about the possible solutions?

I am not saying that try ones best to provide information to the other is a bad thing. But providing too many “unproven” information in the web not only not able to help, it also makes the searching for true solution more difficult!

Using cmake-gui to Create MinGW lib for OpenCV 2.4.13

Recently, I have tried to learn how to use OpenCV. Of course, the first thing is to install OpenCV. The version I tried to install is 2.4.13. The development tools I used is MinGW g++. After download and install all the tools (including cmake), I soon found out that there is no library for MinGW g++ in the distribution. This means I need to build my own if I want to use g++. The search is on…

There is not much information I can find for my environment which is Windows 10 and using g++ as my main c++ compiler. After putting the pieces together, I eventually hit the right path, the following is my procedure for building the MinGW lib for OpenCV 2.4.13:

  1. run cmake-gui as follows:
    cmake-gui -G "MinGW Makefiles"

    Setup the location for source (in my case is D:/WinApps/opencv/sources) and the binaries (D:/WinApps/opencv/build/x86/mingw). Add the following two entries as well:

    CMAKE_CXX_COMPILER <em>path_to_g++</em>
    CMAKE_C_COMPILER <em>path_to_gcc</em>
  2. Click Configure then with the default selection of components click Generate
  3. In cmd, change directory to D:/WinApps/opencv/build/x86/mingw and execute the command
    make all

    I encountered two errors during the make process:

    • A compile error for the file window_w32.cpp where the symbols ‘BTNS_AUTOSIZE‘ and ‘BTNS_BUTTON‘ were not declared. I fixed it by change them to 16 and 0 (where I found in one of the header file of g++).
    • Another error from the files in ‘nonfree’ module, for which I just deselect the ‘BUILD_opencv_nonfree’ from cmake and reclick Generate again, then make all again. This time, it went all the way to finish without serious error.
  4. Done!

I test drive the system by creating a c++ program loadimg.cpp which I copied from here.

g++ -I"D:\WinApps\opencv\build\include" -L"D:\WinApps\opencv\build\x86\mingw\lib" loadimg.cpp -lopencv_core2413 -lopencv_highgui2413 -o loadimg

The program compiled and run!

Footer/Icon stays at the bottom of screen

I were looking for ways to fix some icons to be shown at the bottom of the screen and came across the following code. I haven’t test the code yet but it should fit my need.

html {
  position: relative;
  min-height: 100%;
body {
  margin: 0 0 100px; /* bottom = footer height */
footer {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 100px;
  width: 100%;

animateTransform for a group of objects in SVG using InkScape

I recently try to do a presentation in SVG and wanted to do some simple animation on some of the components in the presentation. First of all, I am lucky to come across the Sozi extension for Inkscape. The extension makes Inkscape able to produce presentation very similar to Prezi.

With the framework setup, now it is time to do some element animation. Immediately, I encountered a problem, I used text editor (VIM) to edit the SVG file in order to insert the animation for the elements. The problem I encountered was that when I try to animate (e.g., rotating and scaling) a grouped objects, I cannot find the center. Even I calculate the center correctly, the rotation or scaling behave strangely.

After a few try and hacking, I eventually find a way create grouped object which can be moved or scaled without effecting the animation within the group.

Step 1. Create the component so that its center is at (0, 0) (upper left-hand coiner of Inkscape paper).

Step 2. Add the necessary animation code and put the code inside the group.

Step 3. Add an outer group to the group. In this way, When the group is moved, scaled or rotated, the transformation matrix will be add on the outer most group.

<g id="outer-group">
  <g id="inner-group">
    <path ... />
    <path ... />
      attributeName="transform" type="rotate"
      values="0; 360" dur="2s"
      repeatCount="indefinite" />

The idea is that the inner group cannot have transformation matrix in it, otherwise,

Sleeping and Wake up of Perl script

I am working on a system that requires a Perl script to sleep when it is idle and wake up when new “job” arrive. After some search, the following is what I end up with:

$SIG{ALRM} = sub { print "Alarm!\n"; };
while (1) { # process loop
  if ($therearejobs) {
    # process the job
else {
  print "No job, I am going to sleep now!\n";
  $st = sleep;
  print "Ok, after $st second, I am back to work.\n";

To communicate with the about script, one can send alarm signal to the script by issue a kill command as follows:

kill -14 pid

Where -14 is the signal number of ALRM (alarm).