国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android系統(tǒng)的五種數(shù)據(jù)存儲形式實例(二)

2019-12-12 04:23:50
字體:
來源:轉載
供稿:網(wǎng)友

之前介紹了Android系統(tǒng)下三種數(shù)據(jù)存儲形式,//m.survivalescaperooms.com/article/99468.htm。今天補充介紹另外兩種,分別是內容提供者和網(wǎng)絡存儲。有些人可能認為內存提供者和網(wǎng)絡存儲更偏向于對數(shù)據(jù)的操作而不是數(shù)據(jù)的存儲,但這兩種方式確實與數(shù)據(jù)有關,所以這里還是將這兩種形式簡要的說明一下。

 Content Provider:

Content Provider,中文名是內存提供者,Android四大組件之一,內容提供者是應用程序之間共享數(shù)據(jù)的接口,以數(shù)據(jù)庫形式存入手機內存,可以共享自己的數(shù)據(jù)給其他應用使用。之所以需要設計一個單獨的控件來操作數(shù)據(jù),是為了實現(xiàn)應用程序之間的數(shù)據(jù)傳遞。通過查看DDMS中的目錄結構可以看出,數(shù)據(jù)庫文件對于其他應用來說是不可讀、不可寫,而日常生活中又需要獲取其他應用的數(shù)據(jù),尤其是系統(tǒng)自帶軟件的數(shù)據(jù)。比如打開QQ或者微信時會提示是否同步聯(lián)系人,又比如備份短信的時候,這些都需要訪問和操作其他應用的數(shù)據(jù)庫。因此谷歌工程師在底層軟件中集成了大量的方法利用內存提供者的原理,類似于在數(shù)據(jù)庫中提供一個對外訪問的路徑,供其他應用訪問。

為了更好的理解內存提供者的工作原理,可以自定義一個內容提示者來幫助理解。首先寫一個類繼承ContentProvider,實現(xiàn)該類中的方法,包括一些增刪改查和數(shù)據(jù)初始化的方法,可以在方法中實現(xiàn)對數(shù)據(jù)庫的增刪改查操作。數(shù)據(jù)庫本來是不對外開放的,所以為保護數(shù)據(jù),類中的方法原始返回數(shù)據(jù)均是空類型。為保證數(shù)據(jù)的安全性,可以創(chuàng)建一個UriMatcher對象,利用addURIf方法添加Uri的路徑規(guī)則,在每一次進行數(shù)據(jù)操作時先判斷傳入的路徑是否符合命名規(guī)則。使用內存提供者需要在配置文件中添加provider標簽,指定主機名。只有當訪問者與內容提供者的主機名一致時,才可以建立數(shù)據(jù)連接。在另一個應用中實現(xiàn)對內存提供者的訪問。具體操作是:創(chuàng)建內容提供者解析器,定義要訪問的Uri的路徑。Uri路徑有著固定的格式:”content://主機名/匹配字符”。 利用內容提供者解析器進行增刪改查,和要操作的數(shù)據(jù)庫之間建立聯(lián)系。以上內容通常用來理解內容提供者的工作原理,實際工作中很少用到自定義的內容提示者。實際中用的比較多的是用內容提供者操作系統(tǒng)聯(lián)系人、系統(tǒng)短信等系統(tǒng)應用的數(shù)據(jù)庫。

內容提供者操作系統(tǒng)應用時相對簡單,需要用到的大部分程序已經(jīng)在底層實現(xiàn),要做的是調用各種方法和相關的參數(shù)。需要關注的參數(shù)有Uri路徑、數(shù)據(jù)庫的表單結構。可以通過查看底層的代碼獲取相應的參數(shù)。其中有些常用的參數(shù)可以記下來,方便調用。比如獲取全部短信的Uri路徑是: content://sms。與聯(lián)系人有關的數(shù)據(jù)庫表單有三個raw_contacts、data、mimetypes。操作raw_contacts 表的Uri是: content://com.android.contacts/raw_contacts,操作data 表的Uri是:content://com.android.contacts/data。本文以短信的備份、還原來演示利用內容提供者訪問短信數(shù)據(jù)庫。

 先看一下短信和手機聯(lián)系人有關的數(shù)據(jù)庫所在的路徑。短信在Android 模擬器下存放在的路徑是:/data/data/com.android.providers.telephony/databases/目錄,聯(lián)系人在Android 模擬器下存放在的路徑是:/data/data/com.android.providers.contacts/databases/目錄。對于短信數(shù)據(jù)庫我們關心的表數(shù)據(jù)有:address、type、body、date,分別表示發(fā)送者號碼、短信類型(收還是發(fā))、短信內容、日期。對于聯(lián)系人數(shù)據(jù)庫的三張表一定要按照一定的順序依次查找才能得到相關的數(shù)據(jù),在這不做解釋。盡管開發(fā)的時候不需要了解短信和手機聯(lián)系人的數(shù)據(jù)庫路徑,但是要明白短信和手機聯(lián)系人的數(shù)據(jù)是存在數(shù)據(jù)庫中的,同時數(shù)據(jù)庫對外是不開放的。

