平时的一些小知识点

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 "%~dp0apktool.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欢迎界面有如下几个特点:

  1. 第一次打开微信时, 会弹出欢迎界面(欢迎界面+延迟加载微信主界面), 之后在打开则不会有该界面弹出
  2. 强杀进程 或者 清除最近运行列表, 下次运行时, 则又会弹出欢迎界面

想到了一个比较标准的实现:

  1. SplashActivity - 欢迎界面
  2. MainActivity    - 主界面
  3. 在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);
    }

摘自http://stackoverflow.com/questions/20079047/android-kitkat-4-4-hangouts-cannot-handle-sending-sms-intent

还没有完全解决,可以发新的内容,但是联系人不能自动填充了

 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;
        }
    }
原文地址:https://www.cnblogs.com/a0000/p/3433073.html