2019年5月3日 星期五

Launch the other app

Reference:

https://blog.csdn.net/shaw1994/article/details/39642473
https://dotblogs.com.tw/neil/2011/08/12/33058/

Code snippet:


public void switchToApp(String packageName) {

    Intent appIntent = getPackageManager().getLaunchIntentForPackage(packageName);

    if(appIntent != null){

        startActivity(appIntent);

    }

}

2018年9月18日 星期二

Use reflection to get framework hide variable value or resource value

Code snippet:

1. Get hide constant value
public static int getHideIntConstants(String classAndPkgName, String fieldName, int defaultValue){
    int fieldValue = defaultValue;

    Class<?> c = null;
    try {
        c = Class.forName(classAndPkgName);
        Field field = c.getDeclaredField(fieldName);
        field.setAccessible(true);
        fieldValue = field.getInt(null);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (Exception e){
        e.printStackTrace();
    }
    String hesString = Integer.toHexString(fieldValue);
    Log.d(TAG, "fieldValue " + fieldName + ": " + fieldValue + " ; hex: " + hesString);
    return fieldValue;
}

2. Get hide constant value declared in inner class
public static int getTypeDisplayOverlayInt(Window window) {
    int typeDisplayOverlay = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

    Class<?> c = null;
    try {
        c = Class.forName("android.view.WindowManager");
        Class<?>[] classes = c.getDeclaredClasses();
        for(Class innerClass: classes){
            if(innerClass.getName().contains("LayoutParams")){
                Field field = innerClass.getDeclaredField("TYPE_DISPLAY_OVERLAY");
                field.setAccessible(true);
                typeDisplayOverlay = field.getInt(window.getAttributes());
                break;
            }
        }
    } catch (Exception e){
        e.printStackTrace();
    }
    return typeDisplayOverlay;
}

3. Get resource value
public static int getStatusHeight(Context context) {
    int statusBarHeight = -1;
    try {
        Class<?> clazz = Class.forName("com.android.internal.R$dimen");
        Object object = clazz.newInstance();
        int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
        statusBarHeight = context.getResources().getDimensionPixelSize(height);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return statusBarHeight;
}

4. Get SystemUI apk recource value
public static String getDateFormat(Context context) {
    PackageManager pm = context.getPackageManager();
    try {
        Resources resources = pm.getResourcesForApplication("com.android.systemui");
        int id = resources.getIdentifier("abbrev_wday_month_day_no_year", "string", "com.android.systemui");
        if (id > 0) {
            return resources.getString(id);
        } else {
            return null;
        }

    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    return null;
}

2018年5月17日 星期四

How to fix INSTALL_FAILED_TEST_ONLY error

Reference:

https://www.jianshu.com/p/8f5730cab8fc
http://www.cnblogs.com/yongfengnice/p/7814016.html
https://blog.csdn.net/chf1142152101/article/details/70738868

Solution:

1. Add the following line into gradle.properties

    ......
    android.injected.testOnly=false


2. Click Android Studio "Build -> BuildAPK(s)" to generate apk

3. Sign key
4. If gradle version is test version, revise it to release version

buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.4.0-alpha3' //版本为测试版 } }

2018年4月6日 星期五

Get height of status bar

Reference:

https://gist.github.com/hamakn/8939eb68a920a6d7a498

Code snippet:

public static int getStatusHeight(Context context) {
    int statusBarHeight = -1;
    try {
        Class<?> clazz = Class.forName("com.android.internal.R$dimen");
        Object object = clazz.newInstance();
        int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
        statusBarHeight = context.getResources().getDimensionPixelSize(height);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return statusBarHeight;
}

Detect device orientation by OrientationEventListener

Reference:
http://blog.csdn.net/zxccxzzxz/article/details/52282256

Code snippet:
private int mLastRotation = -1;
mOrientationEventListener = new OrientationEventListener(this,
        SensorManager.SENSOR_DELAY_NORMAL) {
    @Override    public void onOrientationChanged(int orientation) {
        if (orientation == ORIENTATION_UNKNOWN) {
            return;
        }
        Display display = windowManager.getDefaultDisplay();
        int rotation = display.getRotation();
        if (mLastRotation == DEFAULT_ROTATION){
            mLastRotation = rotation;
        } else if (rotation != mLastRotation) {
            mLastRotation = rotation;
            // notify orientation change
        }
    }
};

2018年4月5日 星期四

Change the menu style on ActionBar

Reference:

http://www.itstrike.cn/Question/c9ee24fa-9e1a-4154-a304-1fd41d418561.html

Code snippet:

1. Background

AndroidManifest.xml
<application    ......
    android:theme="@style/AppTheme">

style.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">   
    <!-- Customize actionbar overflow menu-->    <item name="actionOverflowMenuStyle">@style/My.Widget.Material.Light.PopupMenu.Overflow</item>    
</style>

<style name="My.Widget.Material.Light.PopupMenu.Overflow" parent="android:Widget.Material.Light.PopupMenu.Overflow">
    <item name="android:popupBackground">@drawable/my_popup_background_material</item>
</style>


drawable/my_popup_background_material.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"       android:shape="rectangle">
    <corners            android:radius="12dp" />
    <solid            android:color="@color/action_bar_color" />
</shape>

2. List choice background
activity_layout.xml
......
<android.support.v7.widget.Toolbar    android:id="@+id/tool_bar"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="@color/action_bar_color"    android:theme="@style/AppTheme.AppBarOverlay"    app:contentInsetStartWithNavigation="0dp"    app:popupTheme="@style/AppTheme.PopupOverlay" >

style.xml
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light">
    <item name="android:textColor">@color/list_item_title</item>
    <item name="android:textSize">18sp</item>
    <item name="android:textStyle">normal</item>
    <item name="android:listChoiceBackgroundIndicator">@drawable/my_list_choice_background_material</item>
</style>

drawable/my_list_choice_background_material.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"        android:color="@color/list_highlight_material">
    <item>
        <shape android:shape="rectangle">
            <corners android:radius="12dp"/>
            <solid android:color="@color/action_bar_color" />
        </shape>
    </item>
</ripple>

How to import org.apache.http library to Android Studio

Reference:

https://dotblogs.com.tw/newmonkey48/2016/02/22/140802

Code snippet:

build.gradle

android {
    useLibrary 'org.apache.http.legacy'
}