與短信有關的數(shù)據(jù)庫的目錄結構:

本文給出的案例是短信的備份和還原,從而實現(xiàn)對系統(tǒng)應用數(shù)據(jù)庫的操作。首先利用內容提供者查詢到短信數(shù)據(jù)庫里的詳細參數(shù),將該數(shù)據(jù)以Xml文件的形式存入到指定的文件夾。利用xml解析得到數(shù)據(jù),將獲取的數(shù)據(jù)存在一個工具類中,這樣就能用ListView將數(shù)據(jù)顯示在界面上。具體實現(xiàn)如下。

package com.example.contentprovider; import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.util.ArrayList;import java.util.List; import org.xmlpull.v1.XmlPullParser;import org.xmlpull.v1.XmlSerializer; import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.util.Log;import android.util.Xml;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;/** * 短信的備份和還原 * 添加寫短信和讀短信的權限 * <uses-permission android:name="android.permission.READ_SMS"/>  <uses-permission android:name="android.permission.WRITE_SMS"/> * @author Huang */ public class MainActivity extends Activity {  private static final String TAG = "MainActivity";  private ListView lv;  private List<Person> mlist;  private Myadpter adapter;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    lv = (ListView) findViewById(R.id.lv);    datafresh();  }  //數(shù)據(jù)刷新,一般用到ListView時最好記得刷新數(shù)據(jù)否則不顯示  public void datafresh(){    mlist = getList();    if(adapter == null){      adapter = new Myadpter();    }else {      adapter.notifyDataSetChanged();    }  }  //用ListView顯示短信內容  public class Myadpter extends BaseAdapter{    public int getCount() {      // TODO Auto-generated method stub      return mlist.size();    }    public Object getItem(int position) {      // TODO Auto-generated method stub      return null;    }    public long getItemId(int position) {      // TODO Auto-generated method stub      return 0;    }    public View getView(int position, View convertView, ViewGroup parent) {      TextView tv = new TextView(MainActivity.this);      tv.setText(mlist.get(position).toString());      return tv;    }  }  //短信備份   public void bankup(View view){    ContentResolver resolver = getContentResolver();    Uri uri = Uri.parse("content://sms");    Cursor cursor = resolver.query(uri, new String[]{"address","body","type","date"}, null, null, null);    while(cursor.moveToNext()){      String address = cursor.getString(0);      String body = cursor.getString(1);      String type = cursor.getString(2);      String date = cursor.getString(3);      //序列化,把短信以Xml文件的形式存儲      XmlSerializer serializer = Xml.newSerializer();      File file = new File(getFilesDir(),"info.xml");      try {        FileOutputStream fos = new FileOutputStream(file);        serializer.setOutput(fos, "utf-8");        serializer.startDocument("utf-8", true);        serializer.startTag(null, "person");                 serializer.startTag(null, "address");        serializer.text(address);        serializer.endTag(null, "address");                 serializer.startTag(null, "body");        serializer.text(body);        serializer.endTag(null, "body");                 serializer.startTag(null, "type");        serializer.text(type);        serializer.endTag(null, "type");                 serializer.startTag(null, "date");        serializer.text(date);        serializer.endTag(null, "date");                 serializer.endTag(null, "person");        serializer.endDocument();        fos.close();//       Toast.makeText(this, "數(shù)據(jù)保存成功", 0).show();      } catch (Exception e) {        // TODO Auto-generated catch block        e.printStackTrace();      }    }  }   public void restore(View view){    datafresh();    lv.setAdapter(adapter);  }  //利用Xml解析得到短信內容  private List<Person> getList() {    ContentResolver resolver = getContentResolver();    List<Person> list = new ArrayList();//創(chuàng)建一個Person類存儲標簽內容    Person p = new Person();    File file = new File(getFilesDir(),"info.xml");    XmlPullParser pullParser = Xml.newPullParser();    try {      FileInputStream fis = new FileInputStream(file);      pullParser.setInput(fis, "utf-8");      int mtype = pullParser.getEventType();      while(mtype != XmlPullParser.END_DOCUMENT){        String name = pullParser.getName();        switch (mtype){        case XmlPullParser.START_TAG:          if("address".equals(name)){            String address = pullParser.nextText();            p.setAddress(address);          }else if("body".equals(name)){            String body = pullParser.nextText();            p.setBody(body);          }else if("type".equals(name)){            String type = pullParser.nextText();            p.setType(type);          }else if("date".equals(name)){            String date = pullParser.nextText();            p.setDate(date);          }          break;        case XmlPullParser.END_TAG:          if("person".equals(name)){            list.add(p);          }          break;        }        mtype = pullParser.next();      }      Log.i(TAG, list.toString());      return list;    } catch (Exception e) {      // TODO Auto-generated catch block      e.printStackTrace();      return null;    }  }} 

