转载:http://blog.youkuaiyun.com/amazing7/article/details
1、概述
Android提供了5种方式来让用户保存持久化应用程序数据。根据自己的需求来做选择,比如数据是否是应用程序私有的,是否能被其他程序访问,需要多少数据存储空间等,分别是:
① 使用SharedPreferences存储数据
② 文件存储数据
③ SQLite数据库存储数据
④ 使用ContentProvider存储数据
⑤ 网络存储数据
Android提供了一种方式来暴露你的数据(甚至是私有数据)给其他应用程序 - ContentProvider。它是一个可选组件,可公开读写你应用程序数据。
2、SharedPreferences存储 |
SharedPreference类提供了一个总体框架,使您可以保存和检索的任何基本数据类型( boolean, float, int, long, string)的持久键-值对(基于XML文件存储的“key-value”键值对数据)。
通常用来存储程序的一些配置信息。其存储在“data/data/程序包名/shared_prefs目录下。
xml 处理时Dalvik会通过自带底层的本地XML Parser解析,比如XMLpull方式,这样对于内存资源占用比较好。
2.1 我们可以通过以下两种方法获取SharedPreferences对象(通过Context):
① getSharedPreferences (String name, int mode)
当我们有多个SharedPreferences的时候,根据第一个参数name获得相应的SharedPreferences对象。
② getPreferences (int mode)
如果你的Activity中只需要一个SharedPreferences的时候使用。
这里的mode有四个选项:
<code class="hljs mathematica has-numbering"><span class="hljs-keyword">Context</span>.MODE_PRIVATE</code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>
该SharedPreferences数据只能被本应用程序读、写。
<code class="hljs mathematica has-numbering"><span class="hljs-keyword">Context</span>.MODE_WORLD_READABLE</code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>
该SharedPreferences数据能被其他应用程序读,但不能写。
<code class="hljs mathematica has-numbering"><span class="hljs-keyword">Context</span>.MODE_WORLD_WRITEABLE</code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>
该SharedPreferences数据能被其他应用程序读和写。
<code class="hljs mathematica has-numbering"><span class="hljs-keyword">Context</span>.MODE_MULTI_PROCESS</code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>
sdk2.3后添加的选项,当多个进程同时读写同一个SharedPreferences时它会检查文件是否修改。
2.2 向Shared Preferences中写入值
首先要通过 SharedPreferences.Editor获取到Editor对象;
然后通过Editor的putBoolean() 或 putString()等方法存入值;
最后调用Editor的commit()方法提交;
<code class="hljs avrasm has-numbering">//Use <span class="hljs-number">0</span> <span class="hljs-keyword">or</span> MODE_PRIVATE for the default operation SharedPreferences settings = getSharedPreferences(<span class="hljs-string">"fanrunqi"</span>, <span class="hljs-number">0</span>)<span class="hljs-comment">;</span> SharedPreferences<span class="hljs-preprocessor">.Editor</span> editor = settings<span class="hljs-preprocessor">.edit</span>()<span class="hljs-comment">;</span> editor<span class="hljs-preprocessor">.putBoolean</span>(<span class="hljs-string">"isAmazing"</span>, true)<span class="hljs-comment">; </span> // 提交本次编辑 editor<span class="hljs-preprocessor">.commit</span>()<span class="hljs-comment">;</span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul>
同时Edit还有两个常用的方法:
editor.remove(String key) :下一次commit的时候会移除key对应的键值对
editor.clear():移除所有键值对
2.3 从Shared Preferences中读取值
读取值使用 SharedPreference对象的getBoolean()或getString()等方法就行了(没Editor 啥子事)。
<code class="hljs java has-numbering">SharedPreferences settings = getSharedPreferences(<span class="hljs-string">"fanrunqi"</span>, <span class="hljs-number">0</span>); <span class="hljs-keyword">boolean</span> isAmazing= settings.getBoolean(<span class="hljs-string">"isAmazing"</span>,<span class="hljs-keyword">true</span>);</code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>
2.4 Shared Preferences的优缺点
可以看出来Preferences是很轻量级的应用,使用起来也很方便,简洁。但存储数据类型比较单一(只有基本数据类型),无法进行条件查询,只能在不复杂的存储需求下使用,比如保存配置信息等。
3、文件数据存储 |
3.1 使用内部存储
当文件被保存在内部存储中时,默认情况下,文件是应用程序私有的,其他应用不能访问。当用户卸载应用程序时这些文件也跟着被删除。
文件默认存储位置:/data/data/包名/files/文件名。
3.1.1 创建和写入一个内部存储的私有文件:
① 调用Context的openFileOutput()函数,填入文件名和操作模式,它会返回一个FileOutputStream对象。
② 通过FileOutputStream对象的write()函数写入数据。
③ FileOutputStream对象的close ()函数关闭流。
例如:
<code class="hljs avrasm has-numbering"> String FILENAME = <span class="hljs-string">"a.txt"</span><span class="hljs-comment">;</span> String string = <span class="hljs-string">"fanrunqi"</span><span class="hljs-comment">;</span> try { FileOutputStream fos = openFileOutput(FILENAME, Context<span class="hljs-preprocessor">.MODE</span>_PRIVATE)<span class="hljs-comment">;</span> fos<span class="hljs-preprocessor">.write</span>(string<span class="hljs-preprocessor">.getBytes</span>())<span class="hljs-comment">;</span> fos<span class="hljs-preprocessor">.close</span>()<span class="hljs-comment">;</span> } catch (Exception e) { e<span class="hljs-preprocessor">.printStackTrace</span>()<span class="hljs-comment">;</span> }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul>
在 openFileOutput(String name, int mode)方法中
-
name参数: 用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。
-
mode参数:用于指定操作模式,分为四种:
Context.MODE_PRIVATE = 0
为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容。
Context.MODE_APPEND = 32768
该模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
Context.MODE_WORLD_READABLE = 1
表示当前文件可以被其他应用读取。
MODE_WORLD_WRITEABLE
表示当前文件可以被其他应用写入。
3.1.2 读取一个内部存储的私有文件:
① 调用openFileInput( ),参数中填入文件名,会返回一个FileInputStream对象。
② 使用流对象的 read()方法读取字节
③ 调用流的close()方法关闭流
例如:
<code class="hljs go has-numbering"> String FILENAME = <span class="hljs-string">"a.txt"</span>; try { FileInputStream inStream = openFileInput(FILENAME); <span class="hljs-typename">int</span> <span class="hljs-built_in">len</span> =<span class="hljs-number"> 0</span>; <span class="hljs-typename">byte</span>[] buf = <span class="hljs-built_in">new</span> <span class="hljs-typename">byte</span><span class="hljs-number">[1024</span>]; StringBuilder sb = <span class="hljs-built_in">new</span> StringBuilder(); while ((<span class="hljs-built_in">len</span> = inStream.read(buf)) !=<span class="hljs-number"> -1</span>) { sb.<span class="hljs-built_in">append</span>(<span class="hljs-built_in">new</span> String(buf,<span class="hljs-number"> 0</span>, <span class="hljs-built_in">len</span>)); } inStream.<span class="hljs-built_in">close</span>(); } catch (Exception e) { e.printStackTrace(); } </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li></ul>
其他一些经常用到的方法:
-
getFilesDir(): 得到内存储文件的绝对路径
-
getDir(): 在内存储空间中创建或打开一个已经存在的目录
-
deleteFile(): 删除保存在内部存储的文件。
-
fileList(): 返回当前由应用程序保存的文件的数组(内存储目录下的全部文件)。
3.1.3 保存编译时的静态文件
如果你想在应用编译时保存静态文件,应该把文件保存在项目的 res/raw/ 目录下,你可以通过 openRawResource()方法去打开它(传入参数R.raw.filename),这个方法返回一个 InputStream流对象你可以读取文件但是不能修改原始文件。
<code class="hljs avrasm has-numbering">InputStream is = this<span class="hljs-preprocessor">.getResources</span>()<span class="hljs-preprocessor">.openRawResource</span>(R<span class="hljs-preprocessor">.raw</span><span class="hljs-preprocessor">.filename</span>)<span class="hljs-comment">;</span></code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>
3.1.4 保存内存缓存文件
有时候我们只想缓存一些数据而不是持久化保存,可以使用getCacheDir()去打开一个文件,文件的存储目录( /data/data/包名/cache )是一个应用专门来保存临时缓存文件的内存目录。
当设备的内部存储空间比较低的时候,Android可能会删除这些缓存文件来恢复空间,但是你不应该依赖系统来回收,要自己维护这些缓存文件把它们的大小限制在一个合理的范围内,比如1MB.当你卸载应用的时候这些缓存文件也会被移除。
3.2 使用外部存储(sdcard)
因为内部存储容量限制,有时候需要存储数据比较大的时候需要用到外部存储,使用外部存储分为以下几个步骤:
3.2.1 添加外部存储访问限权
首先,要在AndroidManifest.xml中加入访问SDCard的权限,如下:
<code class="hljs xml has-numbering"> <span class="hljs-comment"><!-- 在SDCard中创建与删除文件权限 --></span> <span class="hljs-tag"><<span class="hljs-title">uses-permission</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"android.permission.MOUNT_UNMOUNT_FILESYSTEMS"</span>/></span> <span class="hljs-comment"><!-- 往SDCard写入数据权限 --></span> <span class="hljs-tag"><<span class="hljs-title">uses-permission</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"android.permission.WRITE_EXTERNAL_STORAGE"</span>/></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>
3.2.2 检测外部存储的可用性
在使用外部存储时我们需要检测其状态,它可能被连接到计算机、丢失或者只读等。下面代码将说明如何检查状态:
<code class="hljs lasso has-numbering"><span class="hljs-comment">//获取外存储的状态</span> <span class="hljs-built_in">String</span> state <span class="hljs-subst">=</span> Environment<span class="hljs-built_in">.</span>getExternalStorageState(); <span class="hljs-keyword">if</span> (Environment<span class="hljs-built_in">.</span>MEDIA_MOUNTED<span class="hljs-built_in">.</span><span class="hljs-keyword">equals</span>(state)) { <span class="hljs-comment">// 可读可写</span> mExternalStorageAvailable <span class="hljs-subst">=</span> mExternalStorageWriteable <span class="hljs-subst">=</span> <span class="hljs-literal">true</span>; } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Environment<span class="hljs-built_in">.</span>MEDIA_MOUNTED_READ_ONLY<span class="hljs-built_in">.</span><span class="hljs-keyword">equals</span>(state)) { <span class="hljs-comment">// 可读</span> } <span class="hljs-keyword">else</span> { <span class="hljs-comment">// 可能有很多其他的状态,但是我们只需要知道,不能读也不能写 </span> }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul>
3.2.3 访问外部存储器中的文件
1、如果 API 版本大于或等于8,使用
getExternalFilesDir (String type)
该方法打开一个外存储目录,此方法需要一个类型,指定你想要的子目录,如类型参数DIRECTORY_MUSIC和 DIRECTORY_RINGTONES(传null就是你应用程序的文件目录的根目录)。通过指定目录的类型,确保Android的媒体扫描仪将扫描分类系统中的文件(例如,铃声被确定为铃声)。如果用户卸载应用程序,这个目录及其所有内容将被删除。
例如:
<code class="hljs vhdl has-numbering"><span class="hljs-keyword">File</span> <span class="hljs-keyword">file</span> = <span class="hljs-keyword">new</span> <span class="hljs-keyword">File</span>(getExternalFilesDir(<span class="hljs-keyword">null</span>), <span class="hljs-string">"fanrunqi.jpg"</span>);</code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>
2、如果API 版本小于 8 (7或者更低)
getExternalStorageDirectory ()
通过该方法打开外存储的根目录,你应该在以下目录下写入你的应用数据,这样当卸载应用程序时该目录及其所有内容也将被删除。
<code class="hljs haskell has-numbering">/<span class="hljs-type">Android</span>/<span class="hljs-typedef"><span class="hljs-keyword">data</span>/<package_name>/files/</span></code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>
读写数据:
<code class="hljs go has-numbering"><span class="hljs-keyword">if</span>(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ File sdCardDir = Environment.getExternalStorageDirectory();<span class="hljs-comment">//获取SDCard目录 "/sdcard" </span> File saveFile = <span class="hljs-built_in">new</span> File(sdCardDir,<span class="hljs-string">"a.txt"</span>); <span class="hljs-comment">//写数据</span> try { FileOutputStream fos= <span class="hljs-built_in">new</span> FileOutputStream(saveFile); fos.write(<span class="hljs-string">"fanrunqi"</span>.getBytes()); fos.<span class="hljs-built_in">close</span>(); } catch (Exception e) { e.printStackTrace(); } <span class="hljs-comment">//读数据</span> try { FileInputStream fis= <span class="hljs-built_in">new</span> FileInputStream(saveFile); <span class="hljs-typename">int</span> <span class="hljs-built_in">len</span> <span class="hljs-number">=0</span>; <span class="hljs-typename">byte</span>[] buf = <span class="hljs-built_in">new</span> <span class="hljs-typename">byte</span><span class="hljs-number">[1024</span>]; StringBuffer sb = <span class="hljs-built_in">new</span> StringBuffer(); while((<span class="hljs-built_in">len</span>=fis.read(buf))!<span class="hljs-number">=-1</span>){ sb.<span class="hljs-built_in">append</span>(<span class="hljs-built_in">new</span> String(buf,<span class="hljs-number"> 0</span>, <span class="hljs-built_in">len</span>)); } fis.<span class="hljs-built_in">close</span>(); } catch (Exception e) { e.printStackTrace(); } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li></ul>
我们也可以在 /Android/data/package_name/cache/目录下做外部缓存。
部分翻译于:android-data-storage
4、 网络存储数据 |
HttpUrlConnection
HttpUrlConnection是Java.net包中提供的API,我们知道Android SDK是基于Java的,所以当然优先考虑HttpUrlConnection这种最原始最基本的API,其实大多数开源的联网框架基本上也是基于JDK的HttpUrlConnection进行的封装罢了,掌握HttpUrlConnection需要以下几个步骤:
1、将访问的路径转换成URL。
URL url = new URL(path);
2、通过URL获取连接。
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
3、设置请求方式。
conn.setRequestMethod(GET);
4、设置连接超时时间。
conn.setConnectTimeout(5000);
5、设置请求头的信息。
conn.setRequestProperty(User-Agent, Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0));
7、针对不同的响应码,做不同的操作(请求码200,表明请求成功,获取返回内容的输入流)
工具类:
<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StreamTools</span> {</span> <span class="hljs-javadoc">/** * 将输入流转换成字符串 * *<span class="hljs-javadoctag"> @param</span> is * 从网络获取的输入流 *<span class="hljs-javadoctag"> @return</span> */</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">streamToString</span>(InputStream is) { <span class="hljs-keyword">try</span> { ByteArrayOutputStream baos = <span class="hljs-keyword">new</span> ByteArrayOutputStream(); <span class="hljs-keyword">byte</span>[] buffer = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[<span class="hljs-number">1024</span>]; <span class="hljs-keyword">int</span> len = <span class="hljs-number">0</span>; <span class="hljs-keyword">while</span> ((len = is.read(buffer)) != -<span class="hljs-number">1</span>) { baos.write(buffer, <span class="hljs-number">0</span>, len); } baos.close(); is.close(); <span class="hljs-keyword">byte</span>[] byteArray = baos.toByteArray(); <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> String(byteArray); } <span class="hljs-keyword">catch</span> (Exception e) { Log.e(tag, e.toString()); <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>; } } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li></ul>
HttpUrlConnection发送GET请求
<code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">loginByGet</span>(String username, String password) { String path = http:<span class="hljs-comment">//192.168.0.107:8080/WebTest/LoginServerlet?username= + username + &password= + password;</span> <span class="hljs-keyword">try</span> { URL url = <span class="hljs-keyword">new</span> URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(<span class="hljs-number">5000</span>); conn.setRequestMethod(GET); <span class="hljs-keyword">int</span> code = conn.getResponseCode(); <span class="hljs-keyword">if</span> (code == <span class="hljs-number">200</span>) { InputStream <span class="hljs-keyword">is</span> = conn.getInputStream(); <span class="hljs-comment">// 字节流转换成字符串</span> <span class="hljs-keyword">return</span> StreamTools.streamToString(<span class="hljs-keyword">is</span>); } <span class="hljs-keyword">else</span> { <span class="hljs-keyword">return</span> 网络访问失败; } } <span class="hljs-keyword">catch</span> (Exception e) { e.printStackTrace(); <span class="hljs-keyword">return</span> 网络访问失败; } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li></ul>
HttpUrlConnection发送POST请求
<code class="hljs lasso has-numbering"><span class="hljs-keyword">public</span> static <span class="hljs-built_in">String</span> loginByPost(<span class="hljs-built_in">String</span> username, <span class="hljs-built_in">String</span> password) { <span class="hljs-built_in">String</span> path <span class="hljs-subst">=</span> http:<span class="hljs-comment">//192.168.0.107:8080/WebTest/LoginServerlet;</span> try { URL url <span class="hljs-subst">=</span> <span class="hljs-literal">new</span> URL(path); HttpURLConnection conn <span class="hljs-subst">=</span> (HttpURLConnection) url<span class="hljs-built_in">.</span>openConnection(); conn<span class="hljs-built_in">.</span>setConnectTimeout(<span class="hljs-number">5000</span>); conn<span class="hljs-built_in">.</span>setRequestMethod(POST); conn<span class="hljs-built_in">.</span>setRequestProperty(Content<span class="hljs-attribute">-Type</span>, application/x<span class="hljs-attribute">-www</span><span class="hljs-attribute">-form</span><span class="hljs-attribute">-urlencoded</span>); <span class="hljs-built_in">String</span> <span class="hljs-built_in">data</span> <span class="hljs-subst">=</span> username<span class="hljs-subst">=</span> <span class="hljs-subst">+</span> username <span class="hljs-subst">+</span> <span class="hljs-subst">&</span>password<span class="hljs-subst">=</span> <span class="hljs-subst">+</span> password; conn<span class="hljs-built_in">.</span>setRequestProperty(Content<span class="hljs-attribute">-Length</span>, <span class="hljs-built_in">data</span><span class="hljs-built_in">.</span>length() <span class="hljs-subst">+</span> ); <span class="hljs-comment">// POST方式,其实就是浏览器把数据写给服务器</span> conn<span class="hljs-built_in">.</span>setDoOutput(<span class="hljs-literal">true</span>); <span class="hljs-comment">// 设置可输出流</span> OutputStream os <span class="hljs-subst">=</span> conn<span class="hljs-built_in">.</span>getOutputStream(); <span class="hljs-comment">// 获取输出流</span> os<span class="hljs-built_in">.</span>write(<span class="hljs-built_in">data</span><span class="hljs-built_in">.</span>getBytes()); <span class="hljs-comment">// 将数据写给服务器</span> int code <span class="hljs-subst">=</span> conn<span class="hljs-built_in">.</span>getResponseCode(); <span class="hljs-keyword">if</span> (code <span class="hljs-subst">==</span> <span class="hljs-number">200</span>) { InputStream is <span class="hljs-subst">=</span> conn<span class="hljs-built_in">.</span>getInputStream(); <span class="hljs-keyword">return</span> StreamTools<span class="hljs-built_in">.</span>streamToString(is); } <span class="hljs-keyword">else</span> { <span class="hljs-keyword">return</span> 网络访问失败; } } catch (Exception e) { e<span class="hljs-built_in">.</span>printStackTrace(); <span class="hljs-keyword">return</span> 网络访问失败; } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li></ul>
HttpClient
HttpClient是开源组织Apache提供的Java请求网络框架,其最早是为了方便Java服务器开发而诞生的,是对JDK中的HttpUrlConnection各API进行了封装和简化,提高了性能并且降低了调用API的繁琐,Android因此也引进了这个联网框架,我们再不需要导入任何jar或者类库就可以直接使用,值得注意的是Android官方已经宣布不建议使用HttpClient了。
HttpClient发送GET请求
1、 创建HttpClient对象
2、创建HttpGet对象,指定请求地址(带参数)
3、使用HttpClient的execute(),方法执行HttpGet请求,得到HttpResponse对象
4、调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码
5、调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据
<code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">loginByHttpClientGet</span>(String username, String password) { String path = http:<span class="hljs-comment">//192.168.0.107:8080/WebTest/LoginServerlet?username=</span> + username + &password= + password; HttpClient client = <span class="hljs-keyword">new</span> DefaultHttpClient(); <span class="hljs-comment">// 开启网络访问客户端</span> HttpGet httpGet = <span class="hljs-keyword">new</span> HttpGet(path); <span class="hljs-comment">// 包装一个GET请求</span> <span class="hljs-keyword">try</span> { HttpResponse response = client.execute(httpGet); <span class="hljs-comment">// 客户端执行请求</span> <span class="hljs-keyword">int</span> code = response.getStatusLine().getStatusCode(); <span class="hljs-comment">// 获取响应码</span> <span class="hljs-keyword">if</span> (code == <span class="hljs-number">200</span>) { InputStream <span class="hljs-keyword">is</span> = response.getEntity().getContent(); <span class="hljs-comment">// 获取实体内容</span> String result = StreamTools.streamToString(<span class="hljs-keyword">is</span>); <span class="hljs-comment">// 字节流转字符串</span> <span class="hljs-keyword">return</span> result; } <span class="hljs-keyword">else</span> { <span class="hljs-keyword">return</span> 网络访问失败; } } <span class="hljs-keyword">catch</span> (Exception e) { e.printStackTrace(); <span class="hljs-keyword">return</span> 网络访问失败; } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li></ul>
HttpClient发送POST请求
1,创建HttpClient对象
2,创建HttpPost对象,指定请求地址
3,创建List,用来装载参数
4,调用HttpPost对象的setEntity()方法,装入一个UrlEncodedFormEntity对象,携带之前封装好的参数
5,使用HttpClient的execute()方法执行HttpPost请求,得到HttpResponse对象
6, 调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码
7, 调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据
<code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">loginByHttpClientPOST</span>(String username, String password) { String path = http:<span class="hljs-comment">//192.168.0.107:8080/WebTest/LoginServerlet;</span> <span class="hljs-keyword">try</span> { HttpClient client = <span class="hljs-keyword">new</span> DefaultHttpClient(); <span class="hljs-comment">// 建立一个客户端</span> HttpPost httpPost = <span class="hljs-keyword">new</span> HttpPost(path); <span class="hljs-comment">// 包装POST请求</span> <span class="hljs-comment">// 设置发送的实体参数</span> List parameters = <span class="hljs-keyword">new</span> ArrayList(); parameters.add(<span class="hljs-keyword">new</span> BasicNameValuePair(username, username)); parameters.add(<span class="hljs-keyword">new</span> BasicNameValuePair(password, password)); httpPost.setEntity(<span class="hljs-keyword">new</span> UrlEncodedFormEntity(parameters, UTF-<span class="hljs-number">8</span>)); HttpResponse response = client.execute(httpPost); <span class="hljs-comment">// 执行POST请求</span> <span class="hljs-keyword">int</span> code = response.getStatusLine().getStatusCode(); <span class="hljs-keyword">if</span> (code == <span class="hljs-number">200</span>) { InputStream <span class="hljs-keyword">is</span> = response.getEntity().getContent(); String result = StreamTools.streamToString(<span class="hljs-keyword">is</span>); <span class="hljs-keyword">return</span> result; } <span class="hljs-keyword">else</span> { <span class="hljs-keyword">return</span> 网络访问失败; } } <span class="hljs-keyword">catch</span> (Exception e) { e.printStackTrace(); <span class="hljs-keyword">return</span> 访问网络失败; } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li></ul>
参考:
Android提供的其他网络访问框架
HttpClient和HttpUrlConnection的两种网络访问方式编写网络代码,需要自己考虑很多,获取数据或许可以,但是如果要将手机本地数据上传至网络,根据不同的web端接口,需要组织不同的数据内容上传,给手机端造成了很大的工作量。
目前有几种快捷的网络开发开源框架,给我们提供了非常大的便利。下面是这些项目Github地址,有文档和Api说明。
android-async-http
5、 SQLite数据库存储数据 |
前面的文章 SQLite的使用入门已经做了详细说明,这里就不在多说了。
6、 使用ContentProvider存储数据 ContentProvider(内容提供者)是Android的四大组件之一,管理android以结构化方式存放的数据,以相对安全的方式封装数据(表)并且提供简易的处理机制和统一的访问接口供其他程序调用。 但注意ContentProvider它也只是一个中间人,真正操作的数据源可能是数据库,也可以是文件、xml或网络等其他存储方式。 2.URL URL(统一资源标识符)代表要操作的数据,可以用来标识每个ContentProvider,这样你就可以通过指定的URI找到想要的ContentProvider,从中获取或修改数据。
2.1MIMEMIME是指定某个扩展名的文件用一种应用程序来打开,就像你用浏览器查看PDF格式的文件,浏览器会选择合适的应用来打开一样。Android中的工作方式跟HTTP类似,ContentProvider会根据URI来返回MIME类型,ContentProvider会返回一个包含两部分的字符串。MIME类型一般包含两部分,如:
分为类型和子类型,Android遵循类似的约定来定义MIME类型,每个内容类型的Android MIME类型有两种形式:多条记录(集合)和单条记录。 集合记录: <code class="hljs avrasm has-numbering">vnd<span class="hljs-preprocessor">.android</span><span class="hljs-preprocessor">.cursor</span><span class="hljs-preprocessor">.dir</span>/自定义</code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul> 单条记录: <code class="hljs avrasm has-numbering">vnd<span class="hljs-preprocessor">.android</span><span class="hljs-preprocessor">.cursor</span><span class="hljs-preprocessor">.item</span>/自定义</code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul> vnd表示这些类型和子类型具有非标准的、供应商特定的形式。Android中类型已经固定好了,不能更改,只能区别是集合还是单条具体记录,子类型可以按照格式自己填写。 下面分别介绍Android系统提供了两个用于操作Uri的工具类:ContentUris和UriMatcher。 2.2 ContentUrisContetnUris包含一个便利的函数withAppendedId()来向URI追加一个id。 <code class="hljs avrasm has-numbering">Uri uri = Uri<span class="hljs-preprocessor">.parse</span>(<span class="hljs-string">"content://cn.scu.myprovider/user"</span>) Uri resultUri = ContentUris<span class="hljs-preprocessor">.withAppendedId</span>(uri, <span class="hljs-number">7</span>)<span class="hljs-comment">; </span> //生成后的Uri为:content://cn<span class="hljs-preprocessor">.scu</span><span class="hljs-preprocessor">.myprovider</span>/user/<span class="hljs-number">7</span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul> 同时提供parseId(uri)方法用于从URL中获取ID: <code class="hljs cs has-numbering">Uri uri = Uri.parse(<span class="hljs-string">"content://cn.scu.myprovider/user/7"</span>) <span class="hljs-keyword">long</span> personid = ContentUris.parseId(uri); <span class="hljs-comment">//获取的结果为:7</span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul> 2.3UriMatcherUriMatcher本质上是一个文本过滤器,用在contentProvider中帮助我们过滤,分辨出查询者想要查询哪个数据表。 举例说明:
<code class="hljs cs has-numbering">UriMatcher matcher = <span class="hljs-keyword">new</span> UriMatcher(UriMatcher.NO_MATCH); <span class="hljs-comment">//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码</span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>
<code class="hljs avrasm has-numbering">//USER 和 USER_ID是两个int型数据 matcher<span class="hljs-preprocessor">.addURI</span>(<span class="hljs-string">"cn.scu.myprovider"</span>, <span class="hljs-string">"user"</span>, USER)<span class="hljs-comment">;</span> matcher<span class="hljs-preprocessor">.addURI</span>(<span class="hljs-string">"cn.scu.myprovider"</span>, <span class="hljs-string">"user/#"</span>,USER_ID)<span class="hljs-comment">;</span> //如果match()方法匹配content://cn<span class="hljs-preprocessor">.scu</span><span class="hljs-preprocessor">.myprovider</span>/user路径,返回匹配码为USER</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul>
<code class="hljs java has-numbering"><span class="hljs-comment">/* * 如果操作集合,则必须以vnd.android.cursor.dir开头 * 如果操作非集合,则必须以vnd.android.cursor.item开头 * */</span> <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> String <span class="hljs-title">getType</span>(Uri uri) { Uri uri = Uri.parse(<span class="hljs-string">"content://"</span> + <span class="hljs-string">"cn.scu.myprovider"</span> + <span class="hljs-string">"/user"</span>); <span class="hljs-keyword">switch</span>(matcher.match(uri)){ <span class="hljs-keyword">case</span> USER: <span class="hljs-keyword">return</span> <span class="hljs-string">"vnd.android.cursor.dir/user"</span>; <span class="hljs-keyword">case</span> USER_ID: <span class="hljs-keyword">return</span> <span class="hljs-string">"vnd.android.cursor.item/user"</span>; } } </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul> 3.ContentProvider的主要方法
ContentProvider创建后 或 打开系统后其它应用第一次访问该ContentProvider时调用。
外部应用向ContentProvider中添加数据。
外部应用从ContentProvider删除数据。
外部应用更新ContentProvider中的数据。
供外部应用从ContentProvider中获取数据。
该方法用于返回当前Url所代表数据的MIME类型。 4.ContentResolverContentResolver通过URI来查询ContentProvider中提供的数据。除了URI以 外,还必须知道需要获取的数据段的名称,以及此数据段的数据类型。如果你需要获取一个特定的记录,你就必须知道当前记录的ID,也就是URI中D部分。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
实例代码: <code class="hljs actionscript has-numbering">ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse(<span class="hljs-string">"content://cn.scu.myprovider/user"</span>); <span class="hljs-comment">//添加一条记录</span> ContentValues values = <span class="hljs-keyword">new</span> ContentValues(); values.put(<span class="hljs-string">"name"</span>, <span class="hljs-string">"fanrunqi"</span>); values.put(<span class="hljs-string">"age"</span>, <span class="hljs-number">24</span>); resolver.insert(uri, values); <span class="hljs-comment">//获取user表中所有记录</span> Cursor cursor = resolver.query(uri, <span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">"userid desc"</span>); <span class="hljs-keyword">while</span>(cursor.moveToNext()){ <span class="hljs-comment">//操作</span> } <span class="hljs-comment">//把id为1的记录的name字段值更改新为finch</span> ContentValues updateValues = <span class="hljs-keyword">new</span> ContentValues(); updateValues.put(<span class="hljs-string">"name"</span>, <span class="hljs-string">"finch"</span>); Uri updateIdUri = ContentUris.withAppendedId(uri, <span class="hljs-number">1</span>); resolver.update(updateIdUri, updateValues, <span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>); <span class="hljs-comment">//删除id为2的记录</span> Uri deleteIdUri = ContentUris.withAppendedId(uri, <span class="hljs-number">2</span>); resolver.<span class="hljs-keyword">delete</span>(deleteIdUri, <span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>);</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li></ul> 5.ContentObserverContentObserver(内容观察者),目的是观察特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它. <code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Activity</span> {</span> <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword">super</span>.onCreate(savedInstanceState); setContentView(R.layout.activity_main); <span class="hljs-comment">//注册观察者Observser </span> <span class="hljs-keyword">this</span>.getContentResolver().registerContentObserver(Uri.parse(<span class="hljs-string">"content://sms"</span>),<span class="hljs-keyword">true</span>,<span class="hljs-keyword">new</span> SMSObserver(<span class="hljs-keyword">new</span> Handler())); } <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SMSObserver</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ContentObserver</span> {</span> <span class="hljs-keyword">public</span> <span class="hljs-title">SMSObserver</span>(Handler handler) { <span class="hljs-keyword">super</span>(handler); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onChange</span>(<span class="hljs-keyword">boolean</span> selfChange) { Cursor cursor = MainActivity.<span class="hljs-keyword">this</span>.getContentResolver().query( Uri.parse(<span class="hljs-string">"content://sms/inbox"</span>), <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>); <span class="hljs-keyword">while</span> (cursor.moveToNext()) { StringBuilder sb = <span class="hljs-keyword">new</span> StringBuilder(); sb.append(<span class="hljs-string">"address="</span>).append( cursor.getString(cursor.getColumnIndex(<span class="hljs-string">"address"</span>))); sb.append(<span class="hljs-string">";subject="</span>).append( cursor.getString(cursor.getColumnIndex(<span class="hljs-string">"subject"</span>))); sb.append(<span class="hljs-string">";body="</span>).append( cursor.getString(cursor.getColumnIndex(<span class="hljs-string">"body"</span>))); sb.append(<span class="hljs-string">";time="</span>).append( cursor.getLong(cursor.getColumnIndex(<span class="hljs-string">"date"</span>))); System.out.println(<span class="hljs-string">"--------has Receivered SMS::"</span> + sb.toString()); } } } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li></ul> 同时可以在ContentProvider发生数据变化时调用 <code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserContentProvider</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ContentProvider</span> {</span> <span class="hljs-keyword">public</span> Uri <span class="hljs-title">insert</span>(Uri uri, ContentValues values) { db.insert(<span class="hljs-string">"user"</span>, <span class="hljs-string">"userid"</span>, values); getContext().getContentResolver().notifyChange(uri, <span class="hljs-keyword">null</span>); } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul> 6.实例说明数据源是SQLite, 用ContentResolver操作ContentProvider。 Constant.Java(储存一些常量) <code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Constant</span> {</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String TABLE_NAME = <span class="hljs-string">"user"</span>; <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String COLUMN_ID = <span class="hljs-string">"_id"</span>; <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String COLUMN_NAME = <span class="hljs-string">"name"</span>; <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String AUTOHORITY = <span class="hljs-string">"cn.scu.myprovider"</span>; <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> ITEM = <span class="hljs-number">1</span>; <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> ITEM_ID = <span class="hljs-number">2</span>; <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String CONTENT_TYPE = <span class="hljs-string">"vnd.android.cursor.dir/user"</span>; <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String CONTENT_ITEM_TYPE = <span class="hljs-string">"vnd.android.cursor.item/user"</span>; <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> Uri CONTENT_URI = Uri.parse(<span class="hljs-string">"content://"</span> + AUTOHORITY + <span class="hljs-string">"/user"</span>); } </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li></ul> DBHelper.java(操作数据库) <code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DBHelper</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">SQLiteOpenHelper</span> {</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String DATABASE_NAME = <span class="hljs-string">"finch.db"</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> DATABASE_VERSION = <span class="hljs-number">1</span>; <span class="hljs-keyword">public</span> <span class="hljs-title">DBHelper</span>(Context context) { <span class="hljs-keyword">super</span>(context, DATABASE_NAME, <span class="hljs-keyword">null</span>, DATABASE_VERSION); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(SQLiteDatabase db) <span class="hljs-keyword">throws</span> SQLException { <span class="hljs-comment">//创建表格 </span> db.execSQL(<span class="hljs-string">"CREATE TABLE IF NOT EXISTS "</span>+ Constant.TABLE_NAME + <span class="hljs-string">"("</span>+ Constant.COLUMN_ID +<span class="hljs-string">" INTEGER PRIMARY KEY AUTOINCREMENT,"</span> + Constant.COLUMN_NAME +<span class="hljs-string">" VARCHAR NOT NULL);"</span>); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onUpgrade</span>(SQLiteDatabase db, <span class="hljs-keyword">int</span> oldVersion, <span class="hljs-keyword">int</span> newVersion) <span class="hljs-keyword">throws</span> SQLException { <span class="hljs-comment">//删除并创建表格 </span> db.execSQL(<span class="hljs-string">"DROP TABLE IF EXISTS "</span>+ Constant.TABLE_NAME+<span class="hljs-string">";"</span>); onCreate(db); } } </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li></ul> MyProvider.java(自定义的ContentProvider) <code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyProvider</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ContentProvider</span> {</span> DBHelper mDbHelper = <span class="hljs-keyword">null</span>; SQLiteDatabase db = <span class="hljs-keyword">null</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> UriMatcher mMatcher; <span class="hljs-keyword">static</span>{ mMatcher = <span class="hljs-keyword">new</span> UriMatcher(UriMatcher.NO_MATCH); mMatcher.addURI(Constant.AUTOHORITY,Constant.TABLE_NAME, Constant.ITEM); mMatcher.addURI(Constant.AUTOHORITY, Constant.TABLE_NAME+<span class="hljs-string">"/#"</span>, Constant.ITEM_ID); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> String <span class="hljs-title">getType</span>(Uri uri) { <span class="hljs-keyword">switch</span> (mMatcher.match(uri)) { <span class="hljs-keyword">case</span> Constant.ITEM: <span class="hljs-keyword">return</span> Constant.CONTENT_TYPE; <span class="hljs-keyword">case</span> Constant.ITEM_ID: <span class="hljs-keyword">return</span> Constant.CONTENT_ITEM_TYPE; <span class="hljs-keyword">default</span>: <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"Unknown URI"</span>+uri); } } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> Uri <span class="hljs-title">insert</span>(Uri uri, ContentValues values) { <span class="hljs-comment">// TODO Auto-generated method stub </span> <span class="hljs-keyword">long</span> rowId; <span class="hljs-keyword">if</span>(mMatcher.match(uri)!=Constant.ITEM){ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"Unknown URI"</span>+uri); } rowId = db.insert(Constant.TABLE_NAME,<span class="hljs-keyword">null</span>,values); <span class="hljs-keyword">if</span>(rowId><span class="hljs-number">0</span>){ Uri noteUri=ContentUris.withAppendedId(Constant.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(noteUri, <span class="hljs-keyword">null</span>); <span class="hljs-keyword">return</span> noteUri; } <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> SQLException(<span class="hljs-string">"Failed to insert row into "</span> + uri); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onCreate</span>() { <span class="hljs-comment">// TODO Auto-generated method stub </span> mDbHelper = <span class="hljs-keyword">new</span> DBHelper(getContext()); db = mDbHelper.getReadableDatabase(); <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> Cursor <span class="hljs-title">query</span>(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { <span class="hljs-comment">// TODO Auto-generated method stub </span> Cursor c = <span class="hljs-keyword">null</span>; <span class="hljs-keyword">switch</span> (mMatcher.match(uri)) { <span class="hljs-keyword">case</span> Constant.ITEM: c = db.query(Constant.TABLE_NAME, projection, selection, selectionArgs, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>, sortOrder); <span class="hljs-keyword">break</span>; <span class="hljs-keyword">case</span> Constant.ITEM_ID: c = db.query(Constant.TABLE_NAME, projection,Constant.COLUMN_ID + <span class="hljs-string">"="</span>+uri.getLastPathSegment(), selectionArgs, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>, sortOrder); <span class="hljs-keyword">break</span>; <span class="hljs-keyword">default</span>: <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"Unknown URI"</span>+uri); } c.setNotificationUri(getContext().getContentResolver(), uri); <span class="hljs-keyword">return</span> c; } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">update</span>(Uri uri, ContentValues values, String selection, String[] selectionArgs) { <span class="hljs-comment">// TODO Auto-generated method stub </span> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">delete</span>(Uri uri, String selection, String[] selectionArgs) { <span class="hljs-comment">// TODO Auto-generated method stub</span> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; } } </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li></ul> MainActivity.java(ContentResolver操作) <code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Activity</span> {</span> <span class="hljs-keyword">private</span> ContentResolver mContentResolver = <span class="hljs-keyword">null</span>; <span class="hljs-keyword">private</span> Cursor cursor = <span class="hljs-keyword">null</span>; <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-comment">// TODO Auto-generated method stub</span> <span class="hljs-keyword">super</span>.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.tv); mContentResolver = getContentResolver(); tv.setText(<span class="hljs-string">"添加初始数据 "</span>); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">10</span>; i++) { ContentValues values = <span class="hljs-keyword">new</span> ContentValues(); values.put(Constant.COLUMN_NAME, <span class="hljs-string">"fanrunqi"</span>+i); mContentResolver.insert(Constant.CONTENT_URI, values); } tv.setText(<span class="hljs-string">"查询数据 "</span>); cursor = mContentResolver.query(Constant.CONTENT_URI, <span class="hljs-keyword">new</span> String[]{Constant.COLUMN_ID,Constant.COLUMN_NAME}, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>); <span class="hljs-keyword">if</span> (cursor.moveToFirst()) { String s = cursor.getString(cursor.getColumnIndex(Constant.COLUMN_NAME)); tv.setText(<span class="hljs-string">"第一个数据: "</span>+s); } } } </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li></ul> 最后在manifest申明 <code class="hljs xml has-numbering"><span class="hljs-tag"><<span class="hljs-title">provider</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"MyProvider"</span> <span class="hljs-attribute">android:authorities</span>=<span class="hljs-value">"cn.scu.myprovider"</span> /></span></code> |