SD Card的大小和容量

StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long sdAvailSize = (long)stat.getAvailableBlocks()
               * (long)stat.getBlockSize();
long sdTotalSize =  (long)stat.getBlockCount()
                * (long)stat.getBlockSize()

Android 去掉Activtiy之间的切换动画

<style name="NoAnimationTheme">
    <item name="android:windowAnimationStyle">@style/Animation</item>
</style>
<style name="Animation">
    <item name="android:activityOpenEnterAnimation">@null</item>
    <item name="android:activityOpenExitAnimation">@null</item>
    <item name="android:activityCloseEnterAnimation">@null</item>
    <item name="android:activityCloseExitAnimation">@null</item>
    <item name="android:taskOpenEnterAnimation">@null</item>
    <item name="android:taskOpenExitAnimation">@null</item>
    <item name="android:taskCloseEnterAnimation">@null</item>
    <item name="android:taskCloseExitAnimation">@null</item>
    <item name="android:taskToFrontEnterAnimation">@null</item>
    <item name="android:taskToFrontExitAnimation">@null</item>
    <item name="android:taskToBackEnterAnimation">@null</item>
    <item name="android:taskToBackExitAnimation">@null</item>
</style>

在使用的时候,只需将不需要动画的Activity的style设置成这个就可以了

格式化文件容量代码

public static String formatSize(long size) {
    if (size < 1024) {
        return String.format("%dByte", size);
    } else if (size < 1024 * 1024) {
        return String.format("%.2fKb", size / 1024f);
    } else if (size < 1024 * 1024 * 1024) {
        return String.format("%.2fMb", size / 1024f / 1024f);
    } else {
        return String.format("%.2fGb", size / 1024f / 1024f / 1024f);
    }
}

在`values`中定义id

values文件夹中创建ids.xml文件, 文件目录为:values/ids.xml

我们有时候,会在代码中定义一个组件,如TextView,但是我们想给他设置一个Id,又不知道该设置一个
什么值比较好,就可以用上术方法来定义一个id, 具体代码如下:

<?xml version="1.0" encoding="utf-8"?>
<values>
<item name="custom_item_id" type="id"></item>
</values>

gradle打包的时候,自动重命名APK文件

android.applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def outputFile = output.outputFile
        if (outputFile != null && outputFile.name.endsWith('.apk')) {
            def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}-${ defaultConfig.versionCode}.apk")
            output.outputFile = new File(outputFile.parent, fileName)
        }
    }
}

Android文字颜色选择器

//在这个地方,应该使用
//android:textColor="@drawable/text_color"

// text_color.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/click_blue_color"></item>
    <item android:color="@color/blue_color"></item>
</selector>

TextView之代码设置DrawableLeft

Drawable drawable = getResources().getDrawable(R.drawable.drawable);  
/// 这一步必须要做,否则不会显示.  
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());  
myTextview.setCompoundDrawables(drawable,null,null,null);

Android 按两次返回键退出应用程序

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        if ((System.currentTimeMillis() - mExitTime) > 2000) {
            Object mHelperUtils;
            Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
            mExitTime = System.currentTimeMillis();

        } else {
            finish();
        }
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

Android string.xml中的占位符

<!-- .2f表示的是保留三位小数的浮点数  -->
<string name="book">书名 (字符串)%1$s,作者(字符串)%2$s,编号(整数)%3$d,价格(浮点型):%4$.2f</string>

Android TextView 设置字体大小

/**
 * Set the default text size to the given value, interpreted as "scaled
 * pixel" units.  This size is adjusted based on the current density and
 * user font size preference.
 *
 * @param size The scaled pixel size.
 *
 * @attr ref android.R.styleable#TextView_textSize
 */
@android.view.RemotableViewMethod
public void setTextSize(float size) {
    setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}

/**
 * Set the default text size to a given unit and value.  See {@link
 * TypedValue} for the possible dimension units.
 *
 * @param unit The desired dimension unit.
 * @param size The desired size in the given units.
 *
 * @attr ref android.R.styleable#TextView_textSize
 */
