选择、搜索国家码&数据库表转Json文件

本文介绍了一个在App应用开发中常用的场景:在注册时选择手机号注册,涉及国家或地区码归属的选择和搜索功能。通过Android应用实现国家码数据库表转Json文件的功能,包括搜索国家码、数据库表信息转Json文件等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

选择、搜索国家码&数据库表转Json文件
一、应用场景
            
       首先, 话不多说了,有图有真像,这里先上几张效果图:
             
       第一张截图来自facebook,第二张来自我们的应用
                                            后面3张来自我这次要分享的效果截图

       由此可以看出,这部分的内容在实际的App应用开发中,还是经常用到的。
比如我们在注册时, 可以选择手机号注册,而手机号是有国家或地区码归属的,
而国家和地区码相对较多,需要提供 用户搜索功能的需求。

       二、Demo工程目录


然后在AndroidManifest.xml中加入SDcard读写权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

、Demo源码文件
1. activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.mobile.countrycode.MainActivity"
    tools:ignore="MergeRootFrame" >
    
    <Button 
        android:id="@+id/select_country_code"
        android:layout_width="match_parent"
   		android:layout_height="44dp"
   		android:text="选择国家 "
   		android:layout_marginLeft="10dp"
    	android:layout_marginRight="10dp"
   		android:background="#440000ff"
   		android:gravity="center"
   		android:textSize="20sp" />
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginLeft="10dp"
    	android:layout_marginRight="10dp"
        android:orientation="horizontal" >
        
        <EditText 
	        android:id="@+id/search_country_code"
	        android:layout_width="match_parent"
	   		android:layout_height="40dp"
	   		android:layout_gravity="center_vertical"
	   		android:gravity="center"
	   		android:layout_weight="1"
	   		android:hint="搜索内容" />
        
        <Button 
            android:id="@+id/search"
	        android:layout_width="match_parent"
	   		android:layout_height="40dp"
	   		android:layout_gravity="center_vertical"
	   		android:visibility="visible"
	   		android:layout_weight="4"
	   		android:gravity="center"
	   		android:text="搜索" />
        
    </LinearLayout>
    
    <ListView android:id="@+id/list_country_code"
        android:layout_width="match_parent"
        android:visibility="visible"
   		android:layout_height="match_parent">
    </ListView>
    
</LinearLayout>
2、adapter_country_code.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:orientation="horizontal" >
    
    <TextView 
        android:id="@+id/country_name"
        android:text="中国"
        android:layout_weight="1"
        android:gravity="left|center_vertical"
        android:textSize="18sp"
        android:layout_width="match_parent"
    	android:layout_height="40dp" />
    
    <TextView 
        android:id="@+id/country_code"
        android:text="+86"
        android:layout_weight="1"
        android:gravity="right|center_vertical"
        android:layout_width="match_parent"
        android:textSize="18sp"
    	android:layout_height="40dp" />
    
</LinearLayout>
3、MainActivity.java
package com.mobile.countrycode;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import android.app.Activity;
import android.content.res.AssetManager;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.mobile.countrycode.adapters.CountryCodeAdapter;
import com.mobile.countrycode.db.dao.CountryCodeDao;
import com.mobile.countrycode.domain.CountryCode;
import com.mobile.countrycode.utils.FileUtils;

public class MainActivity extends Activity {
	private static final String TAG = MainActivity.class.getSimpleName();
	private SQLiteDatabase db;
	private static final String externalPath = Environment
			.getExternalStorageDirectory().getAbsolutePath() + File.separator;
	private static final int BUFFERED_SIZE = 1024;
	
	private ListView listView;
	private CountryCodeAdapter adapter;
	private List<CountryCode> countryCodeInfos;
	private List<CountryCode> searchInfos;
	private Button search;
	private EditText searchCountryCode;
	private Button selectCountryCode;
	private String databasePath;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        requestWindowFeature(Window.FEATURE_NO_TITLE); //无title
        getWindow().setFlags(
        		WindowManager.LayoutParams.FLAG_FULLSCREEN, 
        		WindowManager.LayoutParams.FLAG_FULLSCREEN); //全屏
        setContentView(R.layout.activity_main);
        
