android - 常用知识点以及代码片段(不断更新)

获取LayoutInflater对象三种方法:

1、LayoutInflater  inflater=getLayoutInflater();
2、LayoutInflater inflater=(LayoutInflater)mContext.getSystemServic(LAYOUT_INFLATER_SERVICE);
3、LayoutInflater inflater=LayoutInflater.from(context); //这种方法在重写BaseAdapter时常用




如果要用ListActivity,则 Activity的Layout文件中必须包括一个(只能一个)ListView,且ListView的id= "@id/android:list"。(继承ListActivity时)

margin:外边距
padding:内边距
像素/1.5等于dip

EditText属性之一:android:background="@android:drawable/editbox_background"

当LinearLayout 是horizontal ,并且里面的控件使用了layout_width="fill_parent" ,第二组控件会挡在屏幕的右边,那也就是看不到了。

LayoutInflater的作用是,把一个View的对象与XML布局文件关联并实例化。
View的对象实例化之后,可以通过findViewById()查找布局文件中的指定Id的组件。

android:gravity="center_vertical"表示:将对象纵向居中,不改变其大小。垂直对齐方式:垂直方向上居中对齐。
android:gravity="center_horizontal"表示:将对象横向居中,不改变其大小。水平对齐方式:水平方向上居中对齐。

按比例显示LinearLayout内各个子控件,需设置android:layout_width="0dp",如果为竖直方向的设置android:layout_height="0dp"。在这种情况下某子个控件占用LinearLayout的比例为:本控件weight值 / LinearLayout内所有控件的weight值的和。

使用ListView记得加上属性:android:cacheColorHint="#00000000"或者
//设置背景透明  
list.setCacheColorHint(Color.TRANSPARENT);
设置listView点击或滑动为白色(去除默认的黄色):android:listSelector="#fff"

在EditText中加入<requestFocus></requestFocus>可以使之获取焦点

中间加横线:
textView.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG );
底部加横线:
textView.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG );

隐藏状态栏:
final Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
隐藏标题栏:
requestWindowFeature(Window.FEATURE_NO_TITLE);

隐藏ScrollBar:
布局:android:ScrollBars="none"  
代码:
void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled)
void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled)  

获取手机号/手机串号:
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
String imei = tm.getDeviceId();
String tel = tm.getLine1Number();

标题栏进度指示器:
在使用时我们首先需要在setContentView之前声明
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);  
在需要显示进度时调用  
setProgressBarIndeterminateVisibility(true);
停止时调用  
setProgressBarIndeterminateVisibility(false);

在listView的item中有button时,需要设置button为没有焦点。

android:divider="@null"    该属性作用是每一项之间需要设置一个图片做为间隔,或是去掉item之间的分割线
android:fadingEdge="none" 设置后没有阴影

总结一下列表布局的关键部分:
1.布局文件中定义ListView  
2.Adapter用来将数据填充到ListView  
3.要填充到ListView的数据,这些数据可以字符串、图片、控件等等
其中Adapter是 ListView和数据源之间的桥梁,根据数据源的不同Adapter可以分为三类:
1.String[]: ArrayAdapter  
2.List<Map<String,?>>: SimpleAdapter  
3.数据库Cursor: SimpleCursorAdapter

//清空手机上cookie

CookieSyncManager.createInstance(getApplicationContext());

CookieManager.getInstance().removeAllCookie();




自定义标题:

super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); //声明使用自定义标题
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);//自定义布局赋值




//Android 开发之 ClipboardManager

//获取剪贴板管理服务
ClipboardManager cm =(ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
//将文本数据复制到剪贴板
cm.setText(message);
//读取剪贴板数据
cm.getText();




//30分钟执行一次服务

AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);  

Intent intent = new Intent(context, MyService.class);

PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);

long interval = DateUtils.MINUTE_IN_MILLIS * 30;

long firstWake = System.currentTimeMillis() + interval;

am.setRepeating(AlarmManager.RTC,firstWake, interval, pendingIntent);




//MD5加密算法

public class MD5 {  

public static String getMD5(String val) throws NoSuchAlgorithmException{
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(val.getBytes());
byte[] m = md5.digest();//加密
return getString(m);
}
private static String getString(byte[] b){
StringBuffer sb = new StringBuffer();
for(int i = 0; i < b.length; i ++){
sb.append(b[i]);
}
return sb.toString();
}
}




