移动应用开发Android通讯录导入小工具
来源:互联网 发布:数据报表分析 编辑:程序博客网 时间:2024/06/05 20:37
应用开发要求
系统运行效果
实现思路与设计
废话不多说,上代码
首先是MainActivity
package com.example.tsm.xmldemo;import android.app.Dialog;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.Toast;import java.io.FileInputStream;import java.io.InputStream;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button search,button_openfile; private ListView list; private ArrayList<Person> persons; //private SimpleAdapter mAdapter; private int [] tImg = new int[]{R.mipmap.ic_launcher_round,R.mipmap.ic_launcher_round,R.mipmap.ic_launcher_round,R.mipmap.ic_launcher_round,R.mipmap.ic_launcher_round}; private String [] name = new String[10]; private String [] phoneNumber = new String[10]; private String [] temp = new String[3]; private String filepath = null; static private int openfileDialogId = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setView(); } private void setView(){ search = (Button) findViewById(R.id.search); list = (ListView) findViewById(R.id.list); button_openfile = (Button) findViewById(R.id.button_openfile); search.setOnClickListener(this); button_openfile.setOnClickListener(this); } private ArrayList<Person> readxmlForSAX() throws Exception { //获取文件资源建立输入流对象 InputStream is = new FileInputStream(filepath); //①创建XML解析处理器 SaxHelper ss = new SaxHelper(); //②得到SAX解析工厂 SAXParserFactory factory = SAXParserFactory.newInstance(); //③创建SAX解析器 SAXParser parser = factory.newSAXParser(); //④将xml解析处理器分配给解析器,对文档进行解析,将事件发送给处理器 parser.parse(is, ss); is.close(); return ss.getPersons(); } @Override protected Dialog onCreateDialog(int id) { if(id==openfileDialogId){ Map<String, Integer> images = new HashMap<String, Integer>(); // 下面几句设置各文件类型的图标, 需要你先把图标添加到资源文件夹 images.put(OpenFileDialog.sRoot, R.drawable.filedialog_root); // 根目录图标 images.put(OpenFileDialog.sParent, R.drawable.filedialog_folder_up); //返回上一层的图标 images.put(OpenFileDialog.sFolder, R.drawable.filedialog_folder); //文件夹图标 images.put("xml",R.drawable.filedialog_file); //文件图标 images.put("wav", R.drawable.filedialog_wavfile); //wav文件图标 images.put(OpenFileDialog.sEmpty, R.drawable.filedialog_root); Dialog dialog = OpenFileDialog.createDialog(id, this, "打开文件", new CallbackBundle() { @Override public void callback(Bundle bundle) { filepath = bundle.getString("path"); Toast.makeText(getApplicationContext(),"选择成功!",Toast.LENGTH_LONG).show(); //setTitle(filepath); // 把文件路径显示在标题上 } }, ".wav;.xml;", images); return dialog; } return null; } @Override public void onClick(View v) { switch (v.getId()){ case R.id.search:// String path=getApplicationContext().getFilesDir().getAbsolutePath();// Toast.makeText(getApplicationContext(),filepath+"&&"+path,Toast.LENGTH_LONG).show();// //Log.i("XXXXQQQQ",filepath+"&&"+path); //Log.i("xxx","执行了1"); try { persons = readxmlForSAX(); //Log.i("xxx","执行了2"); } catch (Exception e) { e.printStackTrace(); } //mAdapter = new ArrayAdapter<Person>(MainActivity.this, R.layout.list_item, persons); List<Map<String, Object>> listitem = new ArrayList<Map<String, Object>>(); //Log.i("xxx","执行了3"+persons.get(0).toString()+","+ persons.size()); for (int i=0;i< persons.size();i++){ temp = persons.get(i).toString().split(","); name[i] = temp[0]; phoneNumber[i] = temp[1]; } for (int i = 0; i < persons.size() ; i++){ Map<String,Object> showitem = new HashMap<String, Object>(); showitem.put("name",name[i]); //Log.i("name"+i,name[i]); showitem.put("phoneNumber",phoneNumber[i]); showitem.put("tImg",tImg[i]); listitem.add(showitem); } SimpleAdapter mAdapter = new SimpleAdapter(getApplicationContext(),listitem , R.layout.list_item ,new String[]{"tImg","name","phoneNumber"},new int[]{R.id.imageView,R.id.name,R.id.phoneNumber}); list.setAdapter(mAdapter); Toast.makeText(getApplicationContext(),"导入成功!",Toast.LENGTH_LONG).show(); break; case R.id.button_openfile: showDialog(openfileDialogId); break; } }}
通讯录对象属性存储类
person
package com.example.tsm.xmldemo;/** * Created by TSM on 2017/4/29. */public class Person { private int id; private String name; private String phoneNumber; public Person(int id, String name, String phoneNumber) { this.id = id; this.name = name; this.phoneNumber = phoneNumber; } public Person() { } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } @Override public String toString() { return this.name + "," + this.phoneNumber; }}
使用SAX方式解析XML文档
SaxHelper
package com.example.tsm.xmldemo;import android.util.Log;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;import java.util.ArrayList;/** * Created by TSM on 2017/4/29. */public class SaxHelper extends DefaultHandler { private Person person; private ArrayList<Person> persons; //当前解析的元素标签 private String tagName = null; /** * 当读取到文档开始标志是触发,通常在这里完成一些初始化操作 */ @Override public void startDocument() throws SAXException { this.persons = new ArrayList<Person>(); //Log.i("SAX", "读取到文档头,开始解析xml"); } /** * 读到一个开始标签时调用,第二个参数为标签名,最后一个参数为属性数组 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (localName.equals("person")) { person = new Person(); person.setId(Integer.parseInt(attributes.getValue("id"))); //Log.i("SAX", "开始处理person元素~"); } this.tagName = localName; } /** * 读到到内容,第一个参数为字符串内容,后面依次为起始位置与长度 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { //判断当前标签是否有效 if (this.tagName != null) { String data = new String(ch, start, length); //读取标签中的内容 if (this.tagName.equals("name")) { this.person.setName(data); //Log.i("SAX", "处理name元素内容"); } else if (this.tagName.equals("phoneNumber")) { this.person.setPhoneNumber(data); //Log.i("SAX", "处理age元素内容"); } } } /** * 处理元素结束时触发,这里将对象添加到结合中 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (localName.equals("person")) { this.persons.add(person); person = null; //Log.i("SAX", "处理person元素结束~"); } this.tagName = null; } /** * 读取到文档结尾时触发, */ @Override public void endDocument() throws SAXException { super.endDocument(); //Log.i("SAX", "读取到文档尾,xml解析结束"); } //获取persons集合 public ArrayList<Person> getPersons() { return persons; }}
现在开始写打开弹出框选择文件的代码了
OpenFileDialog
package com.example.tsm.xmldemo;/** * Created by TSM on 2017/4/29. */import android.app.Activity;import android.app.AlertDialog;import android.app.Dialog;import android.content.Context;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.Toast;import java.io.File;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class OpenFileDialog { public static String tag = "OpenFileDialog"; static final public String sRoot = "/"; static final public String sParent = ".."; static final public String sFolder = "."; static final public String sEmpty = ""; static final private String sOnErrorMsg = "No rights to access!"; // 参数说明 // context:上下文 // dialogid:对话框ID // title:对话框标题 // callback:一个传递Bundle参数的回调接口 // suffix:需要选择的文件后缀,比如需要选择wav、mp3文件的时候设置为".wav;.mp3;",注意最后需要一个分号(;) // images:用来根据后缀显示的图标资源ID。 // 根目录图标的索引为sRoot; // 父目录的索引为sParent; // 文件夹的索引为sFolder; // 默认图标的索引为sEmpty; // 其他的直接根据后缀进行索引,比如.wav文件图标的索引为"wav" public static Dialog createDialog(int id, Context context, String title, CallbackBundle callback, String suffix, Map<String, Integer> images){ AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setView(new FileSelectView(context, id, callback, suffix, images)); Dialog dialog = builder.create(); //dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setTitle(title); return dialog; } static class FileSelectView extends ListView implements OnItemClickListener{ private CallbackBundle callback = null; private String path = sRoot; private List<Map<String, Object>> list = null; private int dialogid = 0; private String suffix = null; private Map<String, Integer> imagemap = null; public FileSelectView(Context context, int dialogid, CallbackBundle callback, String suffix, Map<String, Integer> images) { super(context); this.imagemap = images; this.suffix = suffix==null?"":suffix.toLowerCase(); this.callback = callback; this.dialogid = dialogid; this.setOnItemClickListener(this); refreshFileList(); } private String getSuffix(String filename){ int dix = filename.lastIndexOf('.'); if(dix<0){ return ""; } else{ return filename.substring(dix+1); } } private int getImageId(String s){ if(imagemap == null){ return 0; } else if(imagemap.containsKey(s)){ return imagemap.get(s); } else if(imagemap.containsKey(sEmpty)){ return imagemap.get(sEmpty); } else { return 0; } } private int refreshFileList() { // 刷新文件列表 File[] files = null; try{ files = new File(path).listFiles(); } catch(Exception e){ files = null; } if(files==null){ // 访问出错 Toast.makeText(getContext(), sOnErrorMsg,Toast.LENGTH_SHORT).show(); return -1; } if(list != null){ list.clear(); } else{ list = new ArrayList<Map<String, Object>>(files.length); } // 用来先保存文件夹和文件夹的两个列表 ArrayList<Map<String, Object>> lfolders = new ArrayList<Map<String, Object>>(); ArrayList<Map<String, Object>> lfiles = new ArrayList<Map<String, Object>>(); if(!this.path.equals(sRoot)){ // 添加根目录 和 上一层目录 Map<String, Object> map = new HashMap<String, Object>(); map.put("name", sRoot); map.put("path", sRoot); map.put("img", getImageId(sRoot)); list.add(map); map = new HashMap<String, Object>(); map.put("name", sParent); map.put("path", path); map.put("img", getImageId(sParent)); list.add(map); } for(File file: files) { if(file.isDirectory() && file.listFiles()!=null){ // 添加文件夹 Map<String, Object> map = new HashMap<String, Object>(); map.put("name", file.getName()); map.put("path", file.getPath()); map.put("img", getImageId(sFolder)); lfolders.add(map); } else if(file.isFile()){ // 添加文件 String sf = getSuffix(file.getName()).toLowerCase(); if(suffix == null || suffix.length()==0 || (sf.length()>0 && suffix.indexOf("."+sf+";")>=0)){ Map<String, Object> map = new HashMap<String, Object>(); map.put("name", file.getName()); map.put("path", file.getPath()); map.put("img", getImageId(sf)); lfiles.add(map); } } } list.addAll(lfolders); // 先添加文件夹,确保文件夹显示在上面 list.addAll(lfiles); //再添加文件 SimpleAdapter adapter = new SimpleAdapter(getContext(), list, R.layout.filedialogitem, new String[]{"img", "name", "path"}, new int[]{R.id.filedialogitem_img, R.id.filedialogitem_name, R.id.filedialogitem_path}); this.setAdapter(adapter); return files.length; } @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { // 条目选择 String pt = (String) list.get(position).get("path"); String fn = (String) list.get(position).get("name"); if(fn.equals(sRoot) || fn.equals(sParent)){ // 如果是更目录或者上一层 File fl = new File(pt); String ppt = fl.getParent(); if(ppt != null){ // 返回上一层 path = ppt; } else{ // 返回更目录 path = sRoot; } } else{ File fl = new File(pt); if(fl.isFile()){ // 如果是文件 ((Activity)getContext()).dismissDialog(this.dialogid); // 让文件夹对话框消失 // 设置回调的返回值 Bundle bundle = new Bundle(); bundle.putString("path", pt); bundle.putString("name", fn); // 调用事先设置的回调函数 this.callback.callback(bundle); return; } else if(fl.isDirectory()){ // 如果是文件夹 // 那么进入选中的文件夹 path = pt; } } this.refreshFileList(); } }}
接口:CallbackBundle
package com.example.tsm.xmldemo;import android.os.Bundle;/** * Created by TSM on 2017/4/29. */public interface CallbackBundle { abstract void callback(Bundle bundle);}
好了,处理的工作写完啦,现在开始写界面代码了
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" android:layout_margin="10dp"> <Button android:id="@+id/search" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/search"/> <Button android:id="@+id/button_openfile" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/diag"/> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp"> </ListView></LinearLayout>
filedialogitem.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/vw1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#000000" android:orientation="horizontal" android:padding="4dp" > <ImageView android:id="@+id/filedialogitem_img" android:layout_width="32dp" android:layout_height="32dp" android:layout_margin="4dp"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/filedialogitem_name" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="18sp" android:textStyle="bold" /> <TextView android:id="@+id/filedialogitem_path" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="10dp" android:textColor="#FFFFFF" android:textSize="14sp" /> </LinearLayout></LinearLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="15dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_marginBottom="5dp" > <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@mipmap/ic_launcher_round" /> <TextView android:id="@+id/name" android:layout_width="80dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="20dp" android:textColor="@color/colorfont" android:text="姓名"/> <TextView android:id="@+id/phoneNumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textColor="@color/colorfont" android:text="17673116337"/> </LinearLayout></LinearLayout>
用于解析的xml文件,把文件置于Android系统的mnt/sdcard文件夹下吧
person.xml
<?xml version="1.0" encoding="UTF-8"?><persons> <person id = "1"> <name>沙瑞金</name> <phoneNumber>17673156987</phoneNumber> </person> <person id = "2"> <name>赵东来</name> <phoneNumber>13008965489</phoneNumber> </person> <person id = "3"> <name>刘大</name> <phoneNumber>15276321254</phoneNumber> </person> <person id = "4"> <name>侯亮平</name> <phoneNumber>18963985236</phoneNumber> </person> <person id = "5"> <name>高育良</name> <phoneNumber>17584563215</phoneNumber> </person></persons>
效果图展示:
0 0
- 移动应用开发Android通讯录导入小工具
- android 开发小工具
- Android开发小工具总结
- Android开发实用小工具
- Android开发实用小工具
- 转载:Android 开发小工具
- ANDROID开发实用小工具
- Android开发实用小工具
- Android开发之小工具
- # Android 开发实用小工具
- EXCEL导入小工具
- Android工具:Android开发实用小工具
- OSGI bundle in android 开发小工具
- Android开发中的实用小工具
- 分享个android开发小工具类
- Android 开发小工具之:Custom Tabs
- Android 开发的几个代码小工具
- android 开发的19个小工具
- codeforces 798a Mike and palindrome 水题
- 第223讲:Spark Shuffle Pluggable框架ShuffleReader解析
- linux安装rz、sz上传下载文件工具
- qt5 使用oracle简单实例
- jsp页面使用EL表达式输出Java中的Date对象
- 移动应用开发Android通讯录导入小工具
- 2016 ICPC 大连 C Game of Taking Stones 【威佐夫博弈+大数+高精度】
- Python leetcode #2 Add Two Numbers
- python爬虫--selenium等待页面加载
- ubuntu下使用intellij运行CloudSimSDN的示例
- 441. Arranging Coins
- compileSdkVersion、targetSdkVersion、Support库的作用与他们之间的关系
- FormatMessage函数
- ASP.NET MVC 常用扩展点:过滤器、模型绑定等