第7章文件和数据
199.使用JSONObject解析JSON字符串
书中是给了一个JSON格式的String,然后通过JSONObject去解析。
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private String mString = "{\"name\":\"AAA\",\"book\":\"BBB\"}";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
JSONTokener jsonTokener = new JSONTokener(mString);
JSONObject jsonObject = (JSONObject) jsonTokener.nextValue();
Log.d(TAG," name = " + jsonObject.getString("name") + " book = " + jsonObject.getString("book"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
运行结果如下:
D/MainActivity: name = AAA book = BBB
200.使用JSONArray解析JSON字符串
书中是给了一个JSONArray格式的String,然后通过JSONObject去解析。
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private String mString = "[{\"name\":\"张三\",\"book\":\"AAA\"},{\"name\":\"李四\",\"book\":\"BBB\"}]";
//"{\"name\":\"AAA\",\"book\":\"BBB\"}";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
JSONArray jsonArray = new JSONArray(mString);
for (int i = 0; i < jsonArray.length(); i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.d(TAG," name = " + jsonObject.getString("name") + " book = " + jsonObject.getString("book"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
运行结果如下
201.使用JSONTokener解析JSON字符串
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private String mString = "大家系列:{\"name\":\"ABCD\",\"book\":\"EFGH\"}";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
JSONTokener jsonTokener = new JSONTokener(mString);
Log.d(TAG,jsonTokener.nextString('G'));//读取G之前的字符
} catch (JSONException e) {
e.printStackTrace();
}
}
}
运行结果如下。
D/MainActivity: 大家系列:{"name":"ABCD","book":"EF
202.使用JsonReader解析JSON字符串
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private String mString = "[{\"name\":\"张三\",\"book\":\"AAA\"},{\"name\":\"李四\",\"book\":\"BBB\"}]";
private String mInfo = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
JsonReader jsonReader = new JsonReader(new StringReader(mString));
jsonReader.beginArray();
while (jsonReader.hasNext()){
jsonReader.beginObject();
while (jsonReader.hasNext()){
String string = jsonReader.nextName();
if (string.equals("name")){
mInfo += "\n 作者" + jsonReader.nextString();
}else if (string.equals("book")){
mInfo += "\n 书名" + jsonReader.nextString();
}
}
jsonReader.endObject();
}
jsonReader.endArray();
Log.d(TAG,"mInfo = " + mInfo);
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果如下:
203.使用JSONStringer创建JSON字符串
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private String mString = "[{\"name\":\"张三\",\"book\":\"AAA\"},{\"name\":\"李四\",\"book\":\"BBB\"}]";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
JSONStringer jsonStringer = new JSONStringer();
//object 和endObject表示一个{} array 和 endArray表示一个[]
jsonStringer.array();
jsonStringer.object();
jsonStringer.key("name");
jsonStringer.value("张三");
jsonStringer.key("book");
jsonStringer.value("AAA");
jsonStringer.endObject();
jsonStringer.object();
jsonStringer.key("name");
jsonStringer.value("李四");
jsonStringer.key("book");
jsonStringer.value("BBB");
jsonStringer.endObject();
jsonStringer.object();
jsonStringer.key("name");
jsonStringer.value("王二");
jsonStringer.key("book");
jsonStringer.value("CCC");
jsonStringer.endObject();
jsonStringer.endArray();
Log.d(TAG,jsonStringer.toString());
} catch (JSONException ex) {
throw new RuntimeException(ex);
}
}
}
运行结果如下
D/MainActivity: [{"name":"张三","book":"AAA"},{"name":"李四","book":"BBB"},{"name":"王二","book":"CCC"}]
延伸阅读:
Android入门——数据解析之创建及使用JSON字符串(一)
https://blog.csdn.net/CrazyMo_/article/details/78297201
Android入门——数据解析之使用GSON解析JSON字符串(二)
https://blog.csdn.net/CrazyMo_/article/details/78518133
Json相关个人总结
首先来看什么是JSON。
//下面这段出自android编程权威指南。
JSON(JavaScript Object Notation)是近年流行开来的一种 数据格式,尤其适用于Web服务。Android提供了标准的org.json包,可以利用包里的一些类创建和解析JSON数据。Android开发者文档有其详细信息。要详细了解JSON数据格式,请访问其官方网站:http://json.org。
这个简单了解一下就好了,接下来看api。
为了了解JSON数据,需要先找一些api接口。直接开放的免费接口还是比较少的,大多数需要注册账号然后申请。我找了一点,链接如下所示。
整理一些完全免费开放的API接口
https://blog.csdn.net/qq_41856814/article/details/89290195
干货集中营 API 文档
http://gank.io/api
玩Android 开放API
https://www.wanandroid.com/blog/show/2
其实还可以用tomcat自行搭建一个服务器。参考链接如下。
使用struts手动搭建一个自己的tomcat服务器,用来返回json数据
//www.greatytc.com/p/42665afd987f
这里先使用一下这个api:
https://www.wanandroid.com//hotkey/json
直接在浏览器中访问这个链接,得到如下json数据。
{"data":[{"id":6,"link":"","name":"面试","order":1,"visible":1},{"id":9,"link":"","name":"Studio3","order":1,"visible":1},{"id":5,"link":"","name":"动画","order":2,"visible":1},{"id":1,"link":"","name":"自定义View","order":3,"visible":1},{"id":2,"link":"","name":"性能优化 速度","order":4,"visible":1},{"id":3,"link":"","name":"gradle","order":5,"visible":1},{"id":4,"link":"","name":"Camera 相机","order":6,"visible":1},{"id":7,"link":"","name":"代码混淆 安全","order":7,"visible":1},{"id":8,"link":"","name":"逆向 加固","order":8,"visible":1}],"errorCode":0,"errorMsg":""}
直接得到的json数据可读性并不好,需要转换一下。
使用在线格式化工具,格式化一下。
https://www.sojson.com/
{
"data": [{
"id": 6,
"link": "",
"name": "面试",
"order": 1,
"visible": 1
}, {
"id": 9,
"link": "",
"name": "Studio3",
"order": 1,
"visible": 1
}, {
"id": 5,
"link": "",
"name": "动画",
"order": 2,
"visible": 1
}, {
"id": 1,
"link": "",
"name": "自定义View",
"order": 3,
"visible": 1
}, {
"id": 2,
"link": "",
"name": "性能优化 速度",
"order": 4,
"visible": 1
}, {
"id": 3,
"link": "",
"name": "gradle",
"order": 5,
"visible": 1
}, {
"id": 4,
"link": "",
"name": "Camera 相机",
"order": 6,
"visible": 1
}, {
"id": 7,
"link": "",
"name": "代码混淆 安全",
"order": 7,
"visible": 1
}, {
"id": 8,
"link": "",
"name": "逆向 加固",
"order": 8,
"visible": 1
}],
"errorCode": 0,
"errorMsg": ""
}
204.使用JSONObject根据IP显示所在城市
2个知识点,1.通过api判断城市2.获取本机ip。
书上用的是新浪的判断城市的api,但是我试了一下无法访问。因此那部分略过。基本原理就是访问链接,然后解析返回的json数据,这些数据里面有城市的信息。
下面是获取本机ip的代码。
/***
* 使用WIFI时,获取本机IP地址
* @param mContext
* @return
*/
public static String getWIFILocalIpAdress(Context mContext) {
//获取wifi服务
WifiManager wifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
//判断wifi是否开启
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ip = formatIpAddress(ipAddress);
return ip;
}
private static String formatIpAddress(int ipAdress) {
return (ipAdress & 0xFF ) + "." +
((ipAdress >> 8 ) & 0xFF) + "." +
((ipAdress >> 16 ) & 0xFF) + "." +
( ipAdress >> 24 & 0xFF) ;
}
参考链接:
Android系统信息获取 之七:获取IP地址和MAC地址
https://blog.csdn.net/netwalk/article/details/9821937
205.使用Gson将数组转换成JSON字符串
206.使用Gson解析JSON字符串
205和206合并一下,可以看下面的链接。
参考链接:
Android使用Google Gson实现JSON字符串和对象、对象数组之间相互转换
https://blog.csdn.net/xiaoyao20161314/article/details/72459518
其实android studio中还可以用插件去本地化json。
参考链接:
Android Json转对象本地快速测试
//www.greatytc.com/p/b47ab8db56ae
207.使用XmlPullParser解析城市天气数据
这里书上是用的聚合数据的天气预报接口,并且代码里给出了key,但是好像这个接口是要钱的,首次申请送500次。所以跳过本节。
208.采用SAX方式解析XML文件内容
参考链接:
android 如何使用SAX解析XML
https://blog.csdn.net/bzlj2912009596/article/details/80262191
209.使用Pattern根据正则表达式校验手机号码
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG," result = " + isMobile("1xxxx"));//这里传入一个手机号码
}
/**
* 判断是否是手机号
*
* @param mobile
* @return
*/
public static boolean isMobile(String mobile) {
// "[1]"代表第1位为数字1,"[358]"代表第二位可以为3、5、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。
String regex = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$";
Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(mobile);
return m.matches();
}
}
D/MainActivity: result = true
参考链接:
2018手机号码正则表达式
https://blog.csdn.net/github_36344730/article/details/79757676
210.使用SharedPreferences保存账户和密码
参考链接:
Android——登录界面、SharedPreferences实现记住密码等账户信息
https://blog.csdn.net/xuejingfu1/article/details/51638684
211.使用ListPreference读写单选按钮值
这是一个PreferenceActivity使用的知识点。这个类我还真的从来没有见过。
PreferenceActivity使用介绍
https://blog.csdn.net/ezconn/article/details/91452516
212.在代码中获取CheckBoxPreference值
这里的知识点是CheckBoxPreference的使用。
参考链接:
CheckBoxPreference--数据存储
https://blog.csdn.net/lovewlforever/article/details/27355067
213.通过PreferenceScreen跳转到Wifi设置
参考链接:
preferenceScreen 利用intent跳转activity
https://blog.csdn.net/hello_kate/article/details/43524381
214.使用Intent实现在Activity之间传递小图像
215.使用Intent在Activity之间传递图像和文本
216.使用Intent在Activity之间传递集合数据
217.在Intent传递数据时使用Bundle携带数组
218.使用Intent在Service和Activity之间传递数据
214-218小节由于是Intent的传递数据的基本使用,可以延伸一下另开一个专题,所以跳过。
219.使用FileInputStream和FileOutputStream读取和保存文本文件
参考链接:
Android中TXT文本文件写入与读取(总结)
https://blog.csdn.net/lpCrazyBoy/article/details/88354259
220.将浮雕风格的特效文字保存为图像文件
2个知识点,一个是是DrawingCache的使用,另一个是bitmap的存储。
书上的代码稍微有点问题,获取的bitmap是null。有可能是xml部分需要改一点,后面我稍微修改了一点java代码,最后代码如下。领android:background必须填ffffff,否则截屏会变黑。如果代码运行报错的话最好先写个ImageView判断一下bitmap是否能正常获取,再一步步判断问题所在。
先加入权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>
<TextView
android:id="@+id/text_view"
android:text="炫酷"
android:textSize="40sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff"/>
</LinearLayout>
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.text_view);
Bitmap bitmap = convertViewToBitmap(mTextView);
try {
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new ContentValues());
OutputStream outputStream = getContentResolver().openOutputStream(uri);
bitmap.compress(Bitmap.CompressFormat.JPEG,90,outputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static Bitmap convertViewToBitmap(View view){
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
return bitmap;
}
}
参考链接:
Android View之DrawingCache的使用
//www.greatytc.com/p/3526bc69f287
Android使用View.getDrawingCache截取的图像变成黑底黑屏的解决方法备忘
https://blog.csdn.net/fengwusan/article/details/88617050
221.在SD卡上将Bitmap保存为PNG图像文件
参考链接:
Android把Bitmap保存为PNG图像文件的简单方法(同步)
https://blog.csdn.net/zhangphil/article/details/75090282
222.从手机相册中选择图像文件并裁剪头像
参考链接:
Android 从本地图库或拍照后裁剪图片并设置头像
223.在ListView上加载手机外存的图像文件
2个知识点,ContentProvider读取图像文件和ListView显示。
跳过。
224.使用DownloadManager下载网络文件
参考链接:
Android使用DownloadManager完成apk下载(适配到8.0)
//www.greatytc.com/p/ca2e82c8be7c
225.使用RandomAccessFile实现断点续传下载
参考链接:
RandomAccessFile实现断点续传
//www.greatytc.com/p/f4bc67f31005
226.使用HttpURLConnection下载图像文件
首先,找一个图片的下载链接。
随便百度找一个图片。
点击下载。这里我用的是chrome自带的下载,下载后如下图所示,会有下载链接。
复制链接地址,这个链接地址就是需要的url。
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private String mUrlString = "https://image.baidu.com/search/down?tn=download&ipn=dwnl&word=download&ie=utf8&fr=result&url=http%3A%2F%2Fimage109.360doc.com%2FDownloadImg%2F2018%2F07%2F2207%2F139155100_23_20180722072723763.jpg&thumburl=https%3A%2F%2Fss1.bdstatic.com%2F70cFuXSh_Q1YnxGkpoWK1HF6hhy%2Fit%2Fu%3D204052842%2C882108833%26fm%3D26%26gp%3D0.jpg";
private ImageView mImageView;
private Handler mHandler = new Handler(){
public void handleMessage(Message message){
Bitmap bitmap = (Bitmap) message.obj;
mImageView.setImageBitmap(bitmap);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.image_view);
new Thread(){
public void run(){
try {
URL url = new URL(mUrlString);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(5000);
int code = httpURLConnection.getResponseCode();
if (code == 200){
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Message message = Message.obtain();
message.obj = bitmap;
mHandler.sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>