//Activity界面切换添加动画特效

//实现淡入淡出的效果
overridePendingTransition(Android.R.anim.fade_in,android.R.anim.fade_out);
overridePendingTransition(Android.R.anim.fade_in,android.R.anim.fade_out);

//由左向右滑入的效果
overridePendingTransition(Android.R.anim.slide_in_left,android.R.anim.slide_out_right);
overridePendingTransition(Android.R.anim.slide_in_left,android.R.anim.slide_out_right);

//实现zoomin和zoomout,即类似iphone的进入和退出时的效果
overridePendingTransition(R.anim.zoomin, R.anim.zoomout);
overridePendingTransition(R.anim.zoomin, R.anim.zoomout);




新建zoomin.xml文件

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.android.com/apk/res/android"
Android:interpolator
="@android:anim/decelerate_interpolator">
<scale Android:fromXScale="2.0" android:toXScale="1.0"
Android:fromYScale
="2.0" android:toYScale="1.0"
Android:pivotX
="50%p" android:pivotY="50%p"
Android:duration
="@android:integer/config_mediumAnimTime" />
</set>




新建zoomout.xml文件

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.android.com/apk/res/android"
Android:interpolator
="@android:anim/decelerate_interpolator"
Android:zAdjustment
="top">
<scale Android:fromXScale="1.0" android:toXScale=".5"
Android:fromYScale
="1.0" android:toYScale=".5"
Android:pivotX
="50%p" android:pivotY="50%p"
Android:duration
="@android:integer/config_mediumAnimTime" />
<alpha Android:fromAlpha="1.0" android:toAlpha="0"
Android:duration
="@android:integer/config_mediumAnimTime"/>
</set>




//设置透明度(这是窗体本身的透明度,非背景)

WindowManager.LayoutParams lp=getWindow().getAttributes();
lp.alpha=0.3f;
getWindow().setAttributes(lp);

//alpha在0.0f到1.0f之间。1.0完全不透明,0.0f完全透明





//设置黑暗度

                WindowManager.LayoutParams lp=getWindow().getAttributes();
lp.dimAmount=0.5f;
getWindow().setAttributes(lp);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

//dimAmount在0.0f和1.0f之间,0.0f完全不暗,1.0f全暗





//设置背景模糊

getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,     
WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

//以上设置对dialog对话框同样有效




//设置星星样式的checkbox

style="?android:attr/starStyle"

//让字体闪烁

 private int clo = 0;  
public void spark() {
final TextView touchScreen = (TextView) findViewById(R.id.TextView01);// 获取页面textview对象
Timer timer = new Timer();
TimerTask taskcc = new TimerTask(){

public void run() {
runOnUiThread(new Runnable() {
public void run() {
if (clo == 0) {
clo = 1;
touchScreen.setTextColor(Color.TRANSPARENT); // 透明
} else {
if (clo == 1) {
clo = 2;
touchScreen.setTextColor(Color.RED);
} else {
clo = 0;
touchScreen.setTextColor(Color.GREEN);
}
}
}
});
}
};
timer.schedule(taskcc, 1, 300); // 参数分别是delay(多长时间后执行),duration(执行间隔)
}
}




//从输入流中获取数据并以字节数组返回

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
public class StreamTool {
/**
* 从输入流获取数据
*
@param inputStream
*
@return
*
@throws Exception
*/
public static byte[] readInputStream(InputStream inputStream) throws Exception {
byte[] buffer = new byte[1024]; //你可以根据实际需要调整缓存大小
int len = -1;
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
while( (len = inputStream.read(buffer)) != -1 ){
outSteam.write(buffer, 0, len);
}
outSteam.close();
inputStream.close();
return outSteam.toByteArray();
}
}




//安装apk文件

private void installAPK(File file) {
Intent intent = newIntent(Intent.ACTION_VIEW);
Uri data =Uri.fromFile(file);
String type ="application/vnd.android.package-archive";
intent.setDataAndType(data,type);
startActivity(intent);
}




 

