使用OkHttp和OkHttpGo获取OneNET云平台数据
图1是OneNET官网关于NB-IoT文档关于批量查询设备最新数据的介绍,可以看到GET方法的URL地址和两个头部信息(图2是Htto请求消息结构)。所以在写url时,还要添加两行头部字段名,不然获取数据失败(图三是效果图,两个方法都一样)。
图1
图2
图3
OKHTTP实现
1 package com.example.helloworld.learnokhttp; 2 3 import android.os.Bundle; 4 import android.os.Handler; 5 import android.os.Message; 6 import android.util.Log; 7 import android.view.View; 8 import android.widget.Button; 9 import android.widget.TextView; 10 11 import androidx.annotation.Nullable; 12 import androidx.appcompat.app.AppCompatActivity; 13 14 import com.example.helloworld.R; 15 16 import java.io.IOException; 17 18 import okhttp3.CertificatePinner; 19 import okhttp3.MediaType; 20 import okhttp3.OkHttpClient; 21 import okhttp3.Request; 22 import okhttp3.RequestBody; 23 import okhttp3.Response; 24 25 public class OkHttpActivity extends AppCompatActivity implements View.OnClickListener { 26 27 private static final int GET = 1;// get请求 28 private static final int POST = 2;// post请求 29 private Button btn_get_post; 30 private TextView tv_result; 31 private final OkHttpClient client = new OkHttpClient(); 32 public static final MediaType JSON = MediaType.get("application/json; charset=utf-8"); 33 34 private Handler handler = new Handler() { 35 @Override 36 public void handleMessage(Message msg) { 37 super.handleMessage(msg); 38 switch (msg.what) { 39 case GET: 40 //获取数据 41 tv_result.setText((String) msg.obj);//不要写成Interger整型了 42 break; 43 case POST: 44 //获取数据 45 tv_result.setText((String) msg.obj); 46 break; 47 } 48 } 49 }; 50 51 @Override 52 protected void onCreate(@Nullable Bundle savedInstanceState) { 53 super.onCreate(savedInstanceState); 54 setContentView(R.layout.activity_okhttp); 55 56 setTitle("学习okhttp"); 57 58 btn_get_post = findViewById(R.id.btn_get_post); 59 tv_result = findViewById(R.id.tv_result); 60 btn_get_post.setOnClickListener(this); //设置监听事件 61 } 62 63 @Override 64 public void onClick(View view) { 65 switch (view.getId()) { 66 case R.id.btn_get_post: //使用原生的okhttp请求网络数据 67 getDataFromGet();//点击事件用GET 68 //getDataFromPost();//点击事件用POST 69 break; 70 } 71 } 72 73 /** 74 * 使用get请求网络数据 75 * */ 76 private void getDataFromGet() { 77 new Thread() { 78 @Override 79 public void run() { 80 super.run(); 81 82 try{ 83 String result = get("https://api.heclouds.com/devices/523698851/datapoints"); 84 Log.e("TAG",result); 85 Message msg = Message.obtain(); 86 msg.what = GET; 87 msg.obj = result; 88 handler.sendMessage(msg); 89 } catch (IOException e) { 90 e.printStackTrace(); 91 } 92 } 93 }.start(); 94 } 95 96 /** 97 * 使用post请求网络数据 98 * */ 99 private void getDataFromPost() { 100 new Thread() { 101 @Override 102 public void run() { 103 super.run(); 104 105 try{ 106 String result = post("https://www.baidu.com",""); 107 Log.e("TAG",result); 108 Message msg = Message.obtain(); 109 msg.what = POST; 110 msg.obj = result; 111 handler.sendMessage(msg); 112 } catch (IOException e) { 113 e.printStackTrace(); 114 } 115 } 116 }.start(); 117 } 118 119 /** 120 *okhttp3的get请求 121 *@author home 122 *@time 2021/2/20 15:11 123 */ 124 private String get(String url) throws IOException { 125 Request request = new Request.Builder() 126 .url(url) 127 .addHeader("api-key","4VdbaFeRQZRwaSTWNhWxb2UEHaw=")//这里的name一定要写api-key,onenet文档要求 128 .addHeader("Content-Type","application/json") 129 .build(); 130 131 try (Response response = client.newCall(request).execute()) { 132 return response.body().string(); 133 } 134 } 135 136 /** 137 *okhttp3的post请求 138 *@author home 139 *@time 2021/2/20 15:09 140 */ 141 String post(String url, String json) throws IOException { 142 RequestBody body = RequestBody.create(JSON, json); 143 Request request = new Request.Builder() 144 .url(url) 145 .post(body) 146 .build(); 147 try (Response response = client.newCall(request).execute()) { 148 return response.body().string(); 149 } 150 } 151 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 6 <Button 7 android:id="@+id/btn_get_post" 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 android:text="get和post方法获取数据"/> 11 12 <TextView 13 android:id="@+id/tv_result" 14 android:layout_width="match_parent" 15 android:layout_height="wrap_content"/> 16 17 </LinearLayout>
OkHttpGo实现,先再build.gradle(app)中的 dependencies 添加依赖(图4), 新建一个class文件专门用于初始化,同时在Manifest文件中的Application中注册这个class文件(图5),准备步骤就这么多。
图4(红线内即可)
图5(.leanokhttp是我工程下面java文件的包名,GApp就是专门用于初始化的class,写红线内代这一行码就行了)
1 package com.example.helloworld.learnokhttp; 2 3 import android.app.Application; 4 5 6 import com.lzy.okgo.OkGo; 7 import com.lzy.okgo.cache.CacheEntity; 8 import com.lzy.okgo.cache.CacheMode; 9 import com.lzy.okgo.cookie.CookieJarImpl; 10 import com.lzy.okgo.cookie.store.DBCookieStore; 11 import com.lzy.okgo.https.HttpsUtils; 12 import com.lzy.okgo.interceptor.HttpLoggingInterceptor; 13 import com.lzy.okgo.model.HttpHeaders; 14 import com.lzy.okgo.model.HttpParams; 15 16 17 import java.util.concurrent.TimeUnit; 18 import java.util.logging.Level; 19 20 import okhttp3.OkHttpClient; 21 22 /** 23 *OkGo的全局配置,只需调用一次即可,参考例程的同名文件 24 *@author home 25 *@time 2021/2/21 23:36 26 */ 27 28 public class GApp extends Application { 29 30 @Override 31 public void onCreate() { 32 super.onCreate(); 33 initOkGo(); 34 } 35 36 private void initOkGo() { 37 //---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------// 38 HttpHeaders headers = new HttpHeaders(); 39 //----------------------------------------------------------------------------------------// 40 41 OkHttpClient.Builder builder = new OkHttpClient.Builder(); 42 //log相关 43 HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("OkGo"); 44 loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY); //log打印级别,决定了log显示的详细程度 45 loggingInterceptor.setColorLevel(Level.INFO); //log颜色级别,决定了log在控制台显示的颜色 46 builder.addInterceptor(loggingInterceptor); //添加OkGo默认debug日志 47 //第三方的开源库,使用通知显示当前请求的log,不过在做文件下载的时候,这个库好像有问题,对文件判断不准确 48 //builder.addInterceptor(new ChuckInterceptor(this)); 49 50 //超时时间设置,默认60秒 51 builder.readTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS); //全局的读取超时时间 52 builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS); //全局的写入超时时间 53 builder.connectTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS); //全局的连接超时时间 54 55 //自动管理cookie(或者叫session的保持),以下几种任选其一就行 56 //builder.cookieJar(new CookieJarImpl(new SPCookieStore(this))); //使用sp保持cookie,如果cookie不过期,则一直有效 57 builder.cookieJar(new CookieJarImpl(new DBCookieStore(this))); //使用数据库保持cookie,如果cookie不过期,则一直有效 58 //builder.cookieJar(new CookieJarImpl(new MemoryCookieStore())); //使用内存保持cookie,app退出后,cookie消失 59 60 //https相关设置,以下几种方案根据需要自己设置 61 //方法一:信任所有证书,不安全有风险 62 HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory(); 63 64 65 // 其他统一的配置 66 // 详细说明看GitHub文档:https://github.com/jeasonlzy/ 67 OkGo.getInstance().init(this) //必须调用初始化 68 .setOkHttpClient(builder.build()) //建议设置OkHttpClient,不设置会使用默认的 69 .setCacheMode(CacheMode.NO_CACHE) //全局统一缓存模式,默认不使用缓存,可以不传 70 .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE) //全局统一缓存时间,默认永不过期,可以不传 71 .setRetryCount(3) //全局统一超时重连次数,默认为三次,那么最差的情况会请求4次(一次原始请求,三次重连请求),不需要可以设置为0 72 .addCommonHeaders(headers) //全局公共头 73 .addCommonParams(params); //全局公共参数 74 } 75 }
1 package com.example.helloworld.learnokhttp; 2 3 import android.os.Bundle; 4 import android.view.View; 5 import android.widget.Button; 6 import android.widget.TextView; 7 import android.widget.Toast; 8 9 import androidx.annotation.Nullable; 10 import androidx.appcompat.app.AppCompatActivity; 11 12 import com.example.helloworld.R; 13 import com.lzy.okgo.OkGo; 14 import com.lzy.okgo.adapter.Call; 15 import com.lzy.okgo.cache.CacheMode; 16 import com.lzy.okgo.callback.StringCallback; 17 import com.lzy.okgo.model.Response; 18 19 import org.w3c.dom.Text; 20 21 public class OkHttpGoActivity extends AppCompatActivity implements View.OnClickListener { 22 23 private String url = "https://api.heclouds.com/devices/523698851/datapoints";// 24 private Button btn_get; 25 private TextView tv_result; 26 27 @Override 28 protected void onCreate(@Nullable Bundle savedInstanceState) { 29 super.onCreate(savedInstanceState); 30 setContentView(R.layout.activity_okhttpgo); 31 32 setTitle("用封装的方法获取数据"); 33 34 btn_get = findViewById(R.id.btn_get); 35 tv_result = findViewById(R.id.tv_result); 36 btn_get.setOnClickListener(this); 37 38 } 39 40 @Override 41 protected void onDestroy() { 42 super.onDestroy(); 43 //Activity销毁时,取消网络请求 44 OkGo.getInstance().cancelTag(this); 45 } 46 47 private void getByOkGo() { 48 OkGo.<String>get(url)//文档说的第一行泛型一定要添加是指这里 49 .headers("api-key", "4VdbaFeRQZRwaSTWNhWxb2UEHaw=")//设备的api-key 50 .headers("Content-Type","application/json") 51 .tag(this) 52 .execute(new StringCallback() { 53 @Override 54 public void onSuccess(Response<String> response) {//请求成功回调onSuccess方法 55 tv_result.setText(response.body());//文档中有说明,body是返回的数据 56 } 57 58 @Override 59 public void onError(Response<String> response) { 60 Toast.makeText(getApplicationContext(), "接口请求错误!", Toast.LENGTH_LONG).show(); 61 } 62 }); 63 } 64 65 @Override 66 public void onClick(View view) { 67 switch (view.getId()) { 68 case R.id.btn_get: //使用原生的okhttp请求网络数据 69 getByOkGo();//用okgo方法获取数据 70 break; 71 } 72 } 73 }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn_get" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="get方法获取数据"/> <TextView android:id="@+id/tv_result" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
参考至
https://square.github.io/okhttp/
https://github.com/jeasonlzy/okhttp-OkGo/wiki
2021-02-22 14:17:47