android 开发一些小细节

时间:2022-08-24 18:20:52
// 获取屏幕密度(方法 1  

             int screenWidth  =getWindowManager().getDefaultDisplay().getWidth();       // 屏幕宽(像素,如:480px) 

             int screenHeight =getWindowManager().getDefaultDisplay().getHeight();

             Log.i("WiFi_ClientsActivity",screenWidth + "左边是宽度------右边是高度" + screenHeight);

 

Android设置文字粗体的方法:

 

testTextView=(TextView)findViewById(R.id.testTextView);

testTextView.getPaint().setFakeBoldText(true);

 

英文和数字可以直接用XML去设置:

android:textStyle="bold"

 

//判断WiFi是否连接

 ConnectivityManager manager =(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

       NetworkInfo.State wifi =manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();

       if(wifi == NetworkInfo.State.CONNECTED){

           //WIFI已连接

           Toast.makeText(getApplicationContext(),"00000-----3333333",Toast.LENGTH_SHORT).show();

           checkDWR();

       }

 

Android 技术之 ListView 分割线显示和隐藏

 

1、设置和取消每个item分隔线

解决方案:

ListView.setDivider(null);

android:Divider="@null";

android:divider="@drawable/listview_horizon_line"

2、隐藏头部分隔线

 

listview分割线会在头部、数据item、及根部的底部打印,如果要取消头部分割线必须

 

先设置期方法

 

 addHeaderView(headView, null, true);

  addFooterView(footView, null, true);

 

注意:第三个参数必须为true,否则无效

 

//显示头部出现分割线

 

listview.setHeaderDividersEnabled(true);

   //禁止底部出现分割线

listview.setFooterDividersEnabled(false);

 

 

 

<?xml version="1.0"encoding="utf-8"?>

<resources>

  <string-array name="launger">

    <item>date1</item>

    <item>date2</item>

    <item>date3</item>

  </string-array>

</resources>

在代码里使用:Resources res;

 

                res=this.getResources();

 

              String []ab=res.getStringArray(R.array.launger);

 

一、ActivityTask()的关系

 

  Task就像一个容器,而Activity就相当与填充这个容器的东西,第一个东西(Activity)则会处于最下面,最后添加的东西(Activity)则会在最低端。从Task中取出东西(Activity)则是从最顶端取出。

  二、界面跳转和服务的启动都会用到Intent,现在介绍Intent Flag是关于Activity的跳转

  Intent intent = new Intent(this,xxx.class);

  //如果activity在task存在,拿到最顶端,不会启动新的Activity

  intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);

 

  //如果activity在task存在,将Activity之上的所有Activity结束掉

  intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

 

  //默认的跳转类型,将Activity放到一个新的Task中

  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

 

  //如果Activity已经运行到了Task,再次跳转不会在运行这个Activity

  intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

 

/**

     * 关闭软键盘

     */

   public static void hideSoftKeyboard(Activity activity) {

            InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);

            inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(),0);

        }

 

   public void setupUI(View view) {

       //Set up touch listener for non-text box views to hide keyboard.

       if(!(view instanceof EditText)) {

           view.setOnTouchListener(new View.OnTouchListener() {

                public boolean onTouch(View v,MotionEvent event) {

                   hideSoftKeyboard(LanSettingsFragment.this.getActivity());  //Main.this是我的activity名

                    return false;

                }

           });

       }

       //If a layout container, iterate over children and seed recursion.

       if (view instanceof ViewGroup) {

 

           for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {

                View innerView = ((ViewGroup)view).getChildAt(i);

                setupUI(innerView);

           }

       }

    }

 

 

//连接wifi获取到的信息

 

private void getWifiInfo(){

        WifiManager wm =(WifiManager)getSystemService(WIFI_SERVICE);

       DhcpInfo di = wm.getDhcpInfo();

       WifiInfo wifiInfo = wm.getConnectionInfo();

 

       long ipAddress = di.ipAddress;

       String ipAddress2=long2ip(ipAddress);//ip地址

       Log.i("MainActivity","getwayIpS:"+ipAddress2);

 

       long getewayIpL=di.gateway;

       String getwayIpS=long2ip(getewayIpL);//网关地址

       Log.i("MainActivity","getwayIpS:"+getwayIpS);

 

       long netmaskIpL=di.netmask;

       String netmaskIpS=long2ip(netmaskIpL);//子网掩码地址

       Log.i("MainActivity","netmaskIpS:"+netmaskIpS);

       //

       long nserverAddress = di.serverAddress;

       String nserverAddress1=long2ip(nserverAddress);//服务器地址

       Log.i("MainActivity","nserverAddress1:"+nserverAddress1);

 

       long dns1 = di.dns1;

       String dns11=long2ip(dns1);//dns1地址

       Log.i("MainActivity","dns11:"+dns11);

 

       long dns2 = di.dns2;

       String dns22=long2ip(dns2);//dns2地址

       Log.i("MainActivity","dns22:"+dns22);

 

       long leaseDuration = di.leaseDuration;//租期

       Log.i("MainActivity","getwayIpS:"+leaseDuration);

 

       String mac = wifiInfo.getMacAddress();//mac地址

       Log.i("MainActivity","mac:"+mac);

 

    }

 

   String long2ip(long ip){

       StringBuffer sb=new StringBuffer();

       sb.append(String.valueOf((int) (ip & 0xff)));

        sb.append('.');

       sb.append(String.valueOf((int) ((ip >> 8) & 0xff)));

       sb.append('.');

       sb.append(String.valueOf((int)((ip>>16)&0xff)));

       sb.append('.');

       sb.append(String.valueOf((int)((ip>>24)&0xff)));

       return sb.toString();

    }

 

 EditText焦点属性

使光标移动到制定的位置:

editText.setSelection(2);

输入的参数是个整数

2

在请求出现光标是,也就是在获取焦点时:

editText.requestFocus();

Android如何让EditText不自动获取焦点

解决之道:在EditText的父级控件中找一个,设置成

   Android:focusable="true" 
   android:focusableInTouchMode="true"

这样,就把EditText默认的行为截断了!

 

3

让EditText不出现光标:

editText.setCursorVisible(false);

禁止输入回车键

android:singleLine="true"  

 

 

//监听某个控件连续被点击多少次

 

//需要监听几次点击事件数组的长度就为几
long[]mHints =new long[8];//初始全部为0
//将mHints数组内的所有元素左移一个位置
System.arraycopy(mHints,1, mHints,0, mHints.length- 1);
//获得当前系统已经启动的时间
mHints[mHints.length-1] = SystemClock.uptimeMillis();
if (SystemClock.uptimeMillis() - mHints[0] <2000) {
   
Toast.makeText(SplashScreen.this,"------点击了8次------", Toast.LENGTH_SHORT).show();
   
//连续点击8次,跳过这个页面,到下一个页面去
    Intentintent = newIntent(SplashScreen.this,
           
LoginScreen.class);
   
startActivity(intent);
    finish();
}

 

//判断edittext有没有获取焦点

 

EditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {  

       

    @Override  

    public void onFocusChange(View v, boolean hasFocus) {  

        if(hasFocus){//获得焦点  

               

        }else{//失去焦点  

             

        }  

    }             

});

 

 

// 在类中用代码控制各个控件之间的间距

LinearLayout.LayoutParamslp1 =new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,

LinearLayout.LayoutParams.WRAP_CONTENT);


LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,

LinearLayout.LayoutParams.WRAP_CONTENT);


LinearLayout.LayoutParams lp3 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,

LinearLayout.LayoutParams.WRAP_CONTENT);


LinearLayout.LayoutParams lp4 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,

LinearLayout.LayoutParams.WRAP_CONTENT);

lp1.setMargins(0, 0,0,0);
lp2.setMargins(0, 0,0,0);
lp3.setMargins(0, 0,0,0);
lp4.setMargins(0, 0,0,0);

adminSettings = (ImageView) view.findViewById(R.id.ADMIN_SETTINGS);
lanSettings = (ImageView) view.findViewById(R.id.LAN_SETTINGS);
message = (ImageView) view.findViewById(R.id.MESSAGES_STATS);
power = (ImageView) view.findViewById(R.id.BATTERY_STATS);


adminSettings.setLayoutParams(lp1);
lanSettings.setLayoutParams(lp2);
message.setLayoutParams(lp3);
power.setLayoutParams(lp4);

 

 