//卸载apk文件

 private void uninstallAPK(String packageName){
Intent intent = newIntent(Intent.ACTION_VIEW);
Uri data = Uri.parse("package:"+ packageName);
intent.setData(data);
startActivity(intent);
}





 //编辑图片大小,保持图片不变形。

 public static Bitmap resetImage(BitmapsourceBitmap,int resetWidth,int resetHeight){
int width =sourceBitmap.getWidth();
int height =sourceBitmap.getHeight();
int tmpWidth;
int tmpHeight;
float scaleWidth =(float)resetWidth / (float)width;
float scaleHeight =(float)resetHeight / (float)height;
float maxTmpScale = scaleWidth>= scaleHeight ? scaleWidth : scaleHeight;
//保持不变形
tmpWidth = (int)(maxTmpScale *width);
tmpHeight = (int)(maxTmpScale *height);
Matrix m = new Matrix();
m.setScale(maxTmpScale,maxTmpScale, tmpWidth, tmpHeight);
sourceBitmap =Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(),sourceBitmap.getHeight(), m, false);
//切图
int x = (tmpWidth -resetWidth)/2;
int y = (tmpHeight -resetHeight)/2;
returnBitmap.createBitmap(sourceBitmap, x, y, resetWidth,resetHeight);
}




 

//从SIM卡中获取联系人

private Cursor getContacts() {
Uri uri = Uri.parse("content://sim/adn");
String[] projection = new String[] { "name", "phone" };
String selection = null;
String[] selectionArgs = null;
String sortOrder = null;
return managedQuery(uri, projection, selection, selectionArgs,sortOrder);
}




//检查网络是否连接  

public boolean checkIntent(){
   ConnectivityManager mannager=(ConnectivityManager)
   this.getSystemService(CONNECTIVITY_SERVICE);
   NetworkInfo info=mannager.getActiveNetworkInfo();
   if(info==null || !info.isConnected()){
   return false;
   }
   if(info.isRoaming()){
   return true;
   }
   return true;
   }
//<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>




//取得屏幕信息

     DisplayMetrics dm = new DisplayMetrics();
dm = this.getResources().getDisplayMetrics();
//获得屏幕宽度
int screenWidth = dm.widthPixels;
//获得屏幕高度
int screenHeight = dm.heightPixels;




//获取屏幕方向

    Configuration newConfig = getResources().getConfiguration();       
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
//横屏
}else if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
//竖屏
}else if(newConfig.hardKeyboardHidden == Configuration.KEYBOARDHIDDEN_NO){
//键盘没关闭。屏幕方向为横屏
}else if(newConfig.hardKeyboardHidden == Configuration.KEYBOARDHIDDEN_YES){
//键盘关闭。屏幕方向为竖屏
}




//开机自动启动

public class BootReceiver extends BroadcastReceiver {    
private PendingIntent mAlarmSender;
@Override
public void onReceive(Context context, Intent intent) {
// 在这里干你想干的事(启动一个Service,Activity等),本例是启动一个定时调度程序,
每30分钟启动一个Service去更新数据
mAlarmSender = PendingIntent.getService(context, 0, new Intent(context,
RefreshDataService.class), 0);
long firstTime = SystemClock.elapsedRealtime();
AlarmManageram=(AlarmManager)context.getSystemService(Activity.ALARM_SERVICE);
am.cancel(mAlarmSender);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 30*60*1000,
mAlarmSender);
}
}



<receiver android:name=".service.BootReceiver">  
<intent-filter>
<!-- 系统启动完成后会调用-->
<action android:name="android.intent.action.BOOT_COMPLETED">
</action>
</intent-filter>
</receiver>


 

HttpURLConnection对象 

1.从Internet获取网页,发送请求,将网页以流的形式读回来.
 
步骤:
1)创建一个URL对象:URL url = new URL(http://www.baidu.com );

2)利用HttpURLConnection对象从网络中获取网页数据:HttpURLConnection conn = (HttpURLConnection) url.openConnection();
3)设置连接超时:conn.setConnectTimeout(6*1000);

4)对响应码进行判断:if (conn.getResponseCode() != 200) throw new RuntimeException("请求url失败");

5)得到网络返回的输入流:InputStream is = conn.getInputStream();

6)String result = readData(is, "GBK");

7)conn.disconnect();
总结:
--记得设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作.

