As mention in previously post, I installed Ubuntu on my HP ZBook. After two days used all things work just fine, but the Thunderbolt 3 Dock did not work at the beginning - the network cable, HDMI, VGA port on the dock is not detected in Ubuntu.
I spent some time to check the BIOS overall, and find out, after change BIOS -> Options -> Ports -> Thunderbolt 3 Port, from "PCIe and Display user authentication" to "PCIe and Display no secure", all Thunderbolt 3 Dock functions work in Ubuntu now. I can use my two 23' displays now.
Thursday, September 28, 2017
Saturday, September 23, 2017
Install Ubuntu with Windows UEFI dual boot
I tried to install Ubuntu with my existed Windows 7 today, and have the Ubuntu / Windows dual OS boot up. The most guides on web are out of date, special for currently most PC use UEFI as default boot configuration, there are a lot of mistakes. So I take a as-is notes for today: 2017-09-24
To install Ubuntu without wipe existed Windows with UEFI:
1. Prepare ubuntu install USB stick and empty disk space in Windows. You can search on web about this step, a lot of guides.
2. Boot up with the ubuntu install USB stick. IMPORTANT: DO NOT select "install ubuntu" in boot menu!! Select "Try ubuntu" to boot into live ubuntu (it runs on your USB stick, does not install any things) firstly, then select "Install Ubuntu" --- These two "Install Ubuntu" are different because you need boot up into ubuntu for detecting UEFI mode.
3. Select "Install ubuntu" -> "Something else", create the first partition , for 300MB size, of your empty space as a "EFI partiton"!!! You MUST have this partition.
4. Then create /boot after that EFI partition. And create /, /home, /swap as your wish.
5. Select "Install boot at" option to the EFI partition you just created!!!
6. Then continue the install process as normal.
The key point is to boot into ubuntu then do the installation, and the EFI partition. Another thing must aware is, DO NOT use "hybird display card" option in BIOS, otherwise ubuntu will show an empty desktop because pci issue.
To install Ubuntu without wipe existed Windows with UEFI:
1. Prepare ubuntu install USB stick and empty disk space in Windows. You can search on web about this step, a lot of guides.
2. Boot up with the ubuntu install USB stick. IMPORTANT: DO NOT select "install ubuntu" in boot menu!! Select "Try ubuntu" to boot into live ubuntu (it runs on your USB stick, does not install any things) firstly, then select "Install Ubuntu" --- These two "Install Ubuntu" are different because you need boot up into ubuntu for detecting UEFI mode.
3. Select "Install ubuntu" -> "Something else", create the first partition , for 300MB size, of your empty space as a "EFI partiton"!!! You MUST have this partition.
4. Then create /boot after that EFI partition. And create /, /home, /swap as your wish.
5. Select "Install boot at" option to the EFI partition you just created!!!
6. Then continue the install process as normal.
The key point is to boot into ubuntu then do the installation, and the EFI partition. Another thing must aware is, DO NOT use "hybird display card" option in BIOS, otherwise ubuntu will show an empty desktop because pci issue.
Wednesday, June 7, 2017
Thrift fails on Windows - thrift failed error: The command line is too long.
Meet a thrift compiling failure on my project on Windows 7. Using Maven in IntelliJ so I choiced maven-thrift-pluging for thrift files. For one project, the thrift failed as below:
[INFO] — maven-thrift-plugin:0.1.11:compile (thrift-sources) @ xxxxxxxxxxxxxxx —
[ERROR] thrift failed output:
[ERROR] thrift failed error: The command line is too long.
Executed the thrift --gen manually did not meet this issue, so most likely caused by how maven-thrift-plugin call the compiler. Finally I had a workaround to decrease the thrift temp file folder path to pass the build:
Below configuration changed the folder name from default "thrift-dependencies" to "td", lucky my project pass build, otherwise I think I have to move my project to a up-level folder to get a shorter path.
[INFO] — maven-thrift-plugin:0.1.11:compile (thrift-sources) @ xxxxxxxxxxxxxxx —
[ERROR] thrift failed output:
[ERROR] thrift failed error: The command line is too long.
Executed the thrift --gen manually did not meet this issue, so most likely caused by how maven-thrift-plugin call the compiler. Finally I had a workaround to decrease the thrift temp file folder path to pass the build:
Below configuration changed the folder name from default "thrift-dependencies" to "td", lucky my project pass build, otherwise I think I have to move my project to a up-level folder to get a shorter path.
<plugin> <groupId>org.apache.thrift.tools</groupId> <artifactId>maven-thrift-plugin</artifactId> <configuration> <thriftExecutable>${thrift.compiler}</thriftExecutable> <generator>${thrift.generator}</generator> <temporaryThriftFileDirectory>${project.build.directory}/td</temporaryThriftFileDirectory> </configuration></plugin>
Friday, May 5, 2017
Gradle Failed for Google Guava: transformClassesWithDexForDebug TransformException
Meet the compile issue when adding Google Guava into my Android project:
After downgrade guava to version 19 the project passed build successfully:
dependencies {
compile 'com.google.guava:guava:21.0'
}
Error:10:16:43.803 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] > com.android.build.api.transform.TransformException: com.android.ide.common.pro
cess.ProcessException: Error while executing java process with main class com.android.multidex.ClassReferenceListBuilder with arguments {xxxxxxxxxxx\build\intermediates\multi-dex\debug\componentClasses.jar xxxxxxxxx\build\intermediates\transforms\jarMerging\de
bug\jars\1\1f\combined.jar}
After downgrade guava to version 19 the project passed build successfully:
dependencies {
compile 'com.google.guava:guava:19.0'
}
Have no time to dig into the root cause yet, record here for reference.Wednesday, March 8, 2017
How to build React-Native behind proxy
Recently I tried to setup and build react-native app (mostly for Android), behind a proxy server. To pass the gradle build, need set proxy config as below:
- Edit AwesomeProject\Android\gradle.properties, add proxy config:
- systemProp.http.proxyHost=10.255.247.227
- systemProp.http.proxyPort=8080
- systemProp.https.proxyHost=10.255.247.227 systemProp.https.proxyPort=8080
Thursday, May 5, 2016
error: undefined reference to '__android_log_print' in Android Studio 2.1
Need load the android log lib in app/build.gradle:
android.ndk {
moduleName = "[the_module_name]"
ldLibs.addAll(['android', 'log'])
}
android.ndk {
moduleName = "[the_module_name]"
ldLibs.addAll(['android', 'log'])
}
Thursday, January 29, 2015
Make TextView scrollable without using ScrollView
2 steps, firstly, set scroll bar rotation in AndroidManifest.xml:
android:scrollbars="vertical"
Then, set the scrolling method for the TextView, mostly in onCreate() function:
((TextView)findViewById(R.id.textview)).setMovementMethod(ScrollingMovementMethod.getInstance());
android:scrollbars="vertical"
Then, set the scrolling method for the TextView, mostly in onCreate() function:
((TextView)findViewById(R.id.textview)).setMovementMethod(ScrollingMovementMethod.getInstance());
Parent Activity is destroyed when providing Up navigation
If providing Up navigation behavior as Android doc: http://developer.android.com/training/implementing-navigation/ancestral.html, when click the Up button on the navigation bar, the parent activity is destroyed then re-created. It is different behavior as pressing back key.
To avoid destroy parent activity, one solution is setting launch mode <singleTop> for the activity in AndroidManifest.xml:
The different between Up key and Back key is, when pressing Back key, by default, the currently activity is popup from activity stack and finished, so the previously activity shows up. When pressing Up key, the currently activity is popup from stack too, but the parent activity, which is defined in AndroidManifest.xml and maybe not the previously activity, is created to show. By default the launch mode is <standard> so the existed activity task is destroyed then re-create. To set the launch mode to <singleTop>, Android will launch the existed one instead of create a new task.
To avoid destroy parent activity, one solution is setting launch mode <singleTop> for the activity in AndroidManifest.xml:
android:launchMode="singleTop"
The different between Up key and Back key is, when pressing Back key, by default, the currently activity is popup from activity stack and finished, so the previously activity shows up. When pressing Up key, the currently activity is popup from stack too, but the parent activity, which is defined in AndroidManifest.xml and maybe not the previously activity, is created to show. By default the launch mode is <standard> so the existed activity task is destroyed then re-create. To set the launch mode to <singleTop>, Android will launch the existed one instead of create a new task.
Tuesday, October 28, 2014
Get Android Kernel log
To catch Kernel log, need a rooted Android device and adb shell worable, then use the adb logcat command:
$adb shell logcat -v time -f /dev/kmsg | cat /proc/kmsg
To write the output to a file:
$adb shell logcat -v time -f /dev/kmsg | cat /proc/kmsg > /sdcard/log.txt
Thursday, April 24, 2014
Get navigation bar (TSB bar) height
The dim value is defined as com.android.internal.R.dimen.navigation_bar_height.
final int naviHeight = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height);
final int naviHeight = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height);
Monday, April 14, 2014
How to exclude activity from recent application list on Android
To forbidden your activity in the recent application list, just define this parameter in AndroidManifest.xml for the activity:
for example:
<activity
android:name="com.test.MainActivity"
android:noHistory="true"
android:screenOrientation="portrait"
android:excludeFromRecents="true"
android:label="@string/app_name">
......
</activity>
android:excludeFromRecents="true"
for example:
<activity
android:name="com.test.MainActivity"
android:noHistory="true"
android:screenOrientation="portrait"
android:excludeFromRecents="true"
android:label="@string/app_name">
......
</activity>
Wednesday, February 26, 2014
Monitor screen ON and OFF
Has to register receiver via function registerReceiver(), so usually have to create a service for it.
public class UpdateService extends Service {
BroadcastReceiver mReceiver = new BroadcastReceiver {
private boolean screenOff;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
handleScreenAction(screenOff);
}
}
private void handleScreenAction(boolean screenOff) {
if (screenOff) {
// your code
} else {
// your code
}
}
@Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, filter);
}
@Override
public void onDestory() {
super.onDestory();
unRegisterReceiver(mReceiver);
}
public void onStart(Context context, Intent intent, int startId) {
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
public class UpdateService extends Service {
BroadcastReceiver mReceiver = new BroadcastReceiver {
private boolean screenOff;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
handleScreenAction(screenOff);
}
}
private void handleScreenAction(boolean screenOff) {
if (screenOff) {
// your code
} else {
// your code
}
}
@Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, filter);
}
@Override
public void onDestory() {
super.onDestory();
unRegisterReceiver(mReceiver);
}
public void onStart(Context context, Intent intent, int startId) {
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Tuesday, February 25, 2014
Detect headset / Bluetooth status
need this permission:
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
and code snap:
AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
if (audioManager.isWiredHeadsetOn()
|| audioManager.isBluetoothA2dpOn()
|| audioManager.isBluetoothScoOn() ) {
// headset connected
}
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
and code snap:
AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
if (audioManager.isWiredHeadsetOn()
|| audioManager.isBluetoothA2dpOn()
|| audioManager.isBluetoothScoOn() ) {
// headset connected
}
How to detect whether phone is in charging
Does not need register a broadcast receiver. Call function
registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)), and it will return anIntent with battery status immediately, because Intent.ACTION_BATTERY_CHANGED is a sticky broadcast.
Here is code snap:registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)), and it will return anIntent with battery status immediately, because Intent.ACTION_BATTERY_CHANGED is a sticky broadcast.
Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean cableCharge = plugged == BatteryManager.BATTERY_PLUGGED_USB
|| plugged == BatteryManager.BATTERY_PLUGGED_AC;
boolean wirelessCharge = plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Friday, February 21, 2014
Translate touch event coordinates to the parent
The touch event coordinates can be got in onTouch() by MotionEvent:getX() and
MotionEvent:getY(), the coordinates are based on currently view. To translate to the parent layout, just append the current view positions to them like this:
view.getLeft() + motionEvent.getX();
view.getTop() + motionEvent.getY();
Haptic feedback (vibration) on Android
Simple use View:performHapticFeedback() to play a vibration:
View view = findViewById(...)
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
Sunday, October 20, 2013
Create custom button with round corner and shadow by XML
To create a button in Android app like this:
The layout XML:
<Button
android:layout_width="match_parent"
android:layout_height="80dip"
android:background="@drawable/hi"
android:text="@string/click_button"
android:textColor="#999"
android:textSize="18dip"
android:textStyle="bold" />
The drawable file hi.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Bottom 2dp Shadow -->
<item android:bottom="11px" android:top="19px" android:left="10px" android:right="10px">
<shape android:shape="rectangle" >
<solid android:color="#ccc" />
<corners android:radius="7dp" />
</shape>
</item>
<!-- White Top color -->
<item android:bottom="15px" android:top="15px" android:left="10px" android:right="10px">
<shape android:shape="rectangle" >
<solid android:color="#FFFFFF" />
<corners android:radius="7dp" />
</shape>
</item>
</layer-list>
Wednesday, October 16, 2013
Convert hex string to color in Android
I got a hex string from resource file, looks like this "#FF00BB00". I wanna to use it as a view's background color. In Java there is a function Color.decode(String), while it is not existed on Android.
But after read the android.graphics.Color of Android quickly there is a same and useful function Color.parseColor(String), just be careful the string shall format to "#FF123456" or "#123456".
Here is the code:
imageView.setBackgroundColor(Color.parseColor("#FF00BB00"));
But after read the android.graphics.Color of Android quickly there is a same and useful function Color.parseColor(String), just be careful the string shall format to "#FF123456" or "#123456".
Here is the code:
imageView.setBackgroundColor(Color.parseColor("#FF00BB00"));
Parser XML via XmlPullParser in Android app
It's easy and simple to use XmlPullParser in Android app, the key method is next(). Call next() to go to next tag in XML, then adjust the current position by the event type. Just notice there is a TEXT event with empty value between two lines.
Here is how to parser a asset XML file:
InputStream is = getAssets().open("colors.xml");
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, null);
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_DOCUMENT) {
System.out.println("Start document");
} else if (eventType == XmlPullParser.START_TAG) {
System.out.println("Start tag " + parser.getName());
} else if (eventType == XmlPullParser.END_TAG) {
System.out.println("End tag " + parser.getName());
} else if (eventType == XmlPullParser.TEXT) {
System.out.println("Text " + parser.getText());
}
eventType = parser.next();
}
System.out.println("End document");
is.close();
Here is how to parser a asset XML file:
InputStream is = getAssets().open("colors.xml");
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, null);
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_DOCUMENT) {
System.out.println("Start document");
} else if (eventType == XmlPullParser.START_TAG) {
System.out.println("Start tag " + parser.getName());
} else if (eventType == XmlPullParser.END_TAG) {
System.out.println("End tag " + parser.getName());
} else if (eventType == XmlPullParser.TEXT) {
System.out.println("Text " + parser.getText());
}
eventType = parser.next();
}
System.out.println("End document");
is.close();
Tuesday, October 15, 2013
How to open Assets files of Android app
The key class is AssetManager, use Context:getAssets() to get the AssetManager object.
To open a file:
InputStream is = context.getAssets().open("foo");
To open a binary XML file. Be notice the XML files under assets folder will not be complied into binary file, so you have to use AssetManager.open() for them.
XMLResourceParser parser = myContext.getAssets().openXmlResourceParser("xml");
And also can list all the asset files:
String[] list = myContext.getAssets().open("sample/foo");
To open a file:
InputStream is = context.getAssets().open("foo");
To open a binary XML file. Be notice the XML files under assets folder will not be complied into binary file, so you have to use AssetManager.open() for them.
XMLResourceParser parser = myContext.getAssets().openXmlResourceParser("xml");
And also can list all the asset files:
String[] list = myContext.getAssets().open("sample/foo");
Subscribe to:
Posts (Atom)
Enable HP Zbook Thunderbolt 3 Dock on Ubuntu
As mention in previously post, I installed Ubuntu on my HP ZBook. After two days used all things work just fine, but the Thunderbolt 3 Dock ...
-
I tried to add a VideoView to a layout dynamic via code in my Android app, but the whole screen flashes when the VideoView was added first ...
-
To create a button in Android app like this: The layout XML: <Button android:layout_width="match_parent" andro...
-
As mention in previously post, I installed Ubuntu on my HP ZBook. After two days used all things work just fine, but the Thunderbolt 3 Dock ...