// 安卓自定义字体

 

TypefacetypeFace =Typeface.createFromAsset(getActivity().getAssets(),"fonts/HelveticaNeueLt.ttf");
textview.setTypeface(typeFace);

 

/** 根据手机的分辨率从dp的单位转成为 px(像素)

public static intdip2px(Context context, float dpValue) {
 final float scale = context.getResources().getDisplayMetrics().density;
 return (int) (dpValue * scale + 0.5f);
}

 

/** 根据手机的分辨率从px(像素)的单位转成为 dp
public static intpx2dip(Context context, float pxValue) {
 final float scale = context.getResources().getDisplayMetrics().density;
 return (int) (pxValue / scale + 0.5f);
}

 

 

//Edittext光标位置

textMessage.setSelection(textMessage.length());

 

 

//1.TextView显示的内容过长时自动显示省略号:

 

省略号的位置:
xml

android:ellipsize = "end"  省略号在结尾

android:ellipsize ="start"   省略号在开头

android:ellipsize = "middle"    省略号在中间

android:ellipsize = "marquee" 跑马灯

android:singleline = "true"
android:lines="2"

 

当然也可以用代码语句

tv.setEllipsize(TextUtils.TruncateAt.valueOf("END"));

tv.setEllipsize(TextUtils.TruncateAt.valueOf("START"));

tv.setEllipsize(TextUtils.TruncateAt.valueOf("MIDDLE"));

tv.setEllipsize(TextUtils.TruncateAt.valueOf("MARQUEE"));

tv.setSingleLine(true);


tv.setEllipsize(null); // 展开

tv.setEllipsize(TextUtils.TruncateAt.END); // 收缩

 

//2.TextView文字中间加横线:
tv_goods_price= (TextView) v.findViewById(R.id.tv_goods_price);
tv_goods_price.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
底部加横线:
tv_goods_price.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);

 

 

// 比较两个时间的先后:

day1 day2 (数据类型均为日期类型)

Calendarc1=Calendar.getInstance();

c1.setTime(day1);

Calendarc2=Calendar.getInstance();

c2.setTime(day2);

if(c1.before(c2))

{ System.out.println("日期c1在日期c2");}

else{ System.out.println("日期c2在日期c1");}

 

 

 

importjava.text.ParseException;

importjava.text.SimpleDateFormat;

 import java.util.Date;

 public class Method_1 {

public static voidDateCompare(String s1,String s2) throws Exception {

//设定时间的模板

SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

//得到指定模范的时间

Date d1 = sdf.parse(s1);

Date d2 = sdf.parse(s2);

//比较

if(Math.abs(((d1.getTime()- d2.getTime())/(24*3600*1000))) >=3) {

 System.out.println("大于三天"); }

else{System.out.println("小于三天");} }

public static voidmain(String args[]) throws Exception {

newMethod_1().DateCompare("2011-11-28 11:15:11","2011-12-0211:15:11"); }

 

 

 

 

 

Calendar类的compareTo方法可以比较两个Calendar表示的时间的早晚:

          Calendar a= Calendar.getInstance();
         a.set(2011, 05,28, 19,50, 2);
          //参数为年 月 日 时 分 秒
           a.set(Calendar.MILLISECOND, 0);
           //设置毫秒
          Calendar c= Calendar.getInstance();
          c.set(2011, 05,28, 19,50, 3);
          c.set(Calendar.MILLISECOND, 0);
          System.out.println(a.compareTo(c));
         //a比c早,返回-1,
        //a与c相同,返回0
        //a比c晚,返回1

compareTo只能比较两个时间的早晚,并不能比较时差,如果需要得到时差,可以使用getTimeInMillis方法,得到的是距格林威治标准时间的毫秒值,两个值相减,就是时差.

 

 

//关于Activity.this getApplicationContext()的区别

Activity.this,是指当前activity的上下文
getApplicationContext()是整个APP的上下文
 
//启动邮箱

// 必须明确使用mailto前缀来修饰邮件地址,如果使用

// intent.putExtra(Intent.EXTRA_EMAIL, email),结果将匹配不到任何应用

//Uri uri =Uri.parse("mailto:3802**[email]419075656@qq.com[/email]");

Uri uri = Uri.parse("mailto:419075656@qq.com");

//String[] email ={"3802**[email]92@qq.com[/email]"};

Intent intent = newIntent(Intent.ACTION_SENDTO, uri);

//intent.putExtra(Intent.EXTRA_CC, email); //抄送人

intent.putExtra(Intent.EXTRA_SUBJECT,"请输入邮件的主题"); // 主题

intent.putExtra(Intent.EXTRA_TEXT, "请输入邮件的正文内容"); // 正文

startActivity(Intent.createChooser(intent,"请选择打开方式"));

 

//浏览器打开

Uri uri=Uri.parse("http://www.baidu.com/");

Intent it = newIntent(Intent.ACTION_VIEW,uri);

startActivity(it);

 

 

//自定义圆形imageView显示图片

 

 publicclass XCRoundImageViewextends  ImageView{

private Paintpaint ;

 public XCRoundImageView(Context context) {

 this(context,null); 

    }

publicXCRoundImageView(Context context, AttributeSet attrs) {

 this(context, attrs,0); 

    }

publicXCRoundImageView(Context context, AttributeSet attrs,int defStyle) {

super(context,attrs, defStyle);

        paint = newPaint();

    } /** * 绘制圆形图片

     * @authorcaizhiming */ @Overrideprotectedvoid onDraw(Canvas canvas) { 

        Drawable drawable =getDrawable(); if (null != drawable) { 

            Bitmap bitmap =((BitmapDrawable) drawable).getBitmap(); 

            Bitmap b = getCircleBitmap(bitmap, 14); finalRect rectSrc =new Rect(0, 0, b.getWidth(), b.getHeight());final Rect rectDest = newRect(0,0,getWidth(),getHeight());

            paint.reset(); 

            canvas.drawBitmap(b, rectSrc,rectDest, paint); 

        } else { super.onDraw(canvas); 

       

    } /** * 获取圆形图片方法

     * @param bitmap

     * @param pixels

     * @return Bitmap

     * @authorcaizhiming */private Bitmap getCircleBitmap(Bitmapbitmap,int pixels) { 

        Bitmap output =Bitmap.createBitmap(bitmap.getWidth(), 

                bitmap.getHeight(),Config.ARGB_8888); 

        Canvas canvas = newCanvas(output); finalint color = 0xff424242;final Rect rect = newRect(0, 0, bitmap.getWidth(),bitmap.getHeight()); 

        paint.setAntiAlias(true); 

        canvas.drawARGB(0, 0, 0, 0); 

        paint.setColor(color); int x =bitmap.getWidth();

        canvas.drawCircle(x / 2, x / 2, x / 2, paint); 

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 

        canvas.drawBitmap(bitmap, rect, rect,paint); return output; 

   

}

 

完成这个自定义类后,就可以使用这个类了,就是把这个当组件在布局中使用即可,比如:

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent" >   

 

<com.xc.xcskin.view.XCRoundImageView

android:id="@+id/roundImageView"

android:layout_centerInParent="true"

android:layout_width="200dp"

 android:layout_height="200dp"

 android:src="@drawable/roundimageview"

 />

</RelativeLayout>

 

 

android任务栈及启动模式

 

1.一个应用程序一般都是由多个activity组成的。
2.
任务栈(task stack)(别名back stack后退栈)记录存放用户开启的activity的。
3.
一个应用程序一被开启系统就给他分配一个任务栈,当所有的activity都退出的时候,任务栈就清空了。
4.
任务栈的id是一个integer的数据类型自增长的。
5.
android操作系统里面会存在多个任务栈,一个应用程序一个任务栈。
6.
桌面应用和一般的应用程序是一样的,任务栈的行为也是一样。
7.
默认情况下,关闭掉一个应用程序,清空了这个应用程序的任务栈。应用程序的进程还会保留。

为什么要引入任务栈的概念:
windows
可以通过点击任务栏切换任务
android
长按小房子切换任务

为了记录用户开启了那些activity,记录这些activity开启的先后顺序,google引入任务栈(task stack)概念,帮助维护好的用户体验。

activity的启动模式:

AndroidManifest.xml中对指定Activity配置:

<activity android:name=".MainActivity"
            android:launchMode="
singleInstance"
            >

1. standard   默认标准的启动模式,每次startActivity都是创建一个新的activity的实例。
             
适用于绝大大数情况
2. singleTop  
单一顶部,如果要开启的activity在任务栈的顶部已经存在,就不会创建新的实例,
             
而是调用onNewIntent()方法。
             
应用场景:浏览器书签。避免栈顶的activity被重复的创建,解决用户体验问题。
3. singletask
单一任务栈activity只会在任务栈里面存在一个实例。如果要激活的activity,在
             
任务栈里面已经存在,就不会创建新的activity,而是复用这个已经存在的activity
             
调用onNewIntent()方法,并且清空这个activity任务栈上面所有的activity
             
应用场景:浏览器activity整个任务栈只有一个实例,节约内存和cpu的目的
             
注意:activity还是运行在当前应用程序的任务栈里面的。不会创建新的任务栈。


4. singleInstance  
单态单例模式
             
单一实例,整个手机操作系统里面只有一个实例存在。不同的应用去打开这个activity
     
共享公用的同一个activity
             
他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。
             
应用场景:呼叫来电界面InCallScreen

 

 

android:background="?android:attr/listDivider"

间隔线以listview中间的divider方式显示

 

 

 

Android中判断字符串中必须包含字母或者数字

 
 

publicstatic boolean isLetterDigit(String str){

  booleanisDigit = false;//定义一个boolean值,用来表示是否包含数字

     booleanisLetter = false;//定义一个boolean值,用来表示是否包含字母

     for(inti=0 ; i

       if(Character.isDigit(str.charAt(i))){  //用char包装类中的判断数字的方法判断每一个字符

         isDigit= true;

       }

       if(Character.isLetter(str.charAt(i))){ //用char包装类中的判断字母的方法判断每一个字符

         isLetter= true;

       }

     }

     Stringregex = "^[a-zA-Z0-9]+$";

    booleanisRight = isDigit && isLetter&&str.matches(regex);

 returnisRight;

  

 }

 

 

 

Android中如何防止Toast重复弹出相同的信息?

 

   public void showToast(String text) { 

       if(mToast == null) { 

           mToast = Toast.makeText(MobileSendTopicActivity.this, text,Toast.LENGTH_SHORT); 

       } else { 

           mToast.setText(text);   

           mToast.setDuration(Toast.LENGTH_SHORT); 

       } 

       mToast.show(); 

   } 

     

   public void cancelToast() { 

           if (mToast != null) { 

                mToast.cancel(); 

           } 

       } 

     

   public void onBackPressed() { 

           cancelToast(); 

           super.onBackPressed(); 

       } 

 

 

获取Wifi配置(Android)生成二维码时需要的信息

WIFI:T:WPA;S:MM;P:123456;H:true;  (H:为隐藏SSID,可选)

WIFI:S:MM;T:nopass;P:123456;

{WIFI:T:WPA;S:mynetwork;P:mypass;;}

相关参数说明:

参数  例子 说明
T   WPA 认证类型: WEP 或WPA,‘nopass’ 代表无需认证
S   network 无线网络的 SSID. (例如 “ABCD”)
P   mypass  无线网络的密码,如果无需认证则忽略此项 (例如“pass”)
H   true    可选。针对隐藏了SSID的网络

 

 

 

 

android 复制文本内容到系统的粘贴板 

 ClipboardManagercmb = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
cbm.setText(et.getText().toString());

 

 

//

/** 
*
实现文本复制功能 
* add by wangqianzhou 

* @param content 
*/  
public static void copy(String content,Context context)  
{  
// 得到剪贴板管理器  
ClipboardManager cmb =(ClipboardManager)context.getSystemService(Context.CLIPBOARD_SERVICE);  

cmb.setText(content.trim());  
}  
/** 
* 实现粘贴功能 
* add by wangqianzhou 

* @param context 
* @return 
*/  
public static String paste(Contextcontext)  
{  
// 得到剪贴板管理器  
ClipboardManager cmb =(ClipboardManager)context.getSystemService(Context.CLIPBOARD_SERVICE);  

return cmb.getText().toString().trim();  
}  

 

 

Layout文件中设置TextView的属性

android:autoLink="email|phone|web"

这样Android就会自动识别邮件、电话号码、网址了,点击时会出发不同的Intent进行处理。

 

 

ImageViewgetDrawableCache获取背景图片的时候注意的问题

获取ImageView的背景图片使用getDrawableCache方法,不要使用getDrawable方法,后者获取不到图片的.

1.在调用imageView.getDrawableCache()之前一定要先调用imageView.setDrawingCacheEnabled(true)方法,否则会出现空指针异常

2.在使用getDrawableCache()方法获取Bitmap之后,一定要调用setDrawingCacheEnable(false)方法,以清除画图缓冲区,不然下一次获取的图片还是上一次的

 

 

生成二维码

 

publicclass EncodingHandler {
    private static final int BLACK =0xff000000;
    private static final int WHITE =0xFFFFFFFF;

    public static BitmapcreateQRCode(String str,int widthAndHeight) throws WriterException {
        Hashtable<EncodeHintType,String> hints = new Hashtable<EncodeHintType, String>();
       hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        BitMatrix matrix = newMultiFormatWriter().encode(str,
                BarcodeFormat.QR_CODE,widthAndHeight, widthAndHeight);
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        int[] pixels = new int[width *height];

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width;x++) {
                if (matrix.get(x, y)) {//有信息设置像素点为黑色
                    pixels[y * width + x]= BLACK;
                } else {
                    pixels[y * width + x]= WHITE;//无信息设置像素点为白色
                }
            }
        }
        Bitmap bitmap =Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        bitmap.setPixels(pixels, 0,width, 0, 0, width, height);
        return bitmap;
   }
}

 