--返回的响应码200,是成功.
--利用ByteArrayOutputStream类,将得到的输入流写入内存.
--在Android中对文件流的操作和JAVA SE上面是一样的.

2.从Internet获取文件

利用HttpURLConnection对象,从网络中获取文件数据.
步骤:
1)创建URL对象,并将文件路径传入:URL url = new URL(http://photocdn.sohu.com/20100125/Img269812337.jpg );

2)创建HttpURLConnection对象,从网络中获取文件数据:HttpURLConnection conn = (HttpURLConnection)
url.openConnection();

3)设置连接超时:conn.setConnectTimeout(6* 1000);

4)对响应码进行判断:if (conn.getResponseCode() != 200) throw new RuntimeException("请求url失败");
5)得到网络返回的输入流:InputStream is = conn.getInputStream();

6)将得到的文件流写出:outStream.write(buffer, 0, len);
总结:
--在对大文件的操作时,要将文件写到SDCard上面,不要直接写到手机内存上.

--操作大文件是,要一遍从网络上读,一遍要往SDCard上面写,减少手机内存的使用.这点很重要,面试经常会被问到.
--对文件流操作完,要记得及时关闭.
3.向Internet发送请求参数
步骤:

 



2)创建URL对象:URL realUrl = new URL(requestUrl);

3)通过HttpURLConnection对象,向网络地址发送请求:HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();

4)设置容许输出:conn.setDoOutput(true);

5)设置不使用缓存:conn.setUseCaches(false);
6)设置使用POST的方式发送:conn.setRequestMethod("POST");
          
7)设置维持长连接:conn.setRequestProperty("Connection", "Keep-Alive");

8)设置文件字符集:conn.setRequestProperty("Charset", "UTF-8");

9)设置文件长度:conn.setRequestProperty("Content-Length", String.valueOf(data.length));

10)设置文件类型:conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

11)以流的方式输出.

总结:
--发送POST请求必须设置允许输出

--不要使用缓存,容易出现问题.
--在开始用HttpURLConnection对象的setRequestProperty()设置,就是生成HTML文件头.
4.向Internet发送xml数据
XML格式是通信的标准语言,Android系统也可以通过发送XML文件传输数据.
步骤:
1)将生成的XML文件写入到byte数组中,并设置为UTF-8:byte[] xmlbyte = xml.toString().getBytes("UTF-8");
2)创建URL对象,并指定地址和参数:URL url = new URL(http://localhost:8080/itcast/contanctmanage.do?method=readxml );
3)获得链接:HttpURLConnection conn = (HttpURLConnection) url.openConnection();
4)设置连接超时:conn.setConnectTimeout(6* 1000);
5)设置允许输出conn.setDoOutput(true);
6)设置不使用缓存:conn.setUseCaches(false);
7)设置以POST方式传输:conn.setRequestMethod("POST");          
8)维持长连接:conn.setRequestProperty("Connection", "Keep-Alive");
9)设置字符集:conn.setRequestProperty("Charset", "UTF-8");
10)设置文件的总长度:conn.setRequestProperty("Content-Length", String.valueOf(xmlbyte.length));
11)设置文件类型:conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
12)以文件流的方式发送xml数据:outStream.write(xmlbyte);
总结:

--我们使用的是用HTML的方式传输文件,这个方式只能传输一般在5M一下的文件.

--传输大文件不适合用HTML的方式,传输大文件我们要面向Socket编程.确保程序的稳定性

1)将地址和参数存到byte数组中:byte[] data = params.toString().getBytes();

5. HttpURLConnection中如何设置网络超时

Java中可以使用HttpURLConnection来请求WEB资源。
HttpURLConnection对象不能直接构造,需要通过URL.openConnection()来获得HttpURLConnection对象,示例代码如下:
String szUrl = "http://www.baidu.com/";
URL url = new URL(szUrl);
HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();

HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现。如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。可以通过以下两个语句来设置相应的超时:
System.setProperty("sun.net.client.defaultConnectTimeout", 超时毫秒数字符串);
System.setProperty("sun.net.client.defaultReadTimeout", 超时毫秒数字符串);

