平时的一些小知识点
Android
2013.11.20
代码中设置输入法
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
/** 隐藏输入法 */
private void toggleInputMethod(){
InputMethodManager imm = (InputMethodManager) this.getActivity().getSystemService(this.getActivity().INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearchView.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
如果是提供给其他人用的封装好的工具类,有些异常不要在工具类中捕捉,而要抛出来,以便处理
(在做项目过程中,由于调用的是别人写好的jar包,而它在里面已经对异常处理了,我就没法再捕捉这个异常进行处理)
1 /** 2 * @description: 安装下载完成的App 3 * @param localPath :App的地址 4 */ 5 private void installApp(String localPath) { 6 Intent intent = new Intent(); 7 intent.setAction(Intent.ACTION_VIEW); 8 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 9 intent.setDataAndType(Uri.fromFile(new File(localPath)), "application/vnd.android.package-archive"); 10 context.startActivity(intent); 11 }
2013.11.27
原文地址:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=195135&page=1#pid1839003
ViewPager铺满剩余全屏的问题
viewPager下面还有放东西,但是只要在viewPager下面的东西都看不到,viewpager沾满了剩余的所有空间
解决方案参考:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1.0" /> <ImageView android:id="@+id/ivCursor" android:layout_width="60dp" android:layout_height="5dp" android:scaleType="fitCenter" android:src="@drawable/cursor" /> <LinearLayout android:id="@+id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
2013.11.28
解决拍照及上传图片旋转问题:
/** * 选择完图片后的回调方法 * * @param requestCode * int * @param resultCode * int * @param data * Intent */ @SuppressLint("NewApi") protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Bitmap bitmap = null; Uri imageUri = null; if (resultCode == RESULT_OK) { if (requestCode == 1) { //从相册选择图片 imageUri = data.getData(); } else if (requestCode == 0) { Uri data2 = data.getData(); // 拍照 String imageUrl = data.getDataString(); if(imageUri==null){ Bundle extras = data.getExtras(); bitmap = (Bitmap) extras.get("data"); // 压缩图片 bitmap = ThumbnailUtils.extractThumbnail(bitmap, BITMAP_SIZE, BITMAP_SIZE); }else { imageUri = Uri.parse(imageUrl); } } else if (requestCode == UserSettingActivity.REQUEST_CODE_GO_TO_HOME_TOWN) { setResult(RESULT_OK); } if (imageUri != null) { String[] proj = { MediaStore.Images.Media.DATA }; Cursor actualimagecursor = managedQuery(imageUri, proj, null, null, null); int actual_image_column_index = actualimagecursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); actualimagecursor.moveToFirst(); String img_path = actualimagecursor .getString(actual_image_column_index); int picDegree = readPictureDegree(img_path); bitmap = BitmapFactory.decodeFile(img_path); bitmap = rotaingImageView(bitmap, picDegree); // 压缩图片 bitmap = ThumbnailUtils.extractThumbnail(bitmap, BITMAP_SIZE, BITMAP_SIZE); } if (bitmap != null) { bitmap = getCircleBitmap(bitmap); uploadHead(bitmap); } } } /** * 旋转图片 * @param angle * @param bitmap * @return Bitmap */ public static Bitmap rotaingImageView(Bitmap bitmap,int angle) { //旋转图片 动作 Matrix matrix = new Matrix();; matrix.postRotate(angle); // 创建新的图片 Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); return resizedBitmap; } /** * 读取图片属性:旋转的角度 * @param path 图片绝对路径 * @return degree旋转的角度 */ public static int readPictureDegree(String path) { int degree = 0; try { ExifInterface exifInterface = new ExifInterface(path); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; } } catch (IOException e) { e.printStackTrace(); } return degree; } /** * 将圆形图片,返回Bitmap * @param bitmap 源Bitmap * @return */ public static Bitmap getCircleBitmap(Bitmap bitmap) { int x = bitmap.getWidth(); int y = bitmap.getHeight(); Bitmap output = Bitmap.createBitmap(x, y, Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); // 根据原来图片大小画一个矩形 final Rect rect = new Rect(0, 0, x, y); paint.setAntiAlias(true); paint.setColor(color); // 画出一个圆 canvas.drawCircle(x/2, x/2, x/2-5, paint); //canvas.translate(-25, -6); // 取两层绘制交集,显示上层 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); // 将图片画上去 canvas.drawBitmap(bitmap, rect, rect, paint); // 返回Bitmap对象 return output; }
2013.12.04
判断应用已经打开
ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List<RunningTaskInfo> list = am.getRunningTasks(200); for (RunningTaskInfo info : list) { if (info.topActivity.getPackageName().toLowerCase().equals(appBean.getAppPackageCode().toLowerCase()) && info.baseActivity.getPackageName().toLowerCase().equals(appBean.getAppPackageCode().toLowerCase())) { BaseToast.getInstance(mContext, appBean.getAppName()+"已经打开").show(); return; } }
2014.3.12
apk反编译工具apktool反编译大APK JVM OOM处理办法
将批处理文件改为
@echo off
java -Xms512m -Xmx1024m -jar "%~dp0\apktool.jar" %1 %2 %3 %4 %5 %6 %7 %8 %9
用法:
1.进到apktool.jar所在目录
2.在命令行中输入apktool d /xxx/xxx.apk /xxx/xxx完后等待饥渴
2014.4.8
关于android.view.WindowLeaked的解决方案
转自http://blog.csdn.net/u_xtian/article/details/6123945
按字面了解,Window Leaked大概就是说一个窗体泄漏了,也就是我们常说的内存泄漏,为什么窗体会泄漏呢?
产生原因:
我们知道Android的每一个Activity都有个WindowManager窗体管理器,同样,构建在某个Activity之上的对话框、PopupWindow也有相应的WindowManager窗体管理器。因为对话框、PopupWindown不能脱离Activity而单独存在着,所以当某个Dialog或者某个PopupWindow正在显示的时候我们去finish()了承载该Dialog(或PopupWindow)的Activity时,就会抛Window Leaked异常了,因为这个Dialog(或PopupWindow)的WindowManager已经没有谁可以附属了,所以它的窗体管理器已经泄漏了。
解决方法:
关闭(finish)某个Activity前,要确保附属在上面的Dialog或PopupWindow已经关闭(dismiss)了。
2014.4.10
微信Android版本欢迎界面是怎么实现的
Android欢迎界面有如下几个特点:
- 第一次打开微信时, 会弹出欢迎界面(欢迎界面+延迟加载微信主界面), 之后在打开则不会有该界面弹出
- 强杀进程 或者 清除最近运行列表, 下次运行时, 则又会弹出欢迎界面
想到了一个比较标准的实现:
- SplashActivity - 欢迎界面
- MainActivity - 主界面
- 在Splash中延迟启动Main, 并Override Main中的onBackPressed()
public class MainActivity extends Activity { ... @Override public void onBackPressed() { //super.onBackPressed(); moveTaskToBack(true); } }
2014.04.15
关于android KitKat API 19发短信会保存草稿,下次再给此人发的时候,不能显示自定义短信内容的问题
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) //At least KitKat { String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(activity); //Need to change the build to API 19 Intent sendIntent = new Intent(Intent.ACTION_SEND); sendIntent.setType("text/plain"); sendIntent.putExtra(Intent.EXTRA_TEXT, smsText); if (defaultSmsPackageName != null)//Can be null in case that there is no default, then the user would be able to choose any app that support this intent. { sendIntent.setPackage(defaultSmsPackageName); } activity.startActivity(sendIntent); } else //For early versions, do what worked for you before. { Intent sendIntent = new Intent(Intent.ACTION_VIEW); sendIntent.setData(Uri.parse("sms:")); sendIntent.putExtra("sms_body", smsText); activity.startActivity(sendIntent); }
还没有完全解决,可以发新的内容,但是联系人不能自动填充了
2014.04.30
关于同步
1、对于同步的方法或者代码块来说,必须获得对象锁才能够进入同步方法或者代码块进行操作;
2、如果采用method级别的同步,则对象锁即为method所在的对象,如果是静态方法,对象锁即指method所在的
Class对象(唯一);
3、对于代码块,对象锁即指synchronized(abc)中的abc;
摘自http://blog.csdn.net/yangzhijun_cau/article/details/6432216
2014.08.28
android ListView 自动滚动到最底部
如何让你的ListView实现自动滚动呢? Android其实已经考虑到ListView控件的智能滚动操作。直接在Layout中写即可,注意下面的stackFromBottom以及 transcriptMode这两个属性。涉及代码如下:
< ListView android:id="listCWJ"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
/>
摘自:http://blog.163.com/hero_213/blog/static/3989121420116242163189/
2015.07.21
ScrollView中有LinearLayout,都是match_parent ScrollView得加
android:fillViewport="true"
才可以使LinnearLayout填充父窗体
摘自:http://stackoverflow.com/questions/13703447/android-difficulty-with-linearlayout-inside-scrollview
2015.07.28
重复元素背景
<!-- 文件名aaaa.xml放在drawable目录下 -->
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/ic_money" android:tileMode="repeat" />
引用
<ImageView android:layout_width="match_parent" android:background="@drawable/aaaa" android:layout_height="wrap_content"/>
2015.08.17
API21 notification的问题
notification在API21和21之前是不一样的
在用信鸽推送的时候,发现通知栏图标有问题。
看红色线框的地方,图标是白色的,不是应用图标
而且我想要的效果是下面这样的
折腾了一下午,发现信鸽的demo是没有问题的。
最后发现targetSdkVersion不同,试着改成20,OK了,这么神奇。
先记录在这,以后有时间再看看21以上的notification图标及小图标是怎么设置的
2016.04.13
图片毛玻璃效果
http://stackoverflow.com/questions/2067955/fast-bitmap-blur-for-android-sdk
import android.graphics.Bitmap; public class FastBlur { /** * Stack Blur v1.0 from * http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html * Java Author: Mario Klingemann <mario at quasimondo.com> * http://incubator.quasimondo.com * * created Feburary 29, 2004 * Android port : Yahel Bouaziz <yahel at kayenko.com> * http://www.kayenko.com * ported april 5th, 2012 * * This is a compromise between Gaussian Blur and Box blur * It creates much better looking blurs than Box Blur, but is * 7x faster than my Gaussian Blur implementation. * * I called it Stack Blur because this describes best how this * filter works internally: it creates a kind of moving stack * of colors whilst scanning through the image. Thereby it * just has to add one new block of color to the right side * of the stack and remove the leftmost color. The remaining * colors on the topmost layer of the stack are either added on * or reduced by one, depending on if they are on the right or * on the left side of the stack. * * If you are using this algorithm in your code please add * the following line: * Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com> */ public static Bitmap blur(Bitmap sentBitmap, float scale, int radius) { int width = Math.round(sentBitmap.getWidth() * scale); int height = Math.round(sentBitmap.getHeight() * scale); sentBitmap = Bitmap.createScaledBitmap(sentBitmap, width, height, false); Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); if (radius < 1) { return (null); } int w = bitmap.getWidth(); int h = bitmap.getHeight(); int[] pix = new int[w * h]; bitmap.getPixels(pix, 0, w, 0, 0, w, h); int wm = w - 1; int hm = h - 1; int wh = w * h; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, yp, yi, yw; int vmin[] = new int[Math.max(w, h)]; int divsum = (div + 1) >> 1; divsum *= divsum; int dv[] = new int[256 * divsum]; for (i = 0; i < 256 * divsum; i++) { dv[i] = (i / divsum); } yw = yi = 0; int[][] stack = new int[div][3]; int stackpointer; int stackstart; int[] sir; int rbs; int r1 = radius + 1; int routsum, goutsum, boutsum; int rinsum, ginsum, binsum; for (y = 0; y < h; y++) { rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; for (i = -radius; i <= radius; i++) { p = pix[yi + Math.min(wm, Math.max(i, 0))]; sir = stack[i + radius]; sir[0] = (p & 0xff0000) >> 16; sir[1] = (p & 0x00ff00) >> 8; sir[2] = (p & 0x0000ff); rbs = r1 - Math.abs(i); rsum += sir[0] * rbs; gsum += sir[1] * rbs; bsum += sir[2] * rbs; if (i > 0) { rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; } else { routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; } } stackpointer = radius; for (x = 0; x < w; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; rsum -= routsum; gsum -= goutsum; bsum -= boutsum; stackstart = stackpointer - radius + div; sir = stack[stackstart % div]; routsum -= sir[0]; goutsum -= sir[1]; boutsum -= sir[2]; if (y == 0) { vmin[x] = Math.min(x + radius + 1, wm); } p = pix[yw + vmin[x]]; sir[0] = (p & 0xff0000) >> 16; sir[1] = (p & 0x00ff00) >> 8; sir[2] = (p & 0x0000ff); rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; rsum += rinsum; gsum += ginsum; bsum += binsum; stackpointer = (stackpointer + 1) % div; sir = stack[(stackpointer) % div]; routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; rinsum -= sir[0]; ginsum -= sir[1]; binsum -= sir[2]; yi++; } yw += w; } for (x = 0; x < w; x++) { rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; yp = -radius * w; for (i = -radius; i <= radius; i++) { yi = Math.max(0, yp) + x; sir = stack[i + radius]; sir[0] = r[yi]; sir[1] = g[yi]; sir[2] = b[yi]; rbs = r1 - Math.abs(i); rsum += r[yi] * rbs; gsum += g[yi] * rbs; bsum += b[yi] * rbs; if (i > 0) { rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; } else { routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; } if (i < hm) { yp += w; } } yi = x; stackpointer = radius; for (y = 0; y < h; y++) { // Preserve alpha channel: ( 0xff000000 & pix[yi] ) pix[yi] = ( 0xff000000 & pix[yi] ) | ( dv[rsum] << 16 ) | ( dv[gsum] << 8 ) | dv[bsum]; rsum -= routsum; gsum -= goutsum; bsum -= boutsum; stackstart = stackpointer - radius + div; sir = stack[stackstart % div]; routsum -= sir[0]; goutsum -= sir[1]; boutsum -= sir[2]; if (x == 0) { vmin[y] = Math.min(y + r1, hm) * w; } p = x + vmin[y]; sir[0] = r[p]; sir[1] = g[p]; sir[2] = b[p]; rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; rsum += rinsum; gsum += ginsum; bsum += binsum; stackpointer = (stackpointer + 1) % div; sir = stack[stackpointer]; routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; rinsum -= sir[0]; ginsum -= sir[1]; binsum -= sir[2]; yi += w; } } bitmap.setPixels(pix, 0, w, 0, 0, w, h); return (bitmap); } }
2016.05.11
Android 6.0 RecyclerView 重绘BUG
当RecyclerView版本超过23.1.0时有BUG 界面relayout时会绘制不应该显示的item
compile 'com.android.support:recyclerview-v7:23.1.0'
2016.05.12 android studio 过滤指定消息
^((?!NeteaseLiveStream).)*$
2016.07.22 android保存图片到手机,但相册里不显示
解决办法 http://stackoverflow.com/a/18403531
MediaScannerConnection.scanFile(DetailsActivity.this, new String[] {filepath }, null, new OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
}
});
2016.08.01 ViewGroup public void setClipToPadding (boolean clipToPadding)方法使用 false:子view不会被夹在ViewGroup padding中,true:子view会夹在ViewGroup padding中
2016.08.26 Android扫描图片
Android在6.0系统上扫描图片不好用,找到了这个解决文案,由于MediaScannerConnection.scanFile扫描目录很耗资源,后面的Api不允许扫描目录了。
http://stackoverflow.com/a/25086535/4459975
2016.09.21 Android MediaPlayer设置音量
Android MediaPlayer设置音量大小的方法:public void setVolume(float leftVolume, float rightVolume)不是线性的
private final static int MAX_VOLUME = 100; ... ... final float volume = (float) (1 - (Math.log(MAX_VOLUME - soundVolume) / Math.log(MAX_VOLUME))); mediaPlayer.setVolume(volume, volume);
引自:http://stackoverflow.com/a/12197453
2016.09.29 android手机开启Hierarchy Viewer
android studio --> Tools --> Android --> Android Device Monitor --> Window --> Open Perspective --> Hierarchy View
这时有的手机是不能看view层级的需要电脑设置
2017.02.27 设置Paint
// 连接处以圆弧连接 mPaint.setStrokeJoin(Paint.Join.ROUND); // 笔划突出为半圆形,中心在路径的末端。 mPaint.setStrokeCap(Paint.Cap.ROUND);
2017.07.13
EditText设置最大输入长度为12,其中中文最多可以输入6个,英文可以输入12个
editText.setFilters(new InputFilter[]{new LengthFilter(10)}); /** * This filter will constrain edits not to make the length of the text * greater than the specified length. */ public static class LengthFilter implements InputFilter { private final int mMax; String regEx = "[\\u4e00-\\u9fa5]"; // unicode编码,判断是否为汉字 public LengthFilter(int max) { mMax = max; } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { CharSequence destSubStr = dest.subSequence(dstart, dend); int keep = mMax - (dest.length() + getChineseCount(dest.toString()) - destSubStr.length() - getChineseCount(destSubStr.toString())); if (keep <= 0) { return ""; } else { if (source.length() == 0) { return null; } else { String sourceSub = source.subSequence(start, end).toString(); if (sourceSub.length() + getChineseCount(sourceSub) <= keep) { return null; } else { int subEndIndex = getSubEndIndex(sourceSub, keep); if (subEndIndex != -1) { return sourceSub.substring(0, subEndIndex + 1); } else { return ""; } } } } } private int getSubEndIndex(String source, int keep) { int count = 0; int index = -1; for (int i = 0; i < source.length(); i++) { count++; String substring = source.substring(i, i + 1); if (isChinese(substring)) { count++; } if (count > keep) { index = i - 1; break; } else { index = i; } } return index; } private int getChineseCount(String str) { int count = 0; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(str); while (m.find()) { for (int i = 0; i <= m.groupCount(); i++) { count = count + 1; } } return count; } public static boolean isChinese(String str) { String regEx = "[\u4e00-\u9fa5]"; Pattern pat = Pattern.compile(regEx); Matcher matcher = pat.matcher(str); boolean flg = false; if (matcher.find()) flg = true; return flg; } /** * @return the maximum length enforced by this input filter */ public int getMax() { return mMax; } }