保存二维码成图片到本地sd

publicvoid saveMyBitmap(Bitmap bitmap,String bitName) throws IOException {
    File f = newFile("/sdcard/" + bitName + ".jpg");
    f.createNewFile();
    FileOutputStream fOut = null;
    try {
        fOut = new FileOutputStream(f);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
   bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
    try {
        fOut.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        fOut.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    LoadingDialog.cancelLoading();
}

 

注意:在这里可能会遇到保存的二维码图片是全黑的问题。

原因是在源代码在生成二维码的时候,只是对有数据的地方使用了黑色填充,没有数据的地方没有处理,而bitmapcompressjpg/png的时候,默认背景是黑色的,所以就是全黑了。
解决办法是在生成二维码的时候讲没有数据的部分使用白色填充,就可以了。



//二维矩阵转为一维像素数组,也就是一直横着排了
           
int[] pixels = new int[width * height];
           for (int y = 0; y < height; y++) {
                        for (int x = 0; x < width; x++) {
                                         if (bitmapMatrix.get(x, y)) { //有信息设置像素点成黑色
            
pixels[y * width + x] = 0xff000000;
                             
  } else {                            
 //无信息设置像素点为白色
         
pixels[y * width + x] = 0xffffffff;
                      }
                                    }
                    }

 

 

 

/**

 *

 * 判断网络状态是否可用

 *

 * @return true: 网络可用 ; false: 网络不可用

 */

 

publicboolean isConnectInternet()

{

    ConnectivityManager conManager =(ConnectivityManager) test.this

           .getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo networkInfo =conManager.getActiveNetworkInfo();

    if (networkInfo == null ||!networkInfo.isConnected())

    {

        return false;

    }

    if (networkInfo.isConnected())

    {

        return true;

    }

    return false;

}

/*检查网络联机是否正常 */

publicboolean checkInternetConnection(String strURL, String strEncoding)

{

    /* 最多延时n秒若无响应则表示无法联机 */

    int intTimeout = 10;

    try

    {

        HttpURLConnection urlConnection = null;

        URL url = new URL(strURL);

        urlConnection = (HttpURLConnection)url.openConnection();

       urlConnection.setRequestMethod("GET");

        urlConnection.setDoOutput(true);

        urlConnection.setDoInput(true);

       urlConnection.setRequestProperty("User-Agent","Mozilla/4.0"

                + " (compatible; MSIE 6.0;Windows 2000)");

 

       urlConnection.setRequestProperty("Content-type",

                "text/html; charset="+ strEncoding);

        urlConnection.setConnectTimeout(1000 *intTimeout);

        urlConnection.connect();

        if (urlConnection.getResponseCode() ==200)

        {

            return true;

        }

        else

        {

            Log.d("getResponseCode=",urlConnection.getResponseMessage());

 

            return false;

        }

    }

    catch (Exception e)

    {

        e.printStackTrace();

        Log.d("emessage",e.getMessage());

        return false;

    }

}

 

/*自定义BIG5转UTF-8 */

publicString big52unicode(String strBIG5)

{

    String strReturn = "";

    try

    {

        strReturn = newString(strBIG5.getBytes("big5"), "UTF-8");

    }

    catch (Exception e)

    {

        e.printStackTrace();

    }

    return strReturn;

}

 

/*自定义UTF-8转BIG5 */

publicString unicode2big5(String strUTF8)

{

    String strReturn = "";

    try

    {

        strReturn = newString(strUTF8.getBytes("UTF-8"), "big5");

    }

    catch (Exception e)

    {

        e.printStackTrace();

    }

    return strReturn;

}

//该代码片段来自于:http://www.sharejs.com/codes/java/6854

 

 


Android wifi连接,怎么监控密码错误,正在连接,连接成功

mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);//信号强度变化
mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); //网络状态变化
mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); //wifi状态,是否连上,密码
mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);  //是不是正在获得IP地址
        mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
       mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);//连上与否
         用这些广播,你再看看广播的内容就搞得定了。

 

 