其中: sun.net.client.defaultConnectTimeout:连接主机的超时时间(单位:毫秒)
sun.net.client.defaultReadTimeout:从主机读取数据的超时时间(单位:毫秒)

例如:
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");
System.setProperty("sun.net.client.defaultReadTimeout", "30000");

JDK 1.5以前的版本,只能通过设置这两个系统属性来控制网络超时。在1.5中,还可以使用HttpURLConnection的父类URLConnection的以下两个方法:
setConnectTimeout:设置连接主机超时(单位:毫秒)
setReadTimeout:设置从主机读取数据超时(单位:毫秒)

例如:
HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();
urlCon.setConnectTimeout(30000);
urlCon.setReadTimeout(30000);

需要注意的是,笔者在JDK1.4.2环境下,发现在设置了 defaultReadTimeout的情况下,如果发生网络超时,HttpURLConnection会自动重新提交一次请求,出现一次请求调用,请求 服务器两次的问题(Trouble)。我认为这是JDK1.4.2的一个bug。在JDK1.5.0中,此问题已得到解决,不存在自动重发现象。


//自动更新代码示例:

public class Update extends BaseActivity {
public ProgressDialog pBar;
private Handler handler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.update);
Dialog dialog = new AlertDialog.Builder(Update.this)
.setTitle("系统更新")
.setMessage("发现新版本,请更新!")
// 设置内容
.setPositiveButton("确定",// 设置确定按钮
new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog,
int which) {
pBar = new ProgressDialog(Update.this);
pBar.setTitle("正在下载");
pBar.setMessage("请稍候...");
pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
downFile("http://url:8765/OA.apk");

}

})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// 点击"取消"按钮之后退出程序

}
}).create();// 创建
// 显示对话框
dialog.show();

}

void downFile(final String url) {
pBar.show();
new Thread() {
public void run() {
HttpClient client = new DefaultHttpClient();
// params[0]代表连接的url
HttpGet get = new HttpGet(url);
HttpResponse response;
try {
response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
FileOutputStream fileOutputStream = null;
if (is != null) {

File file = new File(
Environment.getExternalStorageDirectory(),
"OA.apk");
fileOutputStream = new FileOutputStream(file);

byte[] buf = new byte[1024];
int ch = -1;
int count = 0;
while ((ch = is.read(buf)) != -1) {
// baos.write(buf, 0, ch);
fileOutputStream.write(buf, 0, ch);
count += ch;
if (length > 0) {

}

}

}
fileOutputStream.flush();
if (fileOutputStream != null) {
fileOutputStream.close();
}
down();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}.start();

}

void down() {
handler.post(new Runnable() {
public void run() {
pBar.cancel();
update();
}
});

}

void update() {

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File("/sdcard/OA.apk")),
"application/vnd.android.package-archive");
startActivity(intent);
}

}

 

应用程序动态全屏和退出全屏

让程序全屏的方法,大家都知道,那是静态的,程序运行之初就申明了。但是如果有这样的需求:要在程序运行的过程中,执行了某个操作而使之全屏,然后还需要退出全屏,怎么做?

    如下:

WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attrs);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

修改window的LayoutParams参数,然后加上FLAG_LAYOUT_NO_LIMITS标志,就OK了。window会自动重新布局,呈现全屏的状态。

    要退出全屏,只需要清除刚才加上的FLAG_FULLSCREEN参数,然后去掉FLAG_LAYOUT_NO_LIMITS标志。

    如下

WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

android监听文件和目录的创建删除移动等事件

android.os下的FileObserver类是一个用于监听文件访问、创建、修改、删除、移动等操作的监听器,基于linux的inotify。 FileObserver 是个抽象类,必须继承它才能使用。每个FileObserver对象监听一个单独的文件或者文件夹,如果监视的是一个文件夹,那么文件夹下所有的文件和级联子目录的改变都会触发监听的事件。
    所能监听的事件类型如下:
    ACCESS,即文件被访问
    MODIFY,文件被 修改
    ATTRIB,文件属性被修改,如 chmod、chown、touch 等
    CLOSE_WRITE,可写文件被 close
    CLOSE_NOWRITE,不可写文件被 close
    OPEN,文件被 open
    MOVED_FROM,文件被移走,如 mv
    MOVED_TO,文件被移来,如 mv、cp
    CREATE,创建新文件
    DELETE,文件被删除,如 rm
    DELETE_SELF,自删除,即一个可执行文件在执行时删除自己
    MOVE_SELF,自移动,即一个可执行文件在执行时移动自己
    CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
    ALL_EVENTS,包括上面的所有事件
      这些都是FileObserver的静态共有属性。
      下面举个例子说明一下其用法。
      比如,我要监听sd卡的目录创建事件,新建一个类SDCardListener继承FileObserver:

