标签:
首先声明,我这里大体是讲的一个关于“Android配置文件分享和JSON数据生成与解析”的整体流程,具体数据库中的数据根据读者自己的项目来安排,如果您看不大懂也请您原谅,毕竟我说了,我只是新手。其实关于数据库中的数据你只需要知道他们都是一个个对象,然后有各自的属性就行了,我们的关键在于JSON数据的生成与解析。
鉴于自己的是个博客新手,感觉自己的博客访问量有些少可能是因为自己确实知识匮乏,毕竟我早就说了,我不适合编程,但是没办法啊,我要去读个文学博士的话,怕是要遭人白眼了,故而以后的事情可以以后再说,当下还是要编程的,这也是没有办法的事情。好了,不多说了,办正事。
首先是配置文件分享:
第一代码段:
//配置文件分享Function private void shareConfiguration() { // Get configuration data. //这是配置文件的名字,文件是JSON类型的 String fileName = "configurationData" + System.currentTimeMillis() + ".json"; //这个是从数据库中取数据以便于写到配置文件中,后面还要说到 String configuration = mDBManager.getDataBaseAsJson(); // Create the temporal file within the private application folder, //将上述从数据库中读取的数据写入到配置文件 tmpSharingFile = Utils.writeToSDFile(fileName, configuration); if (tmpSharingFile == null) { //如果配置文件中没有任何数据,就提示一个错误信息 Toast.makeText(this, getString(R.string.error_sharing_configuration), Toast.LENGTH_SHORT).show(); return; } //弹出一个分享对话框 Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); //将配置文件数据放到分享数据流中 shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tmpSharingFile)); //这个是分享对话框标题 shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getString(R.string.share_configuration)); //shareIntent.setType("application/json"); //这里是指定分享文件的类型,我们可以选择任意的二进制数据类型,以便于支持多种分享接口 shareIntent.setType("application/octet-stream"); //用于分享配置文件成功后,删除本地暂存的配置文件 startActivityForResult(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)), SHARING_RESULT_CODE); }
<span style="font-size:18px;"> @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == SHARING_RESULT_CODE) { if (tmpSharingFile != null) { tmpSharingFile.delete(); } } }</span>
<span style="font-size:18px;"> /** * Get the database as a json format. * * @return json containing the database. */ public synchronized String getDataBaseAsJson() { JSONObject objJson = new JSONObject(); try { // 用于存储所有Devices条目. JSONArray jsonDevices = new JSONArray(); List<Device> devices = getAllDevicesList();//从数据库中查询所有的Device数据存储到列表中 for (int i = 0; i < devices.size(); i++) { //遍历得到的Device数据列表 Device device = devices.get(i); JSONObject deviceJson = new JSONObject(); //将Device的所有属性信息以键值对的形式放入deviceJson(JSONObject类型),在接收端会根据键(Key)来获取对应的值(Value) deviceJson.put(KEY_DEVICE_ID, device.getDeviceID()); deviceJson.put(KEY_DEVICE_NAME, device.getName()); deviceJson.put(KEY_DEVICE_ASSOCIATED,1); deviceJson.put(KEY_DEVICE_HASH, device.getDeviceHash()); deviceJson.put(KEY_DEVICE_APPEARANCE, device.getAppearance()); deviceJson.put(KEY_DEVICE_MODEL_LOW, device.getModelLow()); deviceJson.put(KEY_DEVICE_MODEL_HIGH, device.getModelHigh()); deviceJson.put(KEY_DEVICE_NUM_GROUPS, device.getNumGroups()); // 存储每个Device所属分组的ID组成的数组(int型)如{1,2,3} JSONArray jsonGroups = new JSONArray(); int[] groups = device.getGroups(); for (int j = 0 ; j < groups.length; j++) { jsonGroups.put(groups[j]); } deviceJson.put(KEY_DEVICE_GROUPS, jsonGroups); deviceJson.put(KEY_DEVICE_AUTH_CODE, device.getAuthCode()); jsonDevices.put(deviceJson); } //将所有的Device条目jsonDevices(JSONArray类型)存储到objJson(JSONObject类型)中 objJson.put(KEY_DEVICES_LIST, jsonDevices); //存储所有的分组数据 JSONArray jsonAreas = new JSONArray(); List<Area> areas = getAllAreaList(); for (int i = 0; i < areas.size(); i++) { Area area = areas.get(i); //存储每一条分组数据到areaJson同时将areaJson添加到jsonAreas中 JSONObject areaJson = new JSONObject(); areaJson.put(KEY_AREA_NAME, area.getName()); areaJson.put(KEY_AREA_ID, area.getAreaID()); jsonAreas.put(areaJson); } //将所有的Area条目 jsonAreas(JSONArray类型)存储到objJson(JSONObject类型)中 objJson.put(KEY_AREAS_LIST, jsonAreas); } catch (Exception e) { return null; } //以字符串的形式返回objJson,用于生成本地的JSON文件,具体请见第一代码段 return objJson.toString(); }</span>第四代码段:
<span style="font-size:18px;">/** * Method to write text characters to file on SD card. * * @param filename * @param text * @return */ static public File writeToSDFile(String filename, String text) { //获取外部存储介质的根目录 File root = android.os.Environment.getExternalStorageDirectory(); //获取根目录的绝对路径并在该路径下新建文件 File dir = new File(root.getAbsolutePath()); dir.mkdirs(); //指定新建文件的名称 File file = new File(dir, filename); try { //指定输出文件 FileOutputStream f = new FileOutputStream(file); //打印数据工具类 PrintWriter pw = new PrintWriter(f); //将text写入到文件file中 pw.println(text); //将输出缓冲区的所有数据一次性写入,然后关闭文件输出流 pw.flush(); pw.close(); f.close(); } catch (Exception e) { e.printStackTrace(); return null; } //返回一个文件对象,用于后续操作,具体请见第一代码段中的tmpSharingFile return file; } </span>好了,经过上面的一系列操作,我们已经成功地把数据库中的Device和Area数据在本地生成了JSON文件,并通过调用第三方接口分享出去。那么我们如何来接受并解析JSON文件呢?不要着急,接下来我们还是用代码说话。
第五代码段:
//选择要导入到数据库中的JSON文件 private void pickFileToImport() { //打开系统的文件管理功能 Intent intent = new Intent(Intent.ACTION_GET_CONTENT); //intent.setType("file/*"); intent.setType("application/json"); startActivityForResult(intent, PICKFILE_RESULT_CODE); }第六代码段:
<span style="font-size:18px;"> @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK) { //新Activity成功关闭并返回数据 if (data == null || data.getData() == null) { //如果返回数据为空,则给出错误提示信息 Toast.makeText(getApplicationContext(), getString(R.string.error_opening_file), Toast.LENGTH_SHORT).show(); return; } //根据得到的data参数获取到data中存储的文件路径(文件全称) Uri uri = data.getData(); //根据data存储的路径新建一个文件file对象 File file = new File(uri.getPath()); // Check the extension of the file. App only accept .json extensions. if (!Utils.getFileExtension(file).equalsIgnoreCase(".json")) { //如果文件file的类型不是.JSON,则给出错误提示信息,具体请见第七代码段 Toast.makeText(this, getString(R.string.invalid_file_extension), Toast.LENGTH_SHORT).show(); // no continue. return; } //Start reading a file...开始读取文件数据 //为什么使用StringBuilder而不是StringBuffer可以参考我的另一篇博客 http://blog.csdn.net/songkai320/article/details/51823246 final StringBuilder json = new StringBuilder(); try { //读取文件数据并放到缓冲区 BufferedReader br = new BufferedReader(new FileReader(file)); String line; while ((line = br.readLine()) != null) { //从缓冲区读取数据并存储到json对象中 json.append(line); } br.close(); } catch (IOException e) { Toast.makeText(getApplicationContext(), getString(R.string.error_opening_file), Toast.LENGTH_SHORT).show(); return; } // end reading file // Confirm replacing database. //将json(StringBuilder类型)转换为字符串格式 mImportedJson = json.toString(); if (mEditMode) { //如果处于编辑修改模式,则用导入的数据覆盖当前的数据,具体请见第八代码段 confirmReplacingDatabase(mImportedJson); } else { //如果处于新建模式,则直接将数据导入到本地数据库中 DialogMaterial infoDialog = new DialogMaterial(this, getString(R.string.import_notify_title), getString(R.string.import_notify)); infoDialog.addCancelButton("OK"); infoDialog.show(); } } }</span>第七代码段:
<span style="font-size:18px;">/** * Get the extension of a file. * * @param file * @return extension. */ static public String getFileExtension(File file) { String name = file.getName(); try { return name.substring(name.lastIndexOf(".")); } catch (Exception e) { return ""; } }</span>
<span style="font-size:18px;">private void confirmReplacingDatabase(final String json) { //弹出一个对话框问你是不是要覆盖当前数据,点击“是”开始导入JSON数据 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(getString(R.string.confirm_replacing_db)); builder.setCancelable(false); builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { new Thread(new Runnable() { @Override public void run() { //覆盖原来的数据,具体请见第九代码段 replaceDatabase(json); } }).start(); } }); builder.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create(); alert.show(); }</span>
<span style="font-size:18px;">private void replaceDatabase(String json) { //首先从JSON字符串中得到Device列表,这也是JSON文件解析的关键地方,鉴于这个属性太多,我们选择用<span style="font-family: Arial, Helvetica, sans-serif;">Area的解析作为示例,具体请见第十代码段</span> List<Device> devices = mDBManager.getListDevicesByJson(json, mPlace.getId()); //同上,只不过是Area列表数据 List<Area> areas = mDBManager.getListAreasByJson(json, mPlace.getId()); if (devices == null || areas == null) { runOnUiThread(new Runnable() { public void run() { //如果从JSON字符串中取到的数据为null,那么就给出错误提示信息 Toast.makeText(DetailPlaceActivity.this, R.string.error_importing_db, Toast.LENGTH_SHORT).show(); } }); } else { // 首先删除所有的当前Device数据,以便于导入新的数据来替代 mDBManager.removeAllDevicesByPlaceId(mPlace.getId()); // 然后删除所有的当前Area数据,以便于导入新的数据来替代 mDBManager.removeAreaOfPlaceWithId(mPlace.getId()); for (int i = 0; i < devices.size(); i++) { //将从JSON字符串中解析得到的Device数据一一添加到本地数据库 mDBManager.createOrUpdateDevice(devices.get(i)); } for (int i = 0; i < areas.size(); i++) { //将从JSON字符串中解析得到的Area数据一一添加到本地数据库 mDBManager.createOrUpdateArea(areas.get(i)); } runOnUiThread(new Runnable() { public void run() { //弹出新数据导入成功的提示信息 Toast.makeText(DetailPlaceActivity.this, R.string.db_imported, Toast.LENGTH_SHORT).show(); } }); //更新数据库 mDeviceManager.refreshInfo(); } } </span>第十代码段:
<span style="font-size:18px;"> /** * Create a list of Area objects from JSON. * @param json JSON string containing the description of the areas. * @param placeId The place id to use for the areas. * @return A list of Area objects. */ public synchronized List<Area> getListAreasByJson(String json, int placeId) { List<Area> areas = new ArrayList<>(); try { //通过JSON字符串生成一个JSONObject对象,其实和生成JSON文件的过程大致相反 JSONObject jsonObj = new JSONObject(json); //根据键(Key)KEY_AREAS_LIST获取到Area列表的数据jsonArray JSONArray jsonArray = jsonObj.getJSONArray(KEY_AREAS_LIST); for (int areasIndex = 0; areasIndex < jsonArray.length(); areasIndex++) { Area area = new Area(); //从jsonArray中根据Area的属性每次取出一组数据赋给新建的area对象并添加到areas(List<Area>类型)中 String areaName = jsonArray.getJSONObject(areasIndex).getString(KEY_AREA_NAME); area.setName(areaName); int areaId = jsonArray.getJSONObject(areasIndex).getInt(KEY_AREA_ID); area.setAreaID(areaId); area.setPlaceID(placeId); areas.add(area); } } catch (JSONException e) { return null; } //返回所有的Area数据,以便于插入到本地数据库,具体见第九代码段 return areas; }</span>
标签:
原文地址:http://blog.csdn.net/songkai320/article/details/51829025