Can'tcreate handler inside thread that has not called Looper.prepare()类型的错误及修改方法

 

 

方法一,将对话框创建的地方放在 UiThread 中跑。

 

if(mNeedClearRotateDialog == null || !mNeedClearRotateDialog.isShowing()) {

                            mActivity.runOnUiThread(newRunnable() {

                                   public voidrun() {

                                          mNeedClearRotateDialog= builder.create();

                                   }

                            });

                     }

//------2

                     new Thread(new Runnable() {

                                  

                                   @Override

                                   public voidrun() {

                                          //TODO Auto-generated method stub

              //省略其他代码                     

Toast.makeText(getApplicationContext(),"", Toast.LENGTH_SHORT).show();

                                   }

                            });

 

把上面这行代码也通过处理放进handler之后,错误就没有了,虽然很简单,但是如果一味去找handlerLoop的问题,会走弯路。希望有所帮助。

 


 

控件旋转角度
android:rotation="180"

 

删除sd卡上文件  文件夹!!!!

File file = new File("/sdcard/text.txt");  

        File newFile = new File("/sdcard/text2.txt");  

        File path = new File("/sdcard/ck");  

        /* 删除文件及文件夹 */  

        if(file.exists()){  

            file.delete();  

        }  

        if(path.exists()){  

            path.delete();  

        }  

        /* 给文件重命名 */  

        if(file.exists()){  

            file.renameTo(newFile);  

        }  

 

 

 

1.两个日期是Date型

2.两个日期是String型,且月份与日期都是用双位数的表示形式(比如09/01)

 

直接用compareTo比较

1

2

3

4

5

String start = "2015/10/01";

String end = "2015/09/10";

if(start.compareTo(end)>0){

    //结束日期早于开始日期

}

 

3.日期是String,月份与日期是用单位数的表示形式

用SimpleDateFormat先根据格式转为Date,然后再用compareTo比较

   

String start = "2015/10/1";

String end = "2015/9/10";

         

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/M/d");

try {

    Date startDate = sdf.parse(start);

    Date endDate = sdf.parse(end);

    if(startDate.compareTo(endDate)>0){

        //结束日期早于开始日期

    }

} catch (ParseException e) {

     

}

 

 

检测两个日期间隔天数

public static int getGapCount(Date startDate, Date endDate) {
   
Calendar fromCalendar = Calendar.getInstance();
   
fromCalendar.setTime(startDate);
   
fromCalendar.set(Calendar.HOUR_OF_DAY, 0);
   
fromCalendar.set(Calendar.MINUTE, 0);
   
fromCalendar.set(Calendar.SECOND, 0);
   
fromCalendar.set(Calendar.MILLISECOND, 0);

   
Calendar toCalendar = Calendar.getInstance();
   
toCalendar.setTime(endDate);
   
toCalendar.set(Calendar.HOUR_OF_DAY, 0);
   
toCalendar.set(Calendar.MINUTE, 0);
   
toCalendar.set(Calendar.SECOND, 0);
   
toCalendar.set(Calendar.MILLISECOND, 0);

   
return (int) ((toCalendar.getTime().getTime() - fromCalendar.getTime().getTime()) / (1000 * 60 * 60 * 24));
}

 

 

 网络是否可用

      

       public static booleanisNetworkAvailable(Context context) {

              ConnectivityManager mgr =(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

              NetworkInfo[] info =mgr.getAllNetworkInfo();

          if (info != null) {

                for (int i = 0; i <info.length; i++) {

                       if (info[i].getState()== NetworkInfo.State.CONNECTED) {

                              return true;

                       }

                }

          }

              return false;

       }

 

 

 

设置四周边框

<?xmlversion="1.0"encoding="UTF-8"?>

<shapexmlns:android="http://schemas.android.com/apk/res/android">

   <solidandroid:color="#00000000"/>

   <strokeandroid:width="2dip"android:color="#ff000000" />

</shape>

 


只设置底部边框

<layer-listxmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the main color -->
<item>
  <shape>
        <solidandroid:color="#ffa8abad" />
  </shape>
</item>
<!-- This is the line -->
<item android:bottom="2dp">
 <shape>
       <solidandroid:color="#FFFFFF" />
 </shape>
</item>
</layer-list>

 

设置textview以及Edittextdrawable

Drawable drawable= mContext.getResources().getDrawable(R.drawable.ic_enter);
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
viewHolder.valueTv.setCompoundDrawables(null,null,drawable,null);

 

 

 

 

 

避免虚拟键盘弹出时顶部的自定义标题栏被顶上去,解决办法如下

1:给下面的布局加一个ScrollView
        (为避免布局错乱,给ScrollView加一个android:fillViewport="true"
2:manifest个activity加一个android:windowSoftInputMode="adjustResize"
然后在Activity里监听虚拟键盘弹出时,执行以下方法:
 
private void init() {
   
final ScrollView scrollView = (ScrollView) findViewById(R.id.scrollViewMain);
   
final View decorView = getWindow().getDecorView();
   
decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
       
@Override
       
public void onGlobalLayout() {
           
Rect r = new Rect();
           
decorView.getWindowVisibleDisplayFrame(r);
           
int screenHeight = decorView.getRootView().getHeight();
           
int heightDifference = screenHeight - r.bottom;
           
RelativeLayout.LayoutParams r1 = (RelativeLayout.LayoutParams) scrollView.getLayoutParams();
           
r1.setMargins(0, 0, 0, heightDifference);
           
scrollView.requestLayout();
       
}
   
});

}
 
 

 

动态设置margin

TextView ceshiTv = (TextView)findViewById(R.id.ceshi_tv);

        LinearLayout.LayoutParamslp = (LayoutParams) ceshiTv.getLayoutParams();

        lp.setMargins(30,50, 22, 10);

        ceshiTv.setLayoutParams(lp);

 

 

Androidstudio“importorg.apache.http.Header;”没用?

 

Android M 起默认移除了Apache HTTPhttps://developer.android.com/intl/zh-cn/preview/behavior-changes.html
要使用的话,要这么干
1
、在gradle-wrapper.properties中配置使用较新版本的gradle

distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-all.zip

2、在build.gradle中使用较新版本的gradle buildtools

buildscript {

    repositories {

        jcenter()

    }

    dependencies {

        classpath'com.android.tools.build:gradle:1.3.0'

 

        // NOTE: Donot place your application dependencies here; they belong

        // in theindividual module build.gradle files

    }

}

3、添加以下依赖,重新使用已经deprecatedapache http包:

android{

    useLibrary'org.apache.http.legacy'

}

4、添加apache http component的依赖,补全缺失的类,比如Header

dependencies{

    compile'org.apache.httpcomponents:httpcore:4.4.2'

}

 

 

监听drawableright的点击事件 +显示和隐藏密码 + 设置drawableRight!!

 