        listView = (ListView) findViewById(R.id.list_country_code);
        searchCountryCode = (EditText) findViewById(R.id.search_country_code);
        search = (Button) findViewById(R.id.search);
        selectCountryCode = (Button) findViewById(R.id.select_country_code);
        
        initData(); //初始化一些数据
        
    }

	private void initData() {
		// "/data/data/com.mobile.countrycode/files/area.db"
		Log.i(TAG, "数据库文件路径是: " + getFilesDir() + File.separator + "area.db");
		databasePath = getFilesDir() + File.separator + "area.db";
		copyDB("area.db");
        db = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.OPEN_READONLY);
        
        countryCodeInfos = CountryCodeDao.findAll(databasePath);
        adapter = new CountryCodeAdapter(countryCodeInfos, this);
        listView.setAdapter(adapter);
        
        search.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				String keyword = searchCountryCode.getText().toString().trim();
				if(TextUtils.isEmpty(keyword)) {
					Toast.makeText(getApplicationContext(), "搜索关键字不能为空", Toast.LENGTH_LONG).show();
					countryCodeInfos = CountryCodeDao.findAll(databasePath);
			        adapter = new CountryCodeAdapter(countryCodeInfos, getApplicationContext());
				} else {
					searchInfos = CountryCodeDao.fuzzySearch(databasePath, keyword);
					adapter = new CountryCodeAdapter(searchInfos, getApplicationContext());
				}
				listView.setAdapter(adapter);
		        adapter.notifyDataSetChanged();
			}
		});
        
        selectCountryCode.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				selectCountryCode.setText("将国家码信息转Json文件");
				tableInfo2JsonFile();
			}
		});
        
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				CountryCode countryCode = countryCodeInfos.get(position);
				int country_code = countryCode.getCountry_code();
				String country_name = countryCode.getCountry_name_cn();
				Toast.makeText(getApplicationContext(), "+" + country_code + " " + country_name, 
					Toast.LENGTH_LONG).show();
			}
		});
	}

    /**
     * 拷贝资产目录下的数据库文件
     * @param fileName 数据库名
     */
	private void copyDB(String fileName) {
		File file = new File(getFilesDir(), fileName);
		if(file.exists() && file.length() > 0){
			Log.i(TAG, "数据库文件已经拷贝过了,无需重复拷贝");
		} else {
			try {
				// 数据库文件只需要拷贝一次,如果已经拷贝成功了。以后就不需要重复的拷贝了
				AssetManager am = getAssets();
				InputStream is = am.open(fileName);
				// 创建一个文件 /data/data/包名/files/area.db
				FileOutputStream fos = new FileOutputStream(file);
				byte[] buffer = new byte[BUFFERED_SIZE];
				int len = 0;
				while ((len = is.read(buffer)) != -1) {
					fos.write(buffer, 0, len);
				}
				is.close();
				fos.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 数据库表信息转成json文件
	 */
	public void tableInfo2JsonFile(){
		Toast.makeText(this, "将国家码数据库表信息转Json", Toast.LENGTH_LONG).show();
		JsonArray array = new JsonArray();
		for(CountryCode countryCode : CountryCodeDao.findAll(databasePath)){
			JsonObject jsonObject = new JsonObject();
			
			jsonObject.addProperty("country_id", countryCode.getCountry_id());
			jsonObject.addProperty("country_code", countryCode.getCountry_code());
			jsonObject.addProperty("country_name_en", countryCode.getCountry_name_en());
			jsonObject.addProperty("country_name_cn", countryCode.getCountry_name_cn());
			jsonObject.addProperty("ab", countryCode.getAb());
			
			array.add(jsonObject); // 生成json数组
		}
		
		try { 
			// writeFile(jsonObject.toString());
			// writeFile(array.toString()); 
			writeFile(array);// 写到SDCard
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
	
	/**
	 * 为了提高写入的效率,使用了字符流的缓冲区。 
     * 创建了一个字符写入流的缓冲区对象,并和指定要被缓冲的流对象相关联。
	 * @param array
	 * @throws IOException
	 */
	private void writeFile(JsonArray array) throws IOException {
		FileWriter fw = new FileWriter(FileUtils.getFilePath(externalPath, "countryCode.json"),true);
		BufferedWriter bufw = new BufferedWriter(fw);
		//使用缓冲区中的方法将数据写入到缓冲区中。
		bufw.write(array.toString());
		bufw.newLine();
		//使用缓冲区中的方法,将数据刷新到目的地文件中去。
		bufw.flush();
		//关闭缓冲区,同时关闭了fw流对象 
		bufw.close();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		db.close();
	}
	
}
4、CountryCodeAdapter.java
package com.mobile.countrycode.adapters;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.mobile.countrycode.R;
import com.mobile.countrycode.domain.CountryCode;

public class CountryCodeAdapter extends BaseAdapter {
	private List<CountryCode> countryCodeInfos;
	private Context context;
	
	public CountryCodeAdapter(List<CountryCode> countryCodeInfos,
			Context context) {
		this.countryCodeInfos = countryCodeInfos;
		this.context = context;
	}

	@Override
	public int getCount() {
		return countryCodeInfos.size();
	}

	@Override
	public CountryCode getItem(int position) {
		return countryCodeInfos.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		if (null == convertView) {
			holder = new ViewHolder();
			convertView = LayoutInflater.from(context).inflate(R.layout.adapter_country_code, null);
			holder.countryName = (TextView) convertView.findViewById(R.id.country_name);
			holder.countryCode = (TextView) convertView.findViewById(R.id.country_code);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		CountryCode countryCode = getItem(position);
		holder.countryName.setText(countryCode.getCountry_name_cn());
		holder.countryCode.setText("+"+String.valueOf(countryCode.getCountry_code()));
		return convertView;
	}
	
	static class ViewHolder {
		TextView countryName;
		TextView countryCode;
	}

}
5、CountryCode.java
package com.mobile.countrycode.domain;

public class CountryCode {
	private int country_id; //序号id
	private int country_code; //国家码
	private String country_name_en; //英文名
	private String country_name_cn; //中文名
	private String ab; //字母简称
	
	public int getCountry_id() {
		return country_id;
	}
	public void setCountry_id(int country_id) {
		this.country_id = country_id;
	}
	public int getCountry_code() {
		return country_code;
	}
	public void setCountry_code(int country_code) {
		this.country_code = country_code;
	}
	public String getCountry_name_en() {
		return country_name_en;
	}
	public void setCountry_name_en(String country_name_en) {
		this.country_name_en = country_name_en;
	}
	public String getCountry_name_cn() {
		return country_name_cn;
	}
	public void setCountry_name_cn(String country_name_cn) {
		this.country_name_cn = country_name_cn;
	}
	public String getAb() {
		return ab;
	}
	public void setAb(String ab) {
		this.ab = ab;
	}
	
	@Override
	public String toString() {
		return "CountryCode [country_id=" + country_id + ", country_code="
				+ country_code + ", country_name_en=" + country_name_en
				+ ", country_name_cn=" + country_name_cn + ", ab=" + ab + "]";
	}
	
}
6、CountryCodeDao.java
package com.mobile.countrycode.db.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.mobile.countrycode.domain.CountryCode;

public class CountryCodeDao {
	/*
	  * 判断是关键字否为整数 
	  * @param keyword 传入的字符串 
	  * @return 是整数返回true,否则返回false 
	*/
	public static boolean isInteger(String keyword) {  
		Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");  
		return pattern.matcher(keyword).matches();  
	}
	
	/**
	 * 模糊查找
	 * @param keyword
	 * @return
	 */
	public static List<CountryCode> fuzzySearch(String databasePath, String keyword){
		String sql = "select country_code,country_name_cn,country_name_en,ab from country ";
		SQLiteDatabase db = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.OPEN_READONLY);
		if (isInteger(keyword)) {
			int searchNum = Integer.parseInt(keyword);
			sql = sql + "where country_code like '%" + searchNum + "%'" + "order by country_code,ab";
			// db.query("country", new String[]{"country_code", "country_name_cn", "country_name_en", "ab"}, 
			// "country_code like '%?%'", new String[]{keyword} , null, null, "country_code,ab");
		} else {
			sql = sql + "where country_name_cn like '%" + keyword + "%'" + "order by country_code,ab";
		}
		Cursor cursor = db.rawQuery(sql, null);
		List<CountryCode> infos = new ArrayList<CountryCode>();
		
		while(cursor.moveToNext()) {
			CountryCode countryCode = new CountryCode();
			
			int country_code = cursor.getInt(cursor.getColumnIndex("country_code"));
			String country_name_en = cursor.getString(cursor.getColumnIndex("country_name_en"));
			String country_name_cn = cursor.getString(cursor.getColumnIndex("country_name_cn"));
			String ab = cursor.getString(cursor.getColumnIndex("ab")).trim();
			
			countryCode.setCountry_code(country_code);
			countryCode.setCountry_name_en(country_name_en.trim());
			countryCode.setCountry_name_cn(country_name_cn.trim());
			countryCode.setAb(ab.trim());
			
			infos.add(countryCode);
		}
		return infos;
	}
	
	/**
	 * 获取全部的国家代码信息
	 * @return
	 */
	public static List<CountryCode> findAll(String databasePath){
		SQLiteDatabase db = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.OPEN_READONLY);
		String sql = "select country_id,country_code,country_name_en,country_name_cn,ab from country";
		Cursor cursor = db.rawQuery(sql, null);
		// Cursor cursor = db.query("country", new String[]{"country_id", "country_code", "country_name_en",
		//		"country_name_cn", "ab"}, null, null, null, null, null);
		List<CountryCode> infos = new ArrayList<CountryCode>();
		
		while(cursor.moveToNext()){
			CountryCode countryCode = new CountryCode();
			
			int country_id = cursor.getInt(cursor.getColumnIndex("country_id"));
			int country_code = cursor.getInt(cursor.getColumnIndex("country_code"));
			String country_name_en = cursor.getString(cursor.getColumnIndex("country_name_en"));
			String country_name_cn = cursor.getString(cursor.getColumnIndex("country_name_cn"));
			String ab = cursor.getString(cursor.getColumnIndex("ab"));
			
			countryCode.setCountry_id(country_id);
			countryCode.setCountry_code(country_code);
			countryCode.setCountry_name_en(country_name_en.trim());
			countryCode.setCountry_name_cn(country_name_cn.trim());
			countryCode.setAb(ab.trim());
			
			infos.add(countryCode);
		}
		cursor.close();
		db.close();
		return infos;
	}
	
}
7、FileUtils.java
package com.mobile.countrycode.utils;

import java.io.File;

public class FileUtils {
	/**
	 * 根据文件路径和文件名返回文件对象
	 * @param filePath
	 * @param fileName
	 * @return
	 */
	public static File getFilePath(String filePath, String fileName) {
		File file = null;
		makeRootDirectory(filePath);
		
		try {
			file = new File(filePath + fileName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return file;
	}
	
	/**
	 * 根据文件路径判断是否创建文件目录
	 * @param filePath
	 */
	public static void makeRootDirectory(String filePath) {
		File file = null;
		try {
			file = new File(filePath);
			if (!file.exists()) {
				file.mkdir();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
四、Demo功能解释
       1、可以按关键字,也可以靠数字搜索模糊搜索出包含此关键字的国家名和国家码。
       2、按顶部的title(其实是一个按钮),可以将Sqlite数据库表信息转成Json文件。
                      资源链接:
                    1)Demo源码
                    2)Sqlite数据库area.db
                    3)  生成的Json文件 countryCode.json
                   4)  gson-2.24.jar
            注:生成的countryCode.json在SDCard上的格式是一行的,可以到开源中国
                   JSON在线解析工具  格式化。
                   area.db里还包含全国的省市信息。



                     

                                

       












评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值