編輯:關於Android編程
接著android 中導出數據 一文,下面介紹在android中導入數據的思路:
1、將數據從文本中讀取出來
2、封裝處理成自己想要的對象或模型
3、將處理好的數據對象插入自己應用的數據庫中
4、更新UI顯示
下面仍以導入聯系人至系統中為例,若是導入自己的應用中,思路一樣甚至更簡單,代碼如下:
注:我的聯系人.txt的格式即為android 中導出數據 一文生成的格式
MainActivity:
package com.home.impcontact; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import android.app.Activity; import android.app.AlertDialog; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.provider.ContactsContract; import android.provider.ContactsContract.RawContacts; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.provider.ContactsContract.Contacts.Data; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener { private Button btn;// 導入按鈕 private TextView show;// 顯示結果的文本框 private Thread addThread;// 增加聯系人線程 private static final int ADD_FAIL = 0;// 導入失敗標識 private static final int ADD_SUCCESS = 1;// 導入成功標識 private static int successCount = 0;// 導入成功的計數 private static int failCount = 0;// 導入失敗的計數 // 默認文件路勁,實際情況應作相應修改或從界面輸入或浏覽選擇 private static final String PATH = Environment .getExternalStorageDirectory() + "/我的聯系人.txt"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } /** * 初始化組件 */ private void init() { btn = (Button) findViewById(R.id.main_btn); btn.setOnClickListener(this); show = (TextView) findViewById(R.id.main_tv); } @Override public void onClick(View v) { if (v == btn) { addContact(); } } /** * 導入聯系人入口 */ private void addContact() { if (!new File(PATH).exists()) { Toast.makeText(this, "文件不存在!", Toast.LENGTH_SHORT).show(); show.setText("文件不存在!"); return; } if (addThread != null) { addThread.interrupt(); addThread = null; } addThread = new Thread(new AddRunnable(this, PATH)); createDialog(this, "警告", "確保你是第一次導入,重復導入會創建新的聯系人,請慎用!"); } /** * 創建提示對話框 * * @param context * @param title * @param message */ private void createDialog(Context context, String title, String message) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(title); builder.setMessage(message); builder.setPositiveButton("確定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { startAddContact(); } }); builder.setNeutralButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dialog.cancel(); } }); builder.show(); } /** * 開啟導入線程 */ private void startAddContact() { setAddWidgetEnabled(false); show.setText("正在導入聯系人..."); if (addThread != null) { addThread.start(); } } class AddRunnable implements Runnable { private Context context; private String path; public AddRunnable(Context context, String path) { this.path = path; this.context = context; } @Override public void run() { boolean result = importContact(context, path); if (result) { handler.sendEmptyMessage(ADD_SUCCESS); } else { handler.sendEmptyMessage(ADD_FAIL); } } } /** * 處理UI相關的handler */ private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case ADD_FAIL: show.setText("導入聯系人失敗"); setAddWidgetEnabled(true); break; case ADD_SUCCESS: show.setText(String.format("導入聯系人成功 %d 條,失敗 %d 條", successCount, failCount)); setAddWidgetEnabled(true); break; } } }; /** * 設置導入組件的可用性 * * @param enabled */ private void setAddWidgetEnabled(boolean enabled) { btn.setEnabled(enabled); if (!enabled) { show.setText(""); } } /** * 導入聯系人 * * @param context * @param path * @return */ private boolean importContact(Context context, String path) { successCount = 0; failCount = 0; try { ArrayListlist = readFromFile(path); if (list == null) { return false; } for (int i = 0; i < list.size(); i++) { ContactInfo info = list.get(i); if (doAddContact(context, info)) { successCount++; } } } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 讀取聯系人並封裝成ContactInfo對象集合 * * @param path * @return contactsList */ private ArrayList readFromFile(String path) { ArrayList strsList = doReadFile(path); if (strsList == null) { return null; } ArrayList contactsList = handleReadStrs(strsList); return contactsList; } /** * 將讀出來的內容封裝成ContactInfo對象集合 * * @param strsList * @return */ private ArrayList handleReadStrs(ArrayList strsList) { ArrayList contactsList = new ArrayList (); for (int i = 0; i < strsList.size(); i++) { String info = strsList.get(i); String[] infos = info.split("\\s{2,}"); String displayName = null; String mobileNum = null; String homeNum = null; switch (infos.length) { case 0: continue; case 1: displayName = infos[0]; break; case 2: displayName = infos[0]; if (infos[1].length() >= 11) { mobileNum = infos[1]; } else { homeNum = infos[1]; } break; default: // length >= 3 displayName = infos[0]; mobileNum = infos[1]; homeNum = infos[2]; } if (displayName == null || "".equals(displayName)) { failCount++; continue; } contactsList.add(new ContactInfo(displayName, mobileNum, homeNum)); } return contactsList; } /** * 讀取文件內容 * * @param path * @return */ private ArrayList doReadFile(String path) { FileInputStream in = null; ArrayList arrayList = new ArrayList (); try { byte[] tempbytes = new byte[1 << 24]; in = new FileInputStream(path); while (in.read(tempbytes) != -1) { int length = 0; int first = length; for (int i = 0; i < tempbytes.length; i++) { if (tempbytes[i] == '\n') { length = i; byte[] nowBytes = new byte[length - first]; System.arraycopy(tempbytes, first, nowBytes, 0, length - first); arrayList.add(new String(nowBytes, "utf-8").trim()); first = i + 1; } } } } catch (Exception e1) { return null; } finally { if (in != null) { try { in.close(); } catch (IOException e1) { return null; } } } return arrayList; } /** * 向數據庫表插入聯系人信息 * * @param context * @param contactInfo * @return */ private boolean doAddContact(Context context, ContactInfo contactInfo) { try { ContentValues contentValues = new ContentValues(); Uri uri = context.getContentResolver().insert( RawContacts.CONTENT_URI, contentValues); long rowId = ContentUris.parseId(uri); String name = contactInfo.getDisplayName(); String mobileNum = contactInfo.getMobileNum(); String homeNum = contactInfo.getHomeNum(); // 插入姓名 if (name != null) { contentValues.clear(); contentValues.put(Data.RAW_CONTACT_ID, rowId); contentValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE); int index = name.length() / 2; String displayName = name; String givenName = null; String familyName = null; // 檢查是否是英文名稱 if (checkEnglishName(displayName) == false) { givenName = name.substring(index); familyName = name.substring(0, index); } else { givenName = familyName = displayName; } contentValues.put(StructuredName.DISPLAY_NAME, displayName); contentValues.put(StructuredName.GIVEN_NAME, givenName); contentValues.put(StructuredName.FAMILY_NAME, familyName); context.getContentResolver().insert( ContactsContract.Data.CONTENT_URI, contentValues); } if (mobileNum != null) { // 插入手機電話 contentValues.clear(); contentValues.put(Data.RAW_CONTACT_ID, rowId); contentValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); contentValues.put(Phone.NUMBER, mobileNum); contentValues.put(Phone.TYPE, Phone.TYPE_MOBILE); context.getContentResolver().insert( ContactsContract.Data.CONTENT_URI, contentValues); } if (homeNum != null) { // 插入家庭號碼 contentValues.clear(); contentValues.put(Data.RAW_CONTACT_ID, rowId); contentValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); contentValues.put(Phone.NUMBER, homeNum); contentValues.put(Phone.TYPE, Phone.TYPE_HOME); context.getContentResolver().insert( ContactsContract.Data.CONTENT_URI, contentValues); } } catch (Exception e) { return false; } return true; } /** * 檢查是否是英文名稱 * * @param name * @return */ private boolean checkEnglishName(String name) { char[] nameChars = name.toCharArray(); for (int i = 0; i < nameChars.length; i++) { if ((nameChars[i] >= 'a' && nameChars[i] <= 'z') || (nameChars[i] >= 'A' && nameChars[i] <= 'Z')) { continue; } return false; } return true; } }
聯系人實體類ContactInfo:
package com.home.impcontact; public class ContactInfo { /** 名稱 */ private String displayName; /** 手機號 */ private String mobileNum; /** 家庭電話 */ private String homeNum; public ContactInfo(String displayName, String mobileNum, String homeNum) { this.displayName = displayName; this.mobileNum = mobileNum; this.homeNum = homeNum; } public String getDisplayName() { return displayName; } public String getMobileNum() { return mobileNum; } public String getHomeNum() { return homeNum; } }
布局文件:
權限:
前言 最近在使用第三方登錄和分享的過程中遇到了很多問題,一方面可以歸結為自己經驗的不足,另一方面其實也說明了官方文檔的含糊不清。這篇博文不會寫關於如何使用第三方登錄分享,
學習在於實用,只有把自己學到的東西真正的融入到我們的開發中,並且使用的得心應手,那才是真正的掌握。而想把技術使用的得心應手並不是一蹴而就的,需要不斷的鞏固自己的知識體系,
先來看下效果圖: 其中show和dismiss的時候有動畫效果。 原先試過使用PopupWindow來做,但是使用的時候不是那麼舒服,畢竟不
需求:Android 4.4 + okhttp 3.2;非root,在應用層,拿到DNS維度底層數據方案:jni + hook libc.so中DNS關鍵getaddri