wifiPwdEt.setOnTouchListener(new View.OnTouchListener() {
               
@Override
               
public boolean onTouch(View v, MotionEvent event) {
                   
wifiPwdEt.getCompoundDrawables();
                   
//得到一个长度为4的数组,分别表示左右上下四张图片
                   
Drawable drawable = wifiPwdEt.getCompoundDrawables()[2]; //如果右边没有图片,不再处理
                   
if (drawable == null)
                       
return false; //如果不是按下事件,不再处理

                   
if (event.getAction() != MotionEvent.ACTION_UP)
                       
return false;
                   
if (event.getX() > wifiPwdEt.getWidth() - wifiPwdEt.getPaddingRight() - drawable.getIntrinsicWidth()) {
//                        wifiPwdEt.setText("ssssss");
                        if (isFirst) {
                           
MessageToast.showToast(mainActivity, "显示");
                           
wifiPwdEt.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
Drawable drawableRight = mainActivity.getResources().getDrawable(R.drawable.eye_visible);
drawableRight.setBounds(0, 0, drawableRight.getMinimumWidth(), drawableRight.getMinimumHeight());
wifiPwdEt.setCompoundDrawables(null, null, drawableRight, null);

                           
isFirst = false;
                       
} else {
                           
MessageToast.showToast(mainActivity, "隐藏");
                           
wifiPwdEt.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
Drawable drawableRight = mainActivity.getResources().getDrawable(R.drawable.eye_invisible);
drawableRight.setBounds(0, 0, drawableRight.getMinimumWidth(), drawableRight.getMinimumHeight());
wifiPwdEt.setCompoundDrawables(null, null, drawableRight, null);

                           
isFirst = true;
                       
}
                       
if (null != wifiPwdEt.getText().toString() && !"".equals(wifiPwdEt.getText().toString())) {
                           
wifiPwdEt.setSelection(wifiPwdEt.getText().toString().length());
                       
}

                   
}
                    return false;
               
}
           
});

 

et.setInputType(InputType.TYPE_CLASS_PHONE);//只能输入电话号码
et.
setInputType(InputType.TYPE_CLASS_NUMBER);//只能输入数字
et.
setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);//只能输入邮箱地址
et.
setInputType(InputType.TYPE_NULL); // 禁止输入(不弹出输入法)

 

 

list按照时间排列

ArrayList<Inbox> inboxList;(Inbox是范型

 

Collections.sort(inboxList, new Comparator<Inbox>() {
   
@Override
   
public int compare(Inbox inbox1, Inbox inbox2) {
       
Date date1 = stringToDate(inbox1.getMessageDate());
       
Date date2 = stringToDate(inbox2.getMessageDate());
       
// 对日期字段进行升序,如果欲降序可采用after方法
       
if (date1.before(date2)) {//before是指时间从最新时间下降到之前
           
return 1;
       
}
       
return -1;
   
}

})
;
public Date stringToDate(String dateString) {
   
ParsePosition position = new ParsePosition(0);
   
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
   
Date dateValue = simpleDateFormat.parse((19 + dateString), position);
   
return dateValue;
}

 

 

Android获取当前运行的类名或者方法名

 

public static String getCurrentMethodName() {

int level = 1;

StackTraceElement[] stacks = newThrowable().getStackTrace();

String methodName = stacks[level].getMethodName();

return methodName;

}

public static String getCurrentClassName() {

int level = 1;

StackTraceElement[] stacks = newThrowable().getStackTrace();

String className = stacks[level].getClassName();

return className;

}

 

 

// Android 的上下文菜单类似于 PC上的右键菜单。

registerForContextMenu(Listview);

当为一个视图注册了上下文菜单之后,长按(2秒左右)这个视图对象就会弹出一个浮动菜单,即上下文菜单。任何视图都可以注册上下文菜单,不过,最常见的是用于列表视图ListViewitem

下面是处理

    @SuppressWarnings("unused")
   
@Override
   
public void onCreateContextMenu(ContextMenu menu, View v,
                                   
ContextMenuInfo menuInfo) {
       
if (v.getId() == R.id.messagesList) {
           
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
           
String[] menuItems = getResources().getStringArray(
                   
R.array.messagesContextMenu);
           
for (int i = 0; i < menuItems.length; i++) {
               
menu.add(Menu.NONE, i, i, menuItems[i]);
           
}
       
}
    }

    @Override
   
public boolean onContextItemSelected(MenuItem item) {
       
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
                .getMenuInfo();
       
selectedDeleteItem = info.position;
       
Log.i("Selected Delete Item", "" + selectedDeleteItem);
//        BaseRequests.checkValid(mainActivity, this);
        deleteMessage();
       
return true;
    }

 

 

 

android:textIsSelectable="true"         //文本是否可以复制
android:autoLink="email|phone|web"   //以链接的方式显示出来,邮件、电话号码、网址

 

 

 

模糊搜索

private void searchMsg(String msg) {

   
if (msg.equals("")) {
       
msgInboxAdapter = new ListAdapter(mainActivity, this, msgInboxModel);
       
msgInboxLv.setAdapter(msgInboxAdapter);
   
} else {
       
searchSmsModel.clear();
       
for (ListModel item : msgInboxModel) {
           
String date =  item.getMsgTime();//((MessageModel) item.getCustomObject()).getDate();// "20" +

           
if (item.getMsgPhoneNum().toLowerCase()
                   
.contains(msg.toLowerCase())
                    || item.getMsgHead().toLowerCase()
                    .contains(msg.toLowerCase())
                    || (date.contains(msg.toLowerCase()))) {
                searchSmsModel.add(item);
           
}
           
msgInboxAdapter = new ListAdapter(mainActivity, this, searchSmsModel);
           
msgInboxLv.setAdapter(msgInboxAdapter);
       
}
   
}
}

 

 

1.   String mtype = android.os.Build.MODEL; // 手机型号  

2.          String mtyb= android.os.Build.BRAND;//手机品牌  

3.  android.os.Build.VERSION.RELEASE获取版本号

 

 

 

 

 

监听屏幕上下左右滑动

@Override
public boolean onTouchEvent(MotionEvent event) {
   
//继承了ActivityonTouchEvent方法,直接监听点击事件
   
if(event.getAction() == MotionEvent.ACTION_DOWN) {
       
//当手指按下的时候
       
x1 = event.getX();
       
y1 = event.getY();
   
}
   
if(event.getAction() == MotionEvent.ACTION_UP) {
       
//当手指离开的时候
       
x2 = event.getX();
       
y2 = event.getY();
       
if(y1 - y2 > 50) {
           
Toast.makeText(MainActivity.this, "向上滑", Toast.LENGTH_SHORT).show();
       
} else if(y2 - y1 > 50) {
           
Toast.makeText(MainActivity.this, "向下滑", Toast.LENGTH_SHORT).show();
       
} else if(x1 - x2 > 50) {
           
Toast.makeText(MainActivity.this, "向左滑", Toast.LENGTH_SHORT).show();
       
} else if(x2 - x1 > 50) {
           
Toast.makeText(MainActivity.this, "向右滑", Toast.LENGTH_SHORT).show();
       
}
   
}
    return super.onTouchEvent(event);
}

 

 

textView多字文本android:ellipsize不正常工作的解决办法

可以设置singleLine="true"解决问题,然而这个方法已经被废弃了不推荐使用,我们可以简单实现和singleLine相同的效果(红字部分)

正常工作的解决办法如下

android:ellipsize="end" 
android:lines="1"
android:scrollHorizontally="true"

 

 

 

 

 

 

JSON解析之 getJSONObject 与 optJSONObject 的区别

 

 

//optJSONObject源码解析:    

     /**

     *Returns the value mapped by {@code name} if it exists and is a {@code

     *JSONObject}. Returns null otherwise.

     */

    public JSONObject optJSONObject(String name) {

        Objectobject = opt(name);

        return object instanceof JSONObject ? (JSONObject) object: null;

    }

    //当返回值不是JSONObject对象时,返回值为null,不抛出异常;

 

 

//getJSONObject源码解析:

     /**

     *Returns the value mapped by {@code name} if it exists and is a {@code

     *JSONObject}.

     *@throws JSONException if the mapping doesn't exist or is not a {@code

     *JSONObject}.

     */

    public JSONObject getJSONObject(String name) throws JSONException {

        Objectobject = get(name);

        if (object instanceof JSONObject) {

            return (JSONObject) object;

        }else {

            throw JSON.typeMismatch(name, object, "JSONObject");

        }

    }

    //当返回值不是JSONObject对象时,抛出异常;

 

 

android TextView可滚动

 

在xml里面写上:

  android:maxLines="5"  
        android:singleLine="false"
        android:scrollbars="vertical"  

 

在java里写:

textView.setMovementMethod(ScrollingMovementMethod.getInstance()); 

 

 

 

 

Android 闪烁显示文字

 

public void spark() {
       
Timer timer = new Timer();
       
TimerTask taskcc = new TimerTask() {
           
public void run() {
               
mainActivity.runOnUiThread(new Runnable() {
                   
public void run() {
                       
if (int clo == 0) {
                           
clo = 1;
                           
toLoginTv.setTextColor(Color.GRAY);
                       
} else {
     
                      if (clo == 1) {
//                                clo = 2;
                                toLoginTv.setTextColor(Color.RED);
//                                toLoginTv.setTextColor(Color.YELLOW);
                            }
//                            else if (clo == 2) {
//
//                                clo = 3;
//                                toLoginTv.setTextColor(Color.RED);
//
//                            } else {
//                                clo = 0;
//                                toLoginTv.setTextColor(Color.BLUE);
//                            }
                        }
                   
}
                });
           
}
       
};
       
timer.schedule(taskcc, 0);

   
}

 

 

 

 

 

将数组里的数字按照最大-最小-次大-次小的顺序排列

 

public static void main(String[] args) {

        int array[] = new int[] { 98, 56, 48, 65, 42, 99, 88, 100, 25, 12 };

        arr(array);

    }

    private static void arr(int[] array) {// 从大到小排序

        int min[] = new int[array.length];

        for (int i = 0; i < array.length; i++) {

            for (int j = i + 1; j < array.length; j++) {

                if (array[i] < array[j]) {

                    int temp = array[i];

                    array[i] = array[j];

                    array[j] = temp;

                }

            }

        }

        for (int i = 0, j = array.length - 1; i < array.length; i++, j--) {// 从小到大

            min[i] = array[j];

        }

        if (array.length % 2 == 0) {// 判断最后是否落单,然后折中输出

            for (int i = 0; i < array.length / 2; i++) {

                System.out.print(array[i] + " " + min[i] + " ");

            }

        } else {

            for (int i = 0; i <= array.length / 2; i++) {

                if (i == array.length / 2) {

                    System.out.println(array[i]);

                    continue;

                    //break;

                } else

                    System.out.print(array[i] + " " + min[i] + " ");

            }

        }

    }

    监听popupWindow,是否弹出了

 

 

控制线性布局权重的总和!


android:weightSum="7"

 

 

 

 

 

 

 

 

 

 

//检测手机是否具有虚拟导航键,虚拟返回键、Home键、菜单键

 

@SuppressLint("NewApi")
public  boolean checkDeviceHasNavigationBar(Context activity) {

   
//通过判断设备是否有返回键、菜单键(不是虚拟键,是手机屏幕外的按键,物理按键)来确定是否有navigation bar
   
boolean hasMenuKey = ViewConfiguration.get(activity)
           
.hasPermanentMenuKey();
   
boolean hasBackKey = KeyCharacterMap
           
.deviceHasKey(KeyEvent.KEYCODE_BACK);

   
if (!hasMenuKey && !hasBackKey) {
       
// 做任何你需要做的,这个设备有一个虚拟导航栏
       
Resources resources = activity.getResources();
 
      int resourceId = resources.getIdentifier("navigation_bar_height","dimen", "android");
       
int height = resources.getDimensionPixelSize(resourceId);
       
Log.i("NavigationBarheight", "Navi height:" + height);

       
Toast.makeText(activity, "这个设备有一个虚拟导航栏,高度:" + height, Toast.LENGTH_SHORT).show();
       
return true;
    }
   
return false;
}
 
 
 
//获取屏幕分辨率,如果有虚拟按键,分辨率高度会减少!
//例如1920x1080的机器,如果有虚拟按键,高度假设为144,则获取到的分辨率是1776x1080
private void getScreen() {
   
screenWidth  = getWindowManager().getDefaultDisplay().getWidth();
   
screenHeight = getWindowManager().getDefaultDisplay().getHeight();
   
Log.i("NavigationBarheight", screenWidth + "左边是宽度------右边是高度" + screenHeight);

}
 

 

 

//MD5加密

 


public String pwdToMd5(String string) {

   
byte[] hash;

   
try {
       
hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
   
} catch (NoSuchAlgorithmException e) {
       
throw new RuntimeException("Huh, MD5 should be supported?", e);
   
} catch (UnsupportedEncodingException e) {
       
throw new RuntimeException("Huh, UTF-8 should be supported?", e);
   
}

   
StringBuilder hex = new StringBuilder(hash.length * 2);

   
for (byte b : hash) {
       
int i = (b & 0xFF);
       
if (i < 0x10) hex.append('0');
       
hex.append(Integer.toHexString(i));
   
}

   
return hex.toString();
}
 
 

 

//监听屏幕虚拟导航栏(navigationbar)出现或隐藏。

 

mainxml文件
 
main.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
           
@Override
           
public void onSystemUiVisibilityChange(int visibility) {
//                Toast.makeText(MainActivity.this, "测试导航栏", Toast.LENGTH_SHORT).show();
               
if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {

                   
Toast.makeText(MainActivity.this, "导航栏出现 !", Toast.LENGTH_LONG).show();
               
} else {
                   
Toast.makeText(MainActivity.this, "导航栏被隐藏掉了...........", Toast.LENGTH_LONG).show();
               
}
           
}
        });
 
 