import android.os.FileObserver;
import android.util.Log;

/**
* sd卡上的目录创建监听器
*
@author chroya
*
*/
public class SDCardListener extends FileObserver {

public SDCardListener(String path) {
/*
* 这种构造方法是默认监听所有事件的,如果使用super(String,int)这种构造方法,
* 则int参数是要监听的事件类型.
*/
super(path);
}

@Override
public void onEvent(int event, String path) {
switch(event) {
case FileObserver.ALL_EVENTS:
Log.d("all", "path:"+ path);
break;
case FileObserver.CREATE:
Log.d("Create", "path:"+ path);
break;
}
}
}

onEvent是回调,系统监听到事件后会触发此事件,参数event就是上面所说的事件类型,根据类型,我们可以做相应的处理,参数path就是触发事件的目录。

      然后使用它:

SDCardListener listener = new SDCardListener("/sdcard");
//开始监听
listener.startWatching();
/*
* 在这里做一些操作,比如创建目录什么的
*/
//最后停止监听
listener.stopWatching();

      如果要在onEvent中做较多操作,最好用线程去做 ,以免因为阻塞接收不到后面的事件。

      最后补充一点,比较重要
      FileObserver对象必须保持一个引用,确保不被垃圾收集器回收掉,否则就不会触发事件了。

Android获取其他包的Context

Android中有Context的概念,想必大家都知道。Context可以做很多事情,打开activity、发送广播、打开本包下文件夹和数据库、 获取classLoader、获取资源等等。如果我们得到了一个包的Context对象,那我们基本上可以做这个包自己能做的大部分事情。

         那我们能得到吗?很高兴的告诉你,能!
      Context有个createPackageContext方法,可以创建另外一个包的上下文,这个实例不同于它本身的Context实例,但是功能是一样的。


      这个方法有两个参数:
1。packageName  包名,要得到Context的包名
2。flags  标志位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY两个选项。 CONTEXT_INCLUDE_CODE的意思是包括代码,也就是说可以执行这个包里面的代码。CONTEXT_IGNORE_SECURITY的意思 是忽略安全警告,如果不加这个标志的话,有些功能是用不了的,会出现安全警告。


      下面给个小例子,执行另外一个包里面的某个类的方法。
      另外一个包的包名是chroya.demo,类名Main,方法名print,代码如下:

 

package chroya.demo;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

class Main extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

public void print(String msg) {
Log.d("Main", "msg:"+ msg);
}
}

本包的调用Main的print方法的代码块如下

Context c = createPackageContext("chroya.demo", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
//载入这个类
Class clazz = c.getClassLoader().loadClass("chroya.demo.Main");
//新建一个实例
Object owner = clazz.newInstance();
//获取print方法,传入参数并执行
Object obj = clazz.getMethod("print", String.class).invoke(owner, "Hello");

ok,这样,我们就调用了chroya.demo包的Main类的print方法,执行结果,打印出了Hello。

/**
* 判断日期格式是否正确
*/
public static boolean IsDateFormat(String dataStr) {
boolean state = false;
try {
java.text.SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd");
dFormat.setLenient(false);
java.util.Date d = dFormat.parse(dataStr);
state = true;
} catch (ParseException e) {
e.printStackTrace();
state = false;
}
return state;
}
/**
* 计算date之前n天的日期
*/
public static Date getDateBefore(Date date, int n) {
Calendar now = Calendar.getInstance();
now.setTime(date);
now.set(Calendar.DATE, now.get(Calendar.DATE) - n);
return now.getTime();
}
/** 
* 得到几天后的时间
*/
public static Date getDateAfter(Date d, int day) {
Calendar now = Calendar.getInstance();
now.setTime(d);
now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
return now.getTime();
}











你可能感兴趣的:(android)