1、接口
首先看到华为平台的接口
这些就是云平台上面的对接信息,然后现在用的HTTPS链接。安全秘钥是每个应用都有一个的。
2、开发文档
如果想要开发好APP,一定要看华为云平台上面的开发文档,这里直接给出开发文档的链接
好好细看就可以很快的入手了。
3、连接平台代码
连接方式主要就是以HTTP的方式进行链接的。如果没有这方面的知识必须要好好脑补一下。下面看代码。有端口,IP地址,ID和密钥,密钥要改成自己的。
/**
*
* 登陆
* */
private void Login_into() {
//设置登陆数据
address = edServiceAddress.getText().toString().trim();
port=edt_port.getText().toString().trim();
user = etUsername.getText().toString().trim();
pwd = etPassword.getText().toString().trim();
Config.all_url="https://"+address+":"+port;
//判断文本框信息是否为空,并进行相关处理
//如果都填写,则进行HTTPS请求初始化
if (TextUtils.isEmpty(address)) {
Toast.makeText(LoginActivity.this, "请输入IP", Toast.LENGTH_SHORT).show();
}else if(TextUtils.isEmpty(port)){
Toast.makeText(LoginActivity.this, "请输入端口号", Toast.LENGTH_SHORT).show();
}
else {
if (TextUtils.isEmpty(user) || TextUtils.isEmpty(pwd)) {
Toast.makeText(LoginActivity.this, "用户信息不能为空", Toast.LENGTH_SHORT).show();
}
else {
Init_Demand_HTTPS();
// }
}
}
}
/**
*
* 用户信息请求
*/
private void Init_Demand_HTTPS() {
//开启新线程进行数据请求
new Thread(new Runnable() {
@Override
public void run() {
Message msg = new Message();
Bundle data = new Bundle();
try {
//设置服务器的url(直接到登录界面的url)
String url="https://"+address+":"+port+"/iocm/app/sec/v1.1.0/login";
// https://49.4.92.191:8743/iocm/app/sec/v1.1.0/login
String json= DataManager.Login_Request(LoginActivity.this,url,user,pwd);//连接服务器
data.putString("json", json);
} catch ( Exception e ) {
data.putString("errmsg", e.getMessage());
}
msg.setData(data);
loginhandler.sendMessage(msg);//将登陆界面的程序放进数据库中 防止下次进来再自己输入
}
}).start();
}
其中 Login_Request代码为:
public static String Login_Request(Context mContext, String serverurl,String userID,String tokenpwd)
throws Exception{
//用来保存用户id和密码
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("appId", userID));
params.add(new BasicNameValuePair("secret", tokenpwd));
String json = NetConnect.request(mContext, NetConnect.REQUEST_TYPE_POST,
serverurl, params);
return json;
}
4、返回数据代码
package com.mcz.smoke_appproject;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.support.v7.widget.Toolbar;
import com.gyf.barlibrary.ImmersionBar;
import com.mcz.smoke_appproject.app.model.DataInfo;
import com.mcz.smoke_appproject.app.model.PullrefreshListviewAdapter;
import com.mcz.smoke_appproject.app.utils.Config;
import com.mcz.smoke_appproject.app.utils.DataManager;
import com.mcz.smoke_appproject.app.view.view.IPullToRefresh;
import com.mcz.smoke_appproject.app.view.view.LoadingLayout;
import com.mcz.smoke_appproject.app.view.view.PullToRefreshBase;
import com.mcz.smoke_appproject.app.view.view.PullToRefreshFooter;
import com.mcz.smoke_appproject.app.view.view.PullToRefreshHeader;
import com.mcz.smoke_appproject.app.view.view.PullToRefreshListView;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
//整个过程就是发送请求到服务器,返回数据到适配器,再通过适配器传到视图显示
//华为开发文档 https://iot-dev.huaweicloud.com/assets/docCenter/helpcenter/helpPortal/Portal/helpcenter.html?manualName=UserGuide_COMMON&docSite=COMMON&page=gettingStarted&lang=zh
public class MainActivity extends AppCompatActivity {
// 刷新
@BindView(R.id.main_pull_refresh_lv)//参考 https://blog.csdn.net/qq_36946446/article/details/83542314?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1
PullToRefreshListView mListView;
// 暂无数据页面
@BindView(R.id.main_relative)
RelativeLayout rela_nodata;
// 侧边栏
//private DrawerLayout mDrawerLayout;
// 暂无数据页面
private View mNoMoreView;
// 鉴权
private String login_appid;
String token = "";
SharedPreferences sp;
//监听back键点击时间
private long backfirsttime = 0;
// 上拉刷新适配器
private PullrefreshListviewAdapter adapter;
// 信息数据泛型
private List<DataInfo> mlist = null;
@Override
protected void onCreate(Bundle savedInstanceState) {//这个方法会在活动第一次被创建的时候调用
super.onCreate(savedInstanceState);
//设置对应的页面
setContentView(R.layout.main_activity_layout);//開始運行main_activity_layout界面
ButterKnife.bind(this);//Butter Knife自动找到并把相应的视图布局。
// 设置沉浸式状态栏
ImmersionBar.with(this)
.statusBarColor(R.color.blues)
.fitsSystemWindows(true)
.init();
// 主页初始化
init();
}
@Override
protected void onResume() {//这个方法会在活动准备好和用户进行交互的时候调用
super.onResume();
if ((adapter != null && adapter.getCount() == 0)) {
refreshButtonClicked();
}
hintKbTwo();
}
@Override
protected void onRestart() {//这个方法会在活动由停止状态变为运行状态之前调用,即活动被重启了
super.onRestart();
refreshButtonClicked();
hintKbTwo();
}
//初始化
private void init() {
sp = PreferenceManager.getDefaultSharedPreferences(this);
login_appid = sp.getString("appId","");//用户的名称
token = sp.getString("token", "");
hintKbTwo();
rela_nodata.setVisibility(View.GONE);//不可见
//载入暂无设备页面布局文件
mNoMoreView = getLayoutInflater().inflate(R.layout.no_device_more_footer, null);
//设置加载布局构造器
mListView.setLoadingLayoutCreator(new PullToRefreshBase.LoadingLayoutCreator() {
@Override
public LoadingLayout create(Context context, boolean headerOrFooter,
PullToRefreshBase.Orientation orientation) {
if (headerOrFooter)
return new PullToRefreshHeader(context);
else
return new PullToRefreshFooter(context, PullToRefreshFooter.Style.EMPTY_NO_MORE.EMPTY_NO_MORE);
}
});
//获取可刷新视图
mListView.getRefreshableView().setSelector(getResources().getDrawable(R.color.transparent));
//设置可上拉刷新和下拉刷新
mListView.setMode(PullToRefreshBase.Mode.DISABLED);
//异步加载数据
mListView.setOnRefreshListener(new IPullToRefresh.OnRefreshListener<ListView>() {
@Override
public void onRefresh(PullToRefreshBase<ListView> refreshView,
boolean headerOrFooter) {
//填充数据,通过异步进行数据加载
new LoadDataAsyncTask(headerOrFooter, false).execute();//取出数据
}
});
//配置刷新后的列表刷新适配器
adapter = new PullrefreshListviewAdapter( this);
adapter.setlogin_appid(login_appid);
adapter.settoken(token);
mListView=(PullToRefreshListView)findViewById(R.id.main_pull_refresh_lv) ;
mListView.getRefreshableView().addFooterView(mNoMoreView);
mListView.setAdapter(adapter);
mListView.getRefreshableView().removeFooterView(mNoMoreView);
//导航项
/*Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar= getSupportActionBar();
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
actionBar.setDisplayHomeAsUpEnabled(true);
*/
//侧边栏
/* mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
final NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
item.setCheckable(true);
mDrawerLayout.closeDrawer(navigationView);
return true;
}
});*/
}
/**
* 在进入界面的时候自动加载一遍
* 第一次有数据显示
**/
private void refreshButtonClicked() {
mListView.setVisibility(View.VISIBLE); //View类的setVisibility()方法设置是否显示组件
mListView.setMode(IPullToRefresh.Mode.BOTH);
mListView.setRefreshing();
}
// 回收软键盘 参考 https://blog.csdn.net/jueshiwushuang2007/article/details/78392246
// getCurrentFocus()是获取当前activity中获得焦点的view , 看看是否在Activity中获取焦点 ,否则需求先获取activity 的 Context
//getWindowToken()获取调用的view依附在哪个window的令牌。
private void hintKbTwo() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);// 隐藏软键盘
if(imm.isActive()&&getCurrentFocus()!=null){ //如果当前焦点填写的数据不为空并且键盘上面没有输入性的东西则关闭键盘
if (getCurrentFocus().getWindowToken()!=null) {
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
/**
* 添加数据
* 华为接口批量查询设备信息
**/
private List<DataInfo> ListviewADD_Data(int Fnum, int Onum) {
try {
//设置url,直接到设备页 接口的请求地址 https://server:port/iocm/app/dm/v1.4.0/devices/{deviceId}?appId={appId}&select={select}
String add_url = Config.all_url + "/iocm/app/dm/v1.4.0/devices?appId=" + login_appid
+ "&pageNo=" + Fnum + "&pageSize=" + Onum;
//获取对应的json字符串
String json = DataManager.Txt_REQUSET(MainActivity.this, add_url, login_appid, token);//这一句
mlist = new ArrayList<DataInfo>();
//把json字符串转换为json对象
JSONObject jo = new JSONObject(json);
//定位到名为devices的json集合
JSONArray jsonArray = jo.getJSONArray("devices");
//添加日志
Log.i("ssss","jsonArray:" + jsonArray);
for (int i = 0; i < jsonArray.length(); i++) {
//新建设备类
DataInfo dataInfo = new DataInfo();
//获取对应属性名的数据
String deviceinfo = jsonArray.getJSONObject(i).getString("deviceInfo");
String servicesinfo = jsonArray.getJSONObject(i).getString("services");
//如果设备状态信息不是离线,则设置数据,否则输出暂无数据
if (!servicesinfo.equals("null")){
JSONArray jsa=new JSONArray(servicesinfo);
for (int j = 0; j < jsa.length(); j++) {
//从设备数组中获取设备对象
String ser_data = jsa.getJSONObject(j).getString("data");
JSONObject jsonObject = new JSONObject(ser_data);
//给dataInfo对象的属性赋值
dataInfo.setDeviceCSQ(jsonObject.optString("CSQ"));//optstring -- 选项字符百串 例如 unix,optstring 内容答是 ":abf:o:"就可以取出其值
dataInfo.setStart(jsonObject.optString("Star"));
dataInfo.setDeviceTemperature(jsonObject.optString("Temperature"));
dataInfo.setDeviceHumidity(jsonObject.optString("Humidity"));
dataInfo.setDeviceWeight(jsonObject.optString("Weight"));
dataInfo.setWorkShi(jsonObject.optString("WorkShi"));
dataInfo.setWorkFen(jsonObject.optString("WorkFen"));
}
dataInfo.setDeviceId(jsonArray.getJSONObject(i).optString("deviceId"));
dataInfo.setGatewayId(jsonArray.getJSONObject(i).optString("gatewayId"));
dataInfo.setLasttime(jsonArray.getJSONObject(i).optString("lastModifiedTime"));
JSONObject object = new JSONObject(deviceinfo);
dataInfo.setDeviceName(object.optString("name"));
dataInfo.setDeviceType(object.optString("deviceType"));//model deviceType
dataInfo.setDeviceStatus(object.optString("status"));
mlist.add(dataInfo);
}
else {
dataInfo.setDeviceWeight("暂无数据");
dataInfo.setDeviceHumidity("暂无数据");
dataInfo.setDeviceTemperature("暂无数据");
dataInfo.setWorkFen("暂无数据");
dataInfo.setWorkShi("暂无数据");
dataInfo.setDeviceId(jsonArray.getJSONObject(i).optString("deviceId"));
dataInfo.setGatewayId(jsonArray.getJSONObject(i).optString("gatewayId"));
dataInfo.setLasttime(jsonArray.getJSONObject(i).optString("lastModifiedTime"));
JSONObject object = new JSONObject(deviceinfo);
dataInfo.setDeviceName(object.optString("name"));
dataInfo.setDeviceType(object.optString("deviceType"));//model deviceType
dataInfo.setDeviceStatus(object.optString("status"));
mlist.add(dataInfo);
}
}
} catch ( Exception e ) {
e.printStackTrace();
}
return mlist;
}
/**
* 手动添加设备
*
**/
@Nullable//重载
private List<DataInfo> Listview_Inputmanual(String dvid) {
try {
// https://server:port/iocm/app/dm/v1.4.0/devices/{deviceId}?appId={appId}
String login_appid = sp.getString("appId","");
String add_url = Config.all_url + "/iocm/app/dm/v1.4.0/devices/"+dvid+"?appId=" + login_appid;
String json = DataManager.Txt_REQUSET(MainActivity.this, add_url, login_appid, token);
Log.i("aaa", "josn1" + json);
mlist = new ArrayList<DataInfo>();
JSONObject jo = new JSONObject(json);
String code_error=jo.optString("error_code");
if (!code_error.equals("")){
return null;
}else{
DataInfo dataInfo = new DataInfo();
String deviceinfo = jo.optString("deviceInfo");
dataInfo.setDeviceId(jo.optString("deviceId"));
dataInfo.setLasttime(jo.optString("lastModifiedTime"));
JSONObject object = new JSONObject(deviceinfo);
dataInfo.setDeviceName(object.optString("name"));
dataInfo.setDeviceStatus(object.optString("status"));
String servicesinfo = jo.optString("services");
// servicesinfo 非空则设置dataInfo数据,否则输出暂无数据
if (!servicesinfo.equals("null")){
JSONArray jsa=new JSONArray(servicesinfo);
for (int j = 0; j < jsa.length(); j++) {
String ser_data = jsa.getJSONObject(j).getString("data");
JSONObject jsonObject = new JSONObject(ser_data);
dataInfo.setDeviceCSQ(jsonObject.optString("CSQ"));
}
mlist.add(dataInfo);
}else{
dataInfo.setDeviceCSQ("暂无数据");
}
}
}
catch ( Exception e ) {
Toast.makeText(this, "请输入正确的设备ID", Toast.LENGTH_SHORT).show();
rela_nodata.setVisibility(View.VISIBLE);
e.printStackTrace();
}
return mlist;
}
/**
* 异步加载任务
* 下拉刷新 上拉加载
**/
int numbers = 5;
int begin = 0;
// 选择类型
boolean type_choose = true;
String datajson = "";
private class LoadDataAsyncTask extends AsyncTask<Void, Void, List<DataInfo>> {
private boolean mHeaderOrFooter;
private boolean is_Add;
public LoadDataAsyncTask(boolean headerOrFooter, boolean isadd) {
mHeaderOrFooter = headerOrFooter;
is_Add = isadd;
}
// 执行线程任务前的操作
@Override
protected void onPreExecute() {
super.onPreExecute();
if (mHeaderOrFooter) {
mListView.setVisibility(View.VISIBLE);
}
mListView.getRefreshableView().removeFooterView(mNoMoreView);
}
// 接受输入参数,在后台执行任务中的耗时操作,并返回线程任务执行的结果
@Override
protected List<DataInfo> doInBackground(Void... params) {
if (MainActivity.this.isFinishing()) {
return null;
}
List<DataInfo> result = null;
try {
// 首先判断是否查询所有还是单个
if (!is_Add) {
if (mHeaderOrFooter && type_choose) {
// 下拉刷新走的方法
if (type_choose == false) {
adapter.clearItem();
mlist = new ArrayList<DataInfo>();
}
type_choose = true;
numbers = 5;
result = ListviewADD_Data(0, numbers);
begin=5;
} else {
// 上拉加载走的方法
if (type_choose == false) {
adapter.clearItem();
mlist = new ArrayList<DataInfo>();
numbers = 5;
result = ListviewADD_Data(0, numbers);
begin = 5;
type_choose = true;
} else {
begin = begin + 5;
result = ListviewADD_Data(0, begin);
type_choose = true;
}
}
}
// 否则...
else {
// 更据ID查询
result = Listview_Inputmanual(datajson);
}
return result;
} catch ( Exception e ) {
e.printStackTrace();
return null;
}
}
// 接受线程任务执行结果,将执行结果显示到UI组件
@Override
protected void onPostExecute(List<DataInfo> result) {
super.onPostExecute(result);
mListView.onRefreshComplete();
if (MainActivity.this.isFinishing()) {
return;
}
if (result != null) {
if (mHeaderOrFooter) {
CharSequence dateText = DateFormat.format("yyyy-MM-dd kk:mm:ss", new Date());
for (LoadingLayout layout : mListView.getLoadingLayoutProxy(true, false).getLayouts()) {
((PullToRefreshHeader) layout).setLastRefreshTime(":" + dateText);
}
adapter.clearItem();//清空适配器
mlist = new ArrayList<DataInfo>();
}
if (adapter.getCount() == 0 && result.size() == 0) {
mListView.setVisibility(View.GONE);
mListView.getRefreshableView().removeFooterView(mNoMoreView);
rela_nodata.setVisibility(View.VISIBLE);
} else if (result.size()>5) {
//在这里判断数据的多少确定下一步能否上拉加载
if (result.size()%5==0){
}else{
mListView.setFooterRefreshEnabled(false);
mListView.getRefreshableView().addFooterView(mNoMoreView);
rela_nodata.setVisibility(View.GONE);
mListView.setVisibility(View.VISIBLE);
}
} else if (mHeaderOrFooter) {
if (result.size()>0){
rela_nodata.setVisibility(View.GONE);
mListView.setVisibility(View.VISIBLE);
}
mListView.setFooterRefreshEnabled(true);
mListView.getRefreshableView().removeFooterView(mNoMoreView);
}
addlistdata(result);
adapter.notifyDataSetChanged();//刷新完成
}else{
rela_nodata.setVisibility(View.VISIBLE);
Toast.makeText(MainActivity.this, "暂无设备信息", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 数据循环添加
*
**/
private void addlistdata(List<DataInfo> result) {
int count = result.size();//数据的长度
adapter.clearItem();
for (int i = 0; i < count; i++) {
adapter.addItem(result.get(i));
mlist.add(result.get(i));
}
}
//在间隔两秒之内按两次返回键则关闭APP
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
/**
* 监听返回按钮 (back键)
* 使用系统时间里判断用户是否需要退出
*//* 参考 https://www.cnblogs.com/HDK2016/p/8695052.html */
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
if (System.currentTimeMillis() - backfirsttime > 2000) {
Toast.makeText(getApplication(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
backfirsttime = System.currentTimeMillis();
return false;//返回false表示不退出 ture表示退出
}
else {
finish();
System.exit(0);//结束进程
return true;
}
//return true;
}
return super.onKeyDown(keyCode, event);
}
}
最后分享一下整个APP工程:https://wwwk.lanzouf.com/b015ipphc
密码:df61