上面的visible可以用view.getSystemUiVisibility()这个代替,就是当前界面的xml. getSystemUiVisibility()
 
 
 

 

发送和接收广播:

 
发送方
public static final String action = "jason.broadcast.action";
 
发送
Intent intent =
new Intent(action);
intent.putExtra("data", "closeActivity");
sendBroadcast(intent);
 
接收方:
 
//注册广播:

IntentFilter filter =
new IntentFilter(UnlockSimCardActivity.action);
registerReceiver(broadcastReceiver, filter)//注册广播
 
 
//onDestroy() 时,一定要注销广播

unregisterReceiver(
broadcastReceiver);//注销广播
 
 

//广播
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

   
@Override
   
public void onReceive(Context context, Intent intent) {
       
// TODO Auto-generated method stub
//做接收到广播时的操作!
        if(intent.getStringExtra("data").equals("closeActivity")){
           
finish();
       
}
   
}
};
 
 

 

//强制虚拟隐藏导航栏

 
if (Build.VERSION.SDK_INT > 14) {
           
View decorView = getWindow().getDecorView();
           
// Hide both the navigation bar and the status bar.
           
// SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as
            // a general rule, you should design your app to hide the status bar whenever you
            // hide the navigation bar.
            int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
//                    | View.SYSTEM_UI_FLAG_FULLSCREEN;//
            decorView.setSystemUiVisibility(uiOptions);
       
}
 
 

 

 

//注册长按弹出列表

 
registerForContextMenu(actualListView);
---以下是源码:
public void registerForContextMenu(View view) {
   
view.setOnCreateContextMenuListener(this);
}
 
 
  @Override
   
public void onCreateContextMenu(ContextMenu menu, View v,
                                   
ContextMenu.ContextMenuInfo menuInfo) {
//        if (v.getId() == R.id.pullListview) {//
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
       
selectedDeleteItem = info.position - 1;
       
String[] menuItems = getResources().getStringArray(
             
  R.array.messagesLongClickMenu);
       
for (int i = 0; i < menuItems.length; i++) {
           
menu.add(Menu.NONE, i, i, menuItems[i]);//
       
}
//        public MenuItem add(int groupId, int itemId, int order, CharSequence title);//源码
//        menu.add(0, 1, Menu.NONE, getResources().getString(R.string.delete_msg));
//        menu.add(0, 2, Menu.NONE, getResources().getString(R.string.delete_all_msg));
        Log.i(TAG, "Selected Delete Item position:   " + selectedDeleteItem + "---menu.size()  :" + menu.size());
       
super.onCreateContextMenu(menu, v, menuInfo);
   
}

   
@Override
   
public boolean onContextItemSelected(MenuItem item) {
       
int itemId = item.getItemId();
       
Log.i(TAG, "itemId:   " + itemId );
   
    if (itemId == 0) {//根据itemId的不同,执行不同操作
           

       
} else {
           

       
}
       
return true;//super.onContextItemSelected(item);
   
}
 
 
 

 

gradle project syncfailedPlease fix your project and try again

 

我是通过android studio下,点击 tools ->Android->sync project with gradles files.解决这个问题的。

 

 

