获取手机内存与SD卡容量
@SuppressWarnings("deprecation")
private String getSize(String path) {
StatFs fs = new StatFs(path);
int count = fs.getBlockCount();//得到block的总数
long size = fs.getBlockSize();//得到每一个block的大小
int availableBlocks = fs.getAvailableBlocks();//得到可用的block的数量
String allSize = Formatter.formatFileSize(this, count * size);
String avaSize = Formatter.formatFileSize(this, availableBlocks * size);
return "所有:" + allSize + ",可用:" + avaSize;
}
对于其中的参数path,如果是sd卡,就用Environment.getExternalStorageDirectory().getPath().如果要获取手机内存,就用Environment.getDataDirectory().getPath()。
设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);//无标题栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);// 全屏
以命令运行activity
am start -n com.baigle.adapterdemo/com.baigle.adapterdemo.MainActivity
其中com.baigle.adapterdemo指的是应用的包名,而com.baigle.adapterdemo.MainActivity指的是要启动的activity。这样就可以直接启动对应的activity了。
am命令
sp变化监听
sp = PreferenceManager.getDefaultSharedPreferences(this);//获取sp,这里是默认的
listener = new OnSharedPreferenceChangeListener() {//sp变化监听的监听器
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
if ("pref_syncConnectionType".equals(key)) {
Preference preference = findPreference(key);
preference.setSummary(sp.getString(key, "default"));
}
}
};
@Override
protected void onResume() {//建议在onResume()中为sp注册监听
super.onResume();
sp.registerOnSharedPreferenceChangeListener(listener);
}
@Override
protected void onPause() {//建议在onPause()中为sp注销监听
super.onPause();
sp.unregisterOnSharedPreferenceChangeListener(listener);
}
该方法主要是与Preference结合着使用,当用户更改了某一设置时,可以立即在界面上展示。
之所以在onResume()与onPause()中注册与注销,是因为这两个方法界定了当前界面可操作与不可操作的边界。
界面高亮提示
在有些手机应用中,经常会出现在某一个界面上时会显示将某一个图标高亮显示,并且配上文字说明,而除了该图标之外的地方都是被蒙上一层阴影的。为实现该效果需要两步:(1)获得所要高度显示的组件的位置及大小,(2)用fragment蒙上原本的界面,并在高度组件处放置一个同样的组件。
示例如下:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_above, container, false);
TextView above = (TextView) view.findViewById(R.id.tv_above);
//通过LayoutParams将传递的参数设置给要高亮显示的组件
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(mWidth, mHeight);
lp.leftMargin = mLeft - leftPadding;//-leftPadding是因为承载该fragment的ViewGroup本身距离屏幕有一定的距离
lp.topMargin = mTop-38-leftPadding;//-38是减除状态栏的高度
above.setLayoutParams(lp);
return view;
}
在第一步中主要通过View.getLocationInWindow()方法获取到组件自身在屏幕上的位置,该方法将组件的左上角坐标赋值到传递的2维数组中,并且该位置是相对于屏幕的左上角而言,也即是:左上角的Y轴坐标是包含状态栏的。
禁用物理菜单键
/**
* 关闭menu键
*/
public void closeMenu() {
try {
ViewConfiguration mconfig = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class
.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(mconfig, false);
}
} catch (Exception ex) {
}
}
res/raw与assets
两者都是用来存放音频等文件的,但是raw目录下的文件系统会生成资源id:R.raw.file_name,但assets目录中的却不会。前者可以Resources.openRawResource();将对应的资源转换成InputStream,而后者只能通过AssetManager来读取。
兼容api
如果在低版本上使用到了新版本的api,有两种方法:第一判断当前系统的api版本,只有满足调用新api的最低版本时才调用;第二种通过反射,如果获取不到新api中的方法,就意味着当前没办法调用新api,就需要通过旧api进行代替。例如:新版本的SharedPreferences.Editor提供了一个apply()方法,可以通过以下的方式进行判断:
private void commit(Editor editor) {
Class<Editor> clazz = SharedPreferences.Editor.class;
try {
Method method = clazz.getMethod("apply");
method.invoke(editor);
} catch (Exception e) {
e.printStackTrace();
editor.commit();//报异常说明没有该方法,就调用旧版本的commit()
}
}
加载GIF
android对gif的显示是通过Movie类辅助完成的。4.0以上系统要显示gif时,必须关掉硬件加速,即在清单文件中配置android:hardwareAccelerated="false",或者调用View.setLayerType(LAYER_TYPE_SOFTWARE, new Paint());(据说此种方法适用于一部分手机)。
示例如下:
private static class SampleView extends View {
private Movie mMovie;
private long mMovieStart;
public SampleView(Context context) {
super(context);
setFocusable(true);
InputStream is = context.getResources().openRawResource(
R.drawable.animated_gif);
mMovie = Movie.decodeStream(is);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFCCCCCC);
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
}
if (mMovie != null) {
int dur = mMovie.duration();//获取gif持续时间
if (dur == 0) {
dur = 1000;
}
int relTime = (int) ((now - mMovieStart) % dur);
mMovie.setTime(relTime);
mMovie.draw(canvas, getWidth() - mMovie.width(), getHeight()
- mMovie.height());
invalidate();
}
}
}
上述代码首先通过Movie.decodeStream()生成与gif图片关联的Movie对象。通过Movie.setTime()设置当前显示gif应该要显示的时间,再调用Movie.draw()将当前时间对应的帧画在对应的canvas上。并通过不断调用onDraw()方法,画不同的帧从而使图片动起来。
上面通过在onDraw()中调用invalidate(),可以不断重复执行onDraw(),从而保证了gif可以动起来。
图片模糊
需要使用RenderScript进行向下兼容,而sdk本身就含有一个renderscript-v8.jar的jar包,直接可以使用。具体位置为:sdk\build-tools\sdk版本\renderscript\lib。示例具体代码如下:
public class BlurTools {
private static final float BITMAP_SCALE = 0.4f;
private static final float BLUR_RADIUS = 20f;
public static Bitmap blurView(View v) {
return blurBitmap(v.getContext(), getScreenshot(v));
}
public static Bitmap blurBitmap(Context ctx, Bitmap image) {
int width = Math.round(image.getWidth() * BITMAP_SCALE);
int height = Math.round(image.getHeight() * BITMAP_SCALE);
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
RenderScript rs = RenderScript.create(ctx);
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
theIntrinsic.setRadius(BLUR_RADIUS);
theIntrinsic.setInput(tmpIn);
theIntrinsic.forEach(tmpOut);
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
private static Bitmap getScreenshot(View v) {
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
}
上述代码抄自stackoverflow,具体链接忘记了。
关联support源码
sdk本身就含有各种support包,具体位置为sdk\extras\android\support。而在每一个support包下面都会有该包的源码,如:sdk\extras\android\support\v4\src。而在adt中关联源码方法如下:
1,在libs目录下建立android-support-v4.jar.properties文件
2,大该文件中添加"src = D:\\android-IDE\\sdk\\extras\\android\\support\\v4\\src",这里要注意:只写到src目录就可以,不要在结尾处添加分号,将单斜杠用“\\”替换掉。其实这里指定的就是v4源码的位置,也可以是别的路径。
3,关闭工程,再打开就可以了。
对于上面的第二步,v7包中的源码并不是和libs在一个目录下,它是和support目录同级的m2repository下,并且将源码打成jar了。因此properties的写法如下:src = sdk的路径\\sdk\\extras\\android\\m2repository\\com\\android\\support\\recyclerview-v7\\版本\\recyclerview-v7-21.0.3-sources.jar
打乱List集合中元素的顺序
在某些时候需要打乱list集合中元素的顺序,可以通过以下方法进行操作:
Collections.sort(null, new Comparator<Object>() {
@Override
public int compare(Object lhs, Object rhs) {
//随机对调前后两个元素的
return Math.random() > 0.5 ? 1 : -1;
}
});