效果演示,我的虛擬機中只存了一條短信:

網(wǎng)絡存儲:

網(wǎng)絡存儲是最容易理解的一種存儲方式了。其實說簡單點就是文件的上傳和下載。經(jīng)常聽到的云備份就是這種形式。優(yōu)勢也很明顯,即把數(shù)據(jù)存儲到服務器,不存儲在本地,使用的時候直接從網(wǎng)絡獲取,避免了手機端信息丟失以及其他的安全隱患。因此,對于這種形式就不作多的解釋,直接給出一個文件的上傳和下載的實例來演示網(wǎng)絡存儲。

代碼實現(xiàn):

package com.example.upload;import java.io.File;import java.io.FileNotFoundException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import org.apache.http.Header;import com.loopj.android.http.AsyncHttpClient;import com.loopj.android.http.AsyncHttpResponseHandler;import com.loopj.android.http.RequestParams;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.text.TextUtils;import android.view.Menu;import android.view.View;import android.widget.EditText;import android.widget.ImageView;import android.widget.Toast;public class MainActivity extends Activity {  protected static final int SUCCESS = 1;  protected static final int ERORR = 2;  private EditText et_path;  private ImageView iv;  //訪問網(wǎng)絡操作耗時,需要在子線程中加一個代理  private Handler handler = new Handler(){    @Override    public void handleMessage(Message msg) {      switch (msg.what) {      case SUCCESS:        Bitmap bm = (Bitmap) msg.obj;        iv.setImageBitmap(bm);        break;      case ERORR:        Toast.makeText(MainActivity.this, "圖片獲取失敗", 0).show();        break;      }      super.handleMessage(msg);    }};    @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    et_path = (EditText) findViewById(R.id.et_path);    iv = (ImageView) findViewById(R.id.iv);  }  //上傳程序  public void upload(View view){//    String path = et_path.getText().toString().trim();//    這里為方便把路徑寫死,這種方式不太正規(guī),一般可以讀et_path來訪問    String path = "/mnt/sdcard/info.txt";    if(TextUtils.isEmpty(path)){      Toast.makeText(this, "路徑不能為空", 0).show();      return;    }    File file = new File(path);    AsyncHttpClient client = new AsyncHttpClient();    RequestParams param = new RequestParams();    try {      param.put("file", file);    } catch (FileNotFoundException e) {      // TODO Auto-generated catch block      e.printStackTrace();    }    client.post("http://192.168.1.114:8080/",param, new AsyncHttpResponseHandler() {            @Override      public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {        // TODO Auto-generated method stub        Toast.makeText(MainActivity.this, "提交成功", 0).show();      }            @Override      public void onFailure(int statusCode, Header[] headers,          byte[] responseBody, Throwable error) {        // TODO Auto-generated method stub        Toast.makeText(MainActivity.this, "提交失敗", 0).show();      }    });  }  //下載程序    public void download(View view){    new Thread(){      public void run() {        try {          //這里為方便把路徑寫死,可以讀et_path來訪問,兩者結果一樣          URL url = new URL("http://192.168.1.114:8080/demo1.png");          HttpURLConnection conn = (HttpURLConnection) url.openConnection();          conn.setConnectTimeout(5000);          conn.setRequestMethod("GET");          int code = conn.getResponseCode();          if(code == 200){            InputStream is = conn.getInputStream();            Bitmap bitmap = BitmapFactory.decodeStream(is);            Message msg = Message.obtain();            msg.what = SUCCESS;            msg.obj = bitmap;            handler.sendMessage(msg);            is.close();          }        } catch (Exception e) {          // TODO Auto-generated catch block          e.printStackTrace();           Message msg = Message.obtain();           msg.what = ERORR;           handler.sendMessage(msg);        }      };    }.start();  }}

至此五種數(shù)據(jù)存儲全部實現(xiàn)。當然,實際開發(fā)中可能比這更復雜,會嵌入到別的知識點中,但數(shù)據(jù)操作無疑是最為基本的一步,是整體項目開發(fā)的基礎。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 双牌县| 原平市| 衢州市| 逊克县| 印江| 上思县| 卢氏县| 衡阳县| 琼结县| 历史| 阜城县| 黄浦区| 雷州市| 江都市| 塔河县| 安陆市| 深州市| 巴塘县| 天峻县| 嘉善县| 永胜县| 林口县| 孝昌县| 荥阳市| 朝阳区| 西乌珠穆沁旗| 湘潭县| 马龙县| 准格尔旗| 高安市| 汽车| 汤阴县| 二连浩特市| 榆中县| 英德市| 大兴区| 太仓市| 平武县| 蒲江县| 莎车县| 和田县|