public void setTextSize(int unit, float size) {
    Context c = getContext();
    Resources r;

    if (c == null)
        r = Resources.getSystem();
    else
        r = c.getResources();

    setRawTextSize(TypedValue.applyDimension(
            unit, size, r.getDisplayMetrics()));
}

private void setRawTextSize(float size) {
    if (size != mTextPaint.getTextSize()) {
        mTextPaint.setTextSize(size);

        if (mLayout != null) {
            nullLayouts();
            requestLayout();
            invalidate();
        }
    }
}

以上代码是Android TextView设置字体的源码。可以看出来,使用setTextSize(float size)的时候,默认单位为sp

如果你自己从xml中读的时候,最好使用setTextSize(int unit, float size)这个方法。

Android 混淆记录

--keep class cn.knero.model.*{
    public <methods>; // 不混淆public的方法
}


# Google Gson
#---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
-keep class com.google.** { *; }
-keep class * extends com.google.gson.reflect.TypeToken
-keep class com.google.gson.reflect.TypeToken
##---------------End: proguard configuration for Gson  ----------


#混淆某个方法
-keepclassmembers class cn.knero.fragment.BaseContentFragment {
    public android.view.View refreshError();
    public android.view.View onLoading();
}

java反射内部类

  1. 在java中反射加载类的方法如下
Class rClass = Class.forName("android.R");
  1. 加载android.R.attr
Class attrClass = Class.forName("android.R$attr");

内部类并不是像调用那样,使用., 而是使用$

Android显示密码


//  方法1:
if (mIsShowPsw) {
    mPswEdit.setTransformationMethod(HideReturnsTransformationMethod
            .getInstance());
} else {
    mPswEdit.setTransformationMethod(PasswordTransformationMethod
            .getInstance());
}

// 方法2:
int inputType  = mPswEdit.getInputType();
if (inputType == 129) {
    mPswEdit.setInputType(1);
} else {
    mPswEdit.setInputType(129);
}

Android 截取EditText输入的Emoji表情

public String subInputText(String inputText,int index) {
    int unicode = Character.codePointAt(text, index);
    int skip = Character.charCount(unicode);
    mInputSquares[textCount++].setText(text.substring(index, index+skip));
}

XML 实现 ListView divider margin

<?xml version="1.0" encoding="UTF-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetLeft="50dp"
    android:insetRight="50dp" >
    <shape>
        <solid android:color="@color/orange" />
        <corners android:radius="2.0dip" />
    </shape>
</inset>

参考:

How to assign padding to Listview item divider line

Android TextView setTextSize

Android TextView 在设置TextSize 值很大的时候,会报如下错误Font size too large to fit in cache。 修改方法如下:

TextView bigText = (TextView) findViewById(R.id.bigtext);
bigText.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

获取Logcat信息

private void getLogcat( final LogcatListener listener ) {

    new Thread() {
        @Override
        public void run() {
            try {
                String processId = Integer.toString( android.os.Process.myPid() );
                String[] command = new String[]{
                        "logcat",
                        "-d",
                        "-v",
                        "threadtime"
                };
                Process process = Runtime.getRuntime().exec( command );
                BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( process
                        .getInputStream() ) );

                StringBuilder log = new StringBuilder();
                String line;
                while ( ( line = bufferedReader.readLine() ) != null ) {
                    if ( line.contains( processId ) ) {
                        int lineColor = verboseColor;

                        if ( line.contains( " I " ) ) {
                            lineColor = infoColor;
                        } else if ( line.contains( " E " ) ) {
                            lineColor = errorColor;
                        } else if ( line.contains( " D " ) ) {
                            lineColor = debugColor;
                        } else if ( line.contains( " W " ) ) {
                            lineColor = warningColor;
                        }

                        log.append( "<font color=\"#" + Integer.toHexString( lineColor )
                                .toUpperCase()
                                .substring( 2 ) + "\">" + line + "</font><br><br>" );
                    }
                }
                listener.onLogcatCaptured( log.toString() );
            } catch ( Exception e ) {
                e.printStackTrace();
            }
        }
    }.start();
}

```java