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();
}
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);
一、Activity和Task(栈)的关系
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>
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进行处理。
ImageView的getDrawableCache获取背景图片的时候注意的问题
获取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();
}
注意:在这里可能会遇到“保存的二维码图片是全黑”的问题。
原因是在源代码在生成二维码的时候,只是对有数据的地方使用了黑色填充,没有数据的地方没有处理,而bitmap在compress成jpg/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之后,错误就没有了,虽然很简单,但是如果一味去找handler和Loop的问题,会走弯路。希望有所帮助。
控件旋转角度
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以及Edittext的drawable
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 HTTP:https://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、添加以下依赖,重新使用已经deprecated的apache 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秒左右)这个视图对象就会弹出一个浮动菜单,即上下文菜单。任何视图都可以注册上下文菜单,不过,最常见的是用于列表视图ListView的item。
下面是处理
@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) {
//继承了Activity的onTouchEvent方法,直接监听点击事件
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对象时,抛出异常;
在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)出现或隐藏。
main是xml文件
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
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-
0514
:
42:
17.606: E/AndroidRuntime(
28219): Caused by: java.lang.IllegalStateException: closed
09-
0514
:
42:
17.606: E/AndroidRuntime(
28219): at okhttp3.internal.http.Http1xStream$ChunkedSource.read(Http1xStream.java:
414)
09-
0514
:
42:
17.606: E/AndroidRuntime(
28219): at okio.Buffer.writeAll(Buffer.java:
993)
09-
0514
:
42:
17.606: E/AndroidRuntime(
28219): at okio.RealBufferedSource.readByteArray(RealBufferedSource.java:
106)
09-
0514
:
42:
17.606: E/AndroidRuntime(
28219): at okhttp3.ResponseBody.bytes(ResponseBody.java:
128)
09-
0514
:
42:
17.606: E/AndroidRuntime(
28219): at okhttp3.ResponseBody.string(ResponseBody.java:
154)
09-
0514
:
42:
17.606: E/AndroidRuntime(
28219): ...
4more
这个错误是由于response.body().string()
调用了多次导致的,string()
仅可调用一次。
错误产生:
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.this(Activity是你的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图片
- Glide.with(MainActivity.this).load(url).asGif().diskCacheStrategy(DiskCacheStrategy.SOURCE).into(imageView);
- 为其添加缓存策略,其中缓存策略可以为: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 Studio的PNG合法性检查
// 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显示出来的最后一个的item的position
int lastPosition = -1;
//当前状态为停止滑动状态SCROLL_STATE_IDLE时
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
//通过LayoutManager找到当前显示的最后的item的position
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);
}
//时判断界面显示的最后item的position是否等于itemCount总数-1也就是最后一个item的position
//如果相等则说明已经滑动到最后了
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确实是滑动到底部滑动不了的时候才触发
//得到当前显示的最后一个item的view
View lastChildView = recyclerView.getLayoutManager().getChildAt(recyclerView.getLayoutManager().getChildCount() - 1);
//得到lastChildView的bottom坐标值
int lastChildBottom = lastChildView.getBottom();
//得到Recyclerview的底部坐标减去底部padding值,也就是显示内容最底部的坐标
int recyclerBottom = recyclerView.getBottom() - recyclerView.getPaddingBottom();
//通过这个lastChildView得到这个view当前的position值
int lastPosition = recyclerView.getLayoutManager().getPosition(lastChildView);
//判断lastChildView的bottom值跟recyclerBottom
//判断lastPosition是不是最后一个position
//如果两个条件都满足则说明是真正的滑动到了底部
if (lastChildBottom == recyclerBottom && lastPosition == recyclerView.getLayoutManager().getItemCount() - 1) {
Toast.makeText(WaterfallWallActivity.this, "滑动到底了", Toast.LENGTH_SHORT).show();
}
}
});