移动应用开发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
原创粉丝点击