安装
unable to locate adb
- 法1:确认SDK是否存在:
C:\Users\Katrina\AppData\Local\Android\Sdk\platform-tools
- 法2:打开dos窗口
- 第一步:
cd C:\Users\Katrina\AppData\Local\Android\Sdk\platform-tools
- 第二步:
adb.exe
查看是否存在,效果图如下:
- 第一步:
- 法3:查看插件是否安装完全
- 法4:重新安装SDK
项目分析
《Android第一行代码》第2版 第十四章 天气预报
- 获取天气信息(通过API调用、网络访问)
- 选择城市(ListView)
- 自由切换城市(侧边栏)
- 刷新(手动刷新【下拉刷新】、自动刷新【服务】)
Json
{
"id":2,
"data":{
"id":2,
"data":3
}
"array":[2,3,4], //JsonArray
"array":[
{
"id":2,
"data":3
},
{
"id":2,
"data":3
}
]
}
安装插件gsonformat
第一步:
选择Settings...
第二步:
点击install
安装即可
API接口的调用
- 注册天气API网站
- 进入控制台
- 获取到的结果解析:
- 第一步:点击本处访问api获取返回信息
- 第二步:点击本处可Json在线解析
{
"cityid": "101120101", //"weather_id": "CN101120101"
"date": "2020-08-11",
"week": "星期二",
"update_time": "2020-08-11 16:06:12",
"city": "济南",
"cityEn": "jinan",
"country": "中国",
"countryEn": "China",
"wea": "多云",
"wea_img": "yun",
"tem": "32",
"tem1": "34",
"tem2": "25",
"win": "静风",
"win_speed": "0级",
"win_meter": "",
"humidity": "58%",
"visibility": "7.73km",
"pressure": "986",
"air": "67",
"air_pm25": "67",
"air_level": "良",
"air_tips": "空气好,可以外出活动,除极少数对污染物特别敏感的人群以外,对公众没有危害!",
"alarm": {
"alarm_type": "",
"alarm_level": "",
"alarm_content": ""
}
}
获取cityid
- 继承city.json文件:
http://gitee.com/wangjins/weather_api
- 网络获取:
-
获取省级id:
http://guolin.tech/api/china
-
获取市级id:
http://guolin.tech/api/china/15
省级api + 省级id
-
获取县区id:
http://guolin.tech/api/china/15/96
省级api + 省级id + 市级id
-
[{
"id": 799,
"name": "济南",
"weather_id": "CN101120101"
}, {
"id": 800,
"name": "长清",
"weather_id": "CN101120102"
}, {
"id": 801,
"name": "商河",
"weather_id": "CN101120103"
}, {
"id": 802,
"name": "章丘",
"weather_id": "CN101120104"
}, {
"id": 803,
"name": "平阴",
"weather_id": "CN101120105"
}, {
"id": 804,
"name": "济阳",
"weather_id": "CN101120106"
}]
新建项目
第一步:
自定义项目名称
注:不能出现中文
填坑:
- 启用http通信
https是http加密之后的通信协议,更安全
Google放弃了http,Android app默认情况下只能使用https通信协议
解决: 在AndroidManifest.xml
中启用明文通信,效果图如下:
- 添加maven镜像
在build.gradle中添加代码,其中aliyun
为maven镜像网站,效果图如下:
第二步:项目运行
- 打开模拟器(连接手机),效果图如下:
获取省市县信息并显示
第一步:
添加okhttp,两种添加方式
注:AndroidManifest.xml添加代码,如下:
<uses-permission android:name="android.permission.INTERNET"/>
第一种:
点击本处获取Releases访问第三方库,代码如下:
implementation("com.squareup.okhttp3:okhttp:4.8.1")
在build.gradle中添加代码,效果图如下:
点击Sync Now
下载
第二种:
点击Project Structure
,此处作用为对项目进行配置
选择Dependencies
中app
,添加即可,效果图如下:
选择1 Library Dependency
搜索okhttp3
,点击OK
注:有可能搜不出来,最好选择第一种添加方式
第二步:
ListView使用:
1.数据源 - 数据从哪里来,以及数据格式
2.ListView控件 - 显示数据
3.Adapter - 适配器(需要布局文件,需要和数据源相适应)
创建ListView,activity_main.xml
中添加代码,如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
MainActivity.java
中添加代码,如下:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
//声明ListView
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//创建初始化ListView方法
private void initListView() {
//初始化ListView
//在布局文件中找到该ListView
listView = findViewById(R.id.listview);
}
}
第三步:
创建数据类
在新建的Sheng.java
中添加代码,如下:
/**
* 省数据类
*/
public class Sheng {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
同理创建Shi.java
和Xian.java
,添加代码,如下:
/**
* 市数据类
*/
public class Shi {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* 县数据库
*/
public class Xian {
private int id;
private String name;
private String weather_id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWeather_id() {
return weather_id;
}
public void setWeather_id(String weather_id) {
this.weather_id = weather_id;
}
}
第四步:
代码部分:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.jnsyq">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.example.jnsyq.data.Sheng;
import com.example.jnsyq.data.Shi;
import com.example.jnsyq.data.Xian;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
//声明ListView
private ListView listView;
//声明省市县对应的列表
private List<Sheng> ShengList = new ArrayList<>();
private List<Shi> ShiList = new ArrayList<>();
private List<Xian> XianList = new ArrayList<>();
//声明省市县名称列表:数据源
private List<String> nameList = new ArrayList<>();
//创建适配器
private ArrayAdapter<String> adapter;
//消息处理
//【内存泄漏】
Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what)
{
case 0:
//通知ListView数据更改
adapter.notifyDataSetChanged();
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//调用初始化方法
initListView();
//联网初始化省信息
getSheng();
}
/**
* 新建初始化ListView方法
*/
private void initListView() {
//初始化ListView
//在布局文件中找到该ListView
listView = (ListView) findViewById(R.id.listview);
//数据源、ListView、适配器实现绑定,数据和显示实时更新
//初始化适配器,将适配器和数据源绑定在一起
//this:上下文
//simple_list_item_1:简单的布局
//nameList:设置数据源
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, nameList);
//绑定ListView和适配器,ListView设置适配器
listView.setAdapter(adapter);
//设置点击操作
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//通过点击的位置获取到点击的对象
Sheng s = ShengList.get(position);
Log.d("MainActivity", "onItemClick:" + s.getName());
}
});
}
/**
* 获取省一级的城市列表
*/
private void getSheng() {
//定义url,接口
String url = "http://guolin.tech/api/china";
//1.创建okhttp客户端
OkHttpClient client = new OkHttpClient();
//2.创建请求,构建请求参数
Request request = new Request.Builder().url(url).build();
//3.进行网络访问
//new Callback():回调接口(线程)
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
//如果访问失败,输出失败信息
try {
Log.d("MainActivity", "onFailure:网络访问失败");
} catch (Exception e1) {
// System.out.println("1");
e1.getMessage();
}
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
//将网络相应信息转换成字符串型
//该操作只能执行一次
String data = response.body().string();
// String data1 = response.body().string(); //错误
//输出日志信息
Log.d("MainActivity", "onResponse:" + data);
//解析数据,并生成数据类
try {
//将json字符串转换为json数组
JSONArray shengs = new JSONArray(data); //需处理JSONException,未处理异常【用try/catch包括起来】
//遍历json数字,读取所有的json对象
for (int i = 0; i < shengs.length(); i++) {
//从json数组中读取json对象
JSONObject shengObject = shengs.getJSONObject(i);
//创建省一级城市对象
Sheng s = new Sheng();
//设置对应的值
s.setId(shengObject.getInt("id"));
s.setName(shengObject.getString("name"));
//将省对象添加到列表中
ShengList.add(s);
//将省名称添加到名称列表
nameList.add(s.getName());
//发送消息到Loop
//通过handleMessage进行消息处理
Message msg = new Message();
msg.what = 0; //消息id号
handler.sendMessage(msg);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
效果图:
坑:
更改AndroidManifests文件,需要卸载应用,重新安装