Android Studio勾选后实现自动导包,和自动删除无用的导包-import

 

 

Android开发——遍历读写U盘、SD卡等外部存储

1.首先需要得到挂载在手机上的有哪些盘符

        String[] result = null;

        StorageManager storageManager =(StorageManager)getSystemService(Context.STORAGE_SERVICE);

        try {

            Method method =StorageManager.class.getMethod("getVolumePaths");

            method.setAccessible(true);

            try {

                result=(String[])method.invoke(storageManager);

            } catch (InvocationTargetExceptione) {

                e.printStackTrace();

            }

            for (int i = 0; i <result.length; i++) {

                System.out.println("path---->" + result[i]+"\n");

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

 

这里需要用到一个被系统隐藏的方法,即StorageManager下的getVolumePaths()方法。具体通过反射得到。方法返回值为字符串数组,在我的真机上可以获得三个盘符:sdcard0 sdcard1 usbdisk。

2.拿到上面的根目录路径之后,即可运用listFiles()方法遍历所有的文件

        private void getAllFiles(Filepath){ 

        File files[] = path.listFiles(); 

        if(files != null){ 

            for (File f : files){ 

                if(f.isDirectory()){ 

                    getAllFiles(f); 

                }else{ 

                    System.out.println(f); 

                } 

            } 

        } 

    } 

这样就完成了所有文件的遍历,如果需要读写,通过指定路径拿到File对象实例,再操作文件流即可。

这里需要说明的是,手机如果想读写USB,本身需要支持USB-OTG功能。该功能除了支持U盘,还支持外接鼠标,键盘,游戏手柄,移动硬盘(需要更大电压)等。

从硬件上说,Android4.0或以上系统的智能手机芯片都支持USB-OTG了,如果不支持的话,可能是以下两个原因。   

1、硬件上缺少5V升压器,外接设备没有电压供应。 

2、硬件设备制造商为了省电考虑,从系统上屏蔽了USB-OTG功能。

解决系统屏蔽OTG问题,网上的方法是(没有测试过):

1.ROOT后打开RE管理器,编辑system/etc/vold.fstab文件,在vold.fstab的末尾添加如下代码
# usb otg diskdev_mount usbotg /mnt/usbotg auto /devices/platform/mt_usb/devices/platform/musbfsh_hdrc
2.修改保存,重启手机

3.Android6.0亲测利用反射获取不到U盘的挂载路径,Google了一下发现默认挂载在了/mnt/media_rw/<随机的ID值>

在ADB Shell里可以正常访问,需要Root权限。

 

4.获取手机本身内存路径


File root = Environment.getExternalStorageDirectory()
;

 

 

 

 

okhttp异常:java.lang.IllegalStateException: closed

09-05 14:42:17.606: E/AndroidRuntime(28219): Caused by: java.lang.IllegalStateException: closed
09-05 14:42:17.606: E/AndroidRuntime(28219):    at okhttp3.internal.http.Http1xStream$ChunkedSource.read(Http1xStream.java:414)
09-05 14:42:17.606: E/AndroidRuntime(28219):    at okio.Buffer.writeAll(Buffer.java:993)
09-05 14:42:17.606: E/AndroidRuntime(28219):    at okio.RealBufferedSource.readByteArray(RealBufferedSource.java:106)
09-05 14:42:17.606: E/AndroidRuntime(28219):    at okhttp3.ResponseBody.bytes(ResponseBody.java:128)
09-05 14:42:17.606: E/AndroidRuntime(28219):    at okhttp3.ResponseBody.string(ResponseBody.java:154)
09-05 14:42:17.606: E/AndroidRuntime(28219):    ... 4 more

 

这个错误是由于response.body().string()调用了多次导致的,string()仅可调用一次。

 

 

 

 

Android自用-----WindowManager$BadTokenException: Unable to add window-- token null is not for an application

错误产生:

1.   private Context mcontext;   

2.     

3.       @Override  

4.       protected void onCreate(Bundle savedInstanceState) {mcontext = getApplicationContext();  

5.           System.out.println("mcontext=" + mcontext);   

6.     

7.       }  

1.   new AlertDialog.Builder(mcontext)   

2.               .setIcon(android.R.drawable.ic_dialog_alert)  

3.               .setTitle("Warnning")   

4.               .setMessage(  

5.                       "You forget to write the message. Do you want to fill out it ??")   

6.               .setPositiveButton("Yes", positiveListener).setNegativeButton(  

7.                       "No", negativeListener).create().show();  

致报这个错是在于new AlertDialog.Builder(mcontext),虽然这里的参数是AlertDialog.Builder(Context context)但我们不能使用getApplicationContext()获得的Context,而必须使用Activity,因为只有一个 Activity才能添加一个窗体。 

解决方法:将new AlertDialog.Builder(Context context)中的参数用Activity.thisActivity是你的Activity的名称)来填充就可以正确的创建一个Dialog了。

1.   new AlertDialog.Builder(MyActivity.this)   

2.                   .setIcon(android.R.drawable.ic_dialog_alert)  

3.                   .setTitle("Warnning")   

4.                   .setMessage(  

5.                           "You forget to write the message. Do you want to fill out it ??")   

6.                   .setPositiveButton("Yes", positiveListener).setNegativeButton(  

7.                           "No", negativeListener).create().show();  

 

 

Android View not attached to window manager错误的解决办法

  //判断当前activity是否存在!

//Dismiss the Dialog only when the parent Activity isstill alive.
               if(SelectContactsActivity!=null&&!SelectContactsActivity.this.isFinishing()){
                  mProgressDialog.dismiss();
               }

 

 

Error:(2, 0) Plugin with id'com.github.dcendents.android-maven' not found

挺郁闷的,不知道是个什么东西

上网找了各种方案,终于一步一步慢慢解决了

首先在Project下那个build.grade里面添加全局依赖

buildscript {

    repositories {

        jcenter()

    }

    dependencies {

        classpath 'com.android.tools.build:gradle:1.5.0'

        //1.自动化maven打包插件

            classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'

        //2.自动上传至Bintray平台插件

        classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0"

        // NOTE: Do notplace your application dependencies here; they belong

        // in the individual modulebuild.gradle files

    }

}

 

按顺序来,先添加

classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'

添加完之后同步(Rebuild project)下,AndroidStudio下面的Event Log会出现com.jfrog.bintraynot found的错误提示,maven那个错误提示已经没有了

这时候再添加

classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0"

点同步,等待同步完成,时间略长

 

Glide加载gif图片

  1. Glide.with(MainActivity.this).load(url).asGif().diskCacheStrategy(DiskCacheStrategy.SOURCE).into(imageView);  
  2. 为其添加缓存策略,其中缓存策略可以为:Source及None,None及为不缓存,Source缓存原型.如果为ALL和Result就不行 

Android Studio2.2导入工程出现UnsupportedMethodException

 

最近升级到Android Studio2.2,导入工程后,发现报入后报以下错误,

Unsupported method:AndroidProject.getPluginGeneration().

The version of Gradle you connect to does notsupport that method.

To resolve the problem you can change/upgradethe target version of Gradle you connect to.

Alternatively, you can ignore this exceptionand read other information from the model.

  解决方案:

       Android Studio 检查Instant Run是否可用时会出现这个问题,禁用InstantRun可以解决这个问题。
      File -> Settings -> Build, Execution, Deployment-> Instant Run.

 

打开Androidstudio到欢迎界面,不是直接打开最后一个项目

 

 

if和assert的区别

assert

断言(assert)的语义如下:

       如果表达式的值为0(假),则输出错误消息并终止程序的执行(一般还会出现提示对话框,说明在什么地方引发了assert);如果表达式为真,则不进行任何操作。因此断言失败就表明程序存在一个bug。

     使用assert的目的是捕捉在运行时不应该发生的非法情况

if

语义:

        如果表达式的值为真,则执行其后的语句,否则不执行该语句。语句可以是单条语句,也可以是用花括号{}包括起来的复合语句。

        使用if语句的目的是对于条件判断,满足条件则执行其后的语句,不满足则不执行该语句

区别:

 1. assert语句仅仅在debug版本中才有效,而在release版本中无效;

       if(NULL!=p)是在Release版本中检验指针的有效性;

   2. assert一般用与检查函数参数的合法性(有效性)而不是正确性,但是合法的程序并不见得就是正确的程序。

   3. if语句,简单地说就是“漏斗”,满足条件就进入,不满足则不进入。而assert仿佛就是“城门守卫”,满足条件就是进入城内(这里就是接下来的程序),不满足就阻止进入(程序中断);

  4.assert这个宏只是帮助我们调试代码的,它的作用是:让用户在调试函数的时候把错误排除掉,而不是等待Release之后。assert可以帮助定位错误,而不是排除错误;

一般用与检查函数参数的合法性(有效性)而不是正确性,但是合法的程序并不见得

就是正确的程序。

 

 

Android AndroidManifest.xml文件的android:supportsRtl属性详解

声明你的application是否愿意支持从右到左(原来RTL就是right-to-left 的缩写...)的布局。

 

 

 

 

 

导入到AndroidStudio的时候提示MainActivity非法字符: '\ufeff'解决方案,细细一想编译器没报错,但编译出错,应该是隐蔽字符BOM的问题,于是在资源管理器定位到该文件,用Notepad++打开,果然原创作者没用采用(UTF-8 无BOM)模式。

我们只需要点击把它转为UTF-8无BOM格式编码即可。

PS:Eclipse可以智能的把有BOM文件转为无BOM文件,目前AndoridStudio木有这个功能,各位筒子需手动完成。

右键另存为(选择UTF-8 无BOM)即可!

 

 

 

判断当前界面是否在前台,在前台,则显示登出对话框,不在前台则不显示

 

/**
 
* 判断当前界面是否在前台,在前台,则显示登出对话框,不在前台则不显示
 
*
 
* @param context
 
* @param className 某个界面名称
 
*/
private boolean isForeground(Context context, String className) {
   
if (context == null || TextUtils.isEmpty(className)) {
       
return false;
   
}

   
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
   
List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(1);
   
if (list != null && list.size() > 0) {
 
      ComponentName cpn = list.get(0).topActivity;
       
if (className.equals(cpn.getClassName())) {
           
return true;
       
}
   
}
    return false;
}

 

 

 

FloatMath.sqrt android6.0 23报错

APP升级到6.0以后:

  compileSdkVersion 23
  buildToolsVersion "23.0.1"

出现错误

该方法在api23上已经废弃

经查询使用(float)Math.sqrt替换 FloatMath.sqrt

 

 

android.database.sqlite.SQLiteException:table has no column XXX (code 1)问题解决方法

今天在用到SQLite数据库的时候,老是出现这个出现这个错误:

android.database.sqlite.SQLiteException: tablehas no column named (code 1),找了半天也没找到解决方法。是什么原因造成这个错误呢:

其实是修改了在创建表的内容,你只要升级数据库版本或者卸载当前的应用,然后在运行加载,就不会报这个错误了。

 

 

Androidstudio 9图不能识别报错的问题

要保证.9图片四边都被切割过才可以

或者在build文件里的buildtools下加入

    //关闭Android StudioPNG合法性检查
//    aaptOptions.cruncherEnabled = false
//    aaptOptions.useNewCruncher = false

 

 

 

// 根据屏幕宽度动态设置图片宽高

在适配器里这样设置参数后         

int width = MeasureUtils.getWidth(UiUtils.getContext());

int imageWidth = (width / 3 - 40);

holder.image.setLayoutParams(new LayoutParams(imageWidth, imageWidth));

 

 /**

     * 获取屏幕宽

     */

   publicstaticintgetWidth(Context context){ 

        WindowManager wm=(WindowManager)context.getSystemService(Context.WINDOW_SERVICE); 

        DisplayMetrics outMetrics =new DisplayMetrics(); 

       wm.getDefaultDisplay().getMetrics(outMetrics); 

        return outMetrics.widthPixels

   

      

   /**

     * 获取屏幕高

     */

   publicstaticintgetHeight(Context context){ 

        WindowManager wm=(WindowManager)context.getSystemService(Context.WINDOW_SERVICE); 

        DisplayMetrics outMetrics =new DisplayMetrics(); 

       wm.getDefaultDisplay().getMetrics(outMetrics); 

        return outMetrics.heightPixels

   }

    /**判断软键盘是否弹起 */

   publicstaticboolean isKeyboardShown(ViewrootView) {

         finalint softKeyboardHeight = 100;

        Rect r = new Rect();

        rootView.getWindowVisibleDisplayFrame(r);

         DisplayMetrics dm =rootView.getResources().getDisplayMetrics();

         int heightDiff = rootView.getBottom() - r.bottom;

         return heightDiff > softKeyboardHeight* dm.density;

   }

  

   /**隐藏软件盘 */

   publicstaticvoid hideKeyboard(Contextcontext, IBinder token) {

         if (token !=null) {

             InputMethodManager im =(InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

             im.hideSoftInputFromWindow(token,InputMethodManager.HIDE_NOT_ALWAYS);

         }

   }

  

   /** Dip Px */

   publicstaticint dip2px(int dip){

      float d =getResources().getDisplayMetrics().density;

      return (int)(dip * d + 0.5);

   }

  

   /** Px Dip */

   publicstaticint px2dip(int px){

      float d =getResources().getDisplayMetrics().density;

      return (int)(px / d + 0.5);

   }

 

/** 获取主线程对象 */

   publicstatic Thread getMainThread(){

      returnmMainThread= Thread.currentThread();;

   }

 

   /**获取主线程ID */

   publicstaticint getMainThreadId() {

      returnmMainThreadId= android.os.Process.myTid();

   }

 

 

 

 

RecyclerView  监听RecyclerView  滑动到底部

 


      
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
           
@Override
           
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
               
super.onScrollStateChanged(recyclerView, newState);
               
/**
                
* 这个方法,当最后一个item显示出来的时候,就会触发,即便没有拉到底
                
*/
               
//当前RecyclerView显示出来的最后一个的itemposition
               
int lastPosition = -1;

               
//当前状态为停止滑动状态SCROLL_STATE_IDLE
               
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                   
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                   
if (layoutManager instanceof GridLayoutManager) {
                       
//通过LayoutManager找到当前显示的最后的itemposition
                       
lastPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
                   
} else if (layoutManager instanceof LinearLayoutManager) {
                       
lastPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
 
                  } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                       
//因为StaggeredGridLayoutManager的特殊性可能导致最后显示的item存在多个,所以这里取到的是一个数组
                       
//得到这个数组后再取到数组中position值最大的那个就是最后显示的position值了
           
            int[] lastPositions = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
                       
((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(lastPositions);
                       
lastPosition = findMax(lastPositions);
                   
}

                   
//时判断界面显示的最后itemposition是否等于itemCount总数-1也就是最后一个itemposition
                   
//如果相等则说明已经滑动到最后了
                   
if (lastPosition == recyclerView.getLayoutManager().getItemCount() - 1) {
//                        Toast.makeText(WaterfallWallActivity.this, "滑动到底了", Toast.LENGTH_SHORT).show();

                   
}
               
}


            }

            @Override
           
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
               
super.onScrolled(recyclerView, dx, dy);

               
/**
                
*这个方法,当最后一个item显示出来的时候,不会触发,只有拉到底才会触发
                
*/

//               当最后一个item刚显示出来的时候停止滑动这个时候也会触发滑动到底部的操作,
//               有时候我们可能并不希望这,希望当Recyclerview确实是滑动到底部滑动不了的时候才触发

               
//得到当前显示的最后一个itemview
               
View lastChildView = recyclerView.getLayoutManager().getChildAt(recyclerView.getLayoutManager().getChildCount() - 1);
               
//得到lastChildViewbottom坐标值
               
int lastChildBottom = lastChildView.getBottom();
               
//得到Recyclerview的底部坐标减去底部padding值,也就是显示内容最底部的坐标
               
int recyclerBottom = recyclerView.getBottom() - recyclerView.getPaddingBottom();
               
//通过这个lastChildView得到这个view当前的position
               
int lastPosition = recyclerView.getLayoutManager().getPosition(lastChildView);

               
//判断lastChildViewbottom值跟recyclerBottom
               
//判断lastPosition是不是最后一个position
               
//如果两个条件都满足则说明是真正的滑动到了底部
               
if (lastChildBottom == recyclerBottom && lastPosition == recyclerView.getLayoutManager().getItemCount() - 1) {
                   
Toast.makeText(WaterfallWallActivity.this, "滑动到底了", Toast.LENGTH_SHORT).show();
               
}

           
}
        });