一、实验目的
练习掌握 Android 软件开发基本编程技术、Android 系统 网络API的使用、多线程编程
二、实验内容
开发一个天气预报系统,具备以下功能:
1、可以罗列全国所有省市县
2、可以查看全国任意城市天气信息
3、可以自由切换城市,去查看其它城市的天气
4、提供手动更新以及后台自动更新天气的功能
三、实验要求
(1)每位同学独立设计软件功能、完成软件的开发与测试。
(2)每位同学独立完成实验报告(根据模板),并提交至网络课堂。
四、数据代码及运行结果截图
//WeatherActivity.java 代码太多了,所以其他文件的代码就没有贴上。
public class WeatherActivity extends AppCompatActivity {
private ScrollView weatherlayout;
private TextView titleCity;
private TextView degreeText;
private TextView weatherInfoText;
private LinearLayout forecastLayout;
private LinearLayout suggestionLayput;
private TextView pressureText;
private TextView feelslikeText;
private TextView humidityText;
private TextView windscaleText;
private TextView winddirText;
private ImageView bingPicImg;
private TextView sunriseText;
private TextView One_content;
private TextView One_src;
private TextView sunsetText;
public SwipeRefreshLayout swipeRefresh;
private int mWeatherId;
public DrawerLayout drawerLayout;
private Button navButton;
@SuppressLint("WrongViewCast")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_weather);
if(Build.VERSION.SDK_INT >= 21){
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
weatherlayout=(ScrollView) findViewById(R.id.weather_layout);
titleCity=(TextView) findViewById(R.id.title_city);
degreeText=(TextView) findViewById(R.id.degree_text);
weatherInfoText=(TextView) findViewById(R.id.weather_info_text);
forecastLayout=(LinearLayout) findViewById(R.id.forecast_layout);
suggestionLayput=(LinearLayout) findViewById(R.id.suggestion_layout) ;
winddirText=(TextView) findViewById(R.id.winddir_text);
windscaleText=(TextView) findViewById(R.id.windScale_text);
pressureText=(TextView) findViewById(R.id.pressure_text);
humidityText=(TextView) findViewById(R.id.humidity_text);
feelslikeText=(TextView) findViewById(R.id.feelslike_text);
sunriseText=(TextView) findViewById(R.id.sunrise_text);
sunsetText=(TextView) findViewById(R.id.sunset_text);
bingPicImg=(ImageView) findViewById(R.id.bing_pic_img);
swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
swipeRefresh.setColorSchemeResources(R.color.colorPrimary);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
navButton = (Button) findViewById(R.id.nav_button);
One_content=(TextView) findViewById(R.id.One_content);
One_src=(TextView) findViewById(R.id.One_src);
SharedPreferences prefs= PreferenceManager.getDefaultSharedPreferences(this);
String weatherString=prefs.getString("weather",null);
String weathernowString =prefs.getString("weathernow",null);
String weatherliveString =prefs.getString("weatherlive",null);
int weatherid=prefs.getInt("cityCode",0);
if(weatherString != null&&weatherid!=0&&weathernowString!=null&&weatherliveString!=null){
//有缓存时直接解析天气数据
Weather weather = Utility.handleWeatherResponse(weatherString);
Now now =Utility.handleWeathernowResponse(weathernowString);
Suggestion suggestion=Utility.handleliveindexResponse(weatherliveString);
mWeatherId = weatherid;
showWeatherInfo1(weather);
showWeatherInfo2(now);
showWeatherInfo3(suggestion);
}else{
//无缓存时去服务器查询天气
mWeatherId = getIntent().getIntExtra("weather_id",1);
weatherlayout.setVisibility(View.INVISIBLE);
requestWeather(mWeatherId);
}
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
requestWeather(mWeatherId);
}
});
//加载图片
String bingPic = prefs.getString("bing_pic", null);
if(bingPic != null){
Glide.with(this).load(bingPic).into(bingPicImg);
}else{
loadBingPic();
}
navButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
drawerLayout.openDrawer(GravityCompat.START);
}
});
loadOnecontent();
}
//https://devapi.heweather.net/v7/weather/now?key=4651f31cceb1442fb128631c437a7eb6&location=101210401
public void requestWeather(final int weatherId) {
mWeatherId=weatherId;
final SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this).edit();;
String weatherUrl = "https://devapi.heweather.net/v7/weather/3d?key=4651f31cceb1442fb128631c437a7eb6&location="+weatherId;
String weatherNowUrl = "https://devapi.heweather.net/v7/weather/now?key=4651f31cceb1442fb128631c437a7eb6&location="+weatherId;
String weatherliveUrl = "https://devapi.qweather.com/v7/indices/1d?key=4651f31cceb1442fb128631c437a7eb6&type=1,2,3,9,16&location="+weatherId;
HttpUtil.sendOkHttpRequest(weatherUrl, new Callback() {
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseText = response.body().string();
final Weather weather = Utility.handleWeatherResponse(responseText);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (weather != null ) {
editor.putString("weather", responseText);
editor.putInt("cityCode",weatherId);
editor.apply();
showWeatherInfo1(weather);
} else {
Toast.makeText(WeatherActivity.this, "获取天气信息失败1", Toast.LENGTH_SHORT).show();
}
swipeRefresh.setRefreshing(false);
}
});
}
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(WeatherActivity.this, "获取天气信息失败", Toast.LENGTH_SHORT).show();
swipeRefresh.setRefreshing(false);
}
});
}
});
HttpUtil.sendOkHttpRequest(weatherNowUrl, new Callback() {
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseText = response.body().string();
final Now now = Utility.handleWeathernowResponse(responseText);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (now != null ) {
editor.putString("weathernow", responseText);
editor.apply();
showWeatherInfo2(now);
} else {
Toast.makeText(WeatherActivity.this, "获取天气信息失败2", Toast.LENGTH_SHORT).show();
}
swipeRefresh.setRefreshing(false);
}
});
}
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(WeatherActivity.this, "获取天气信息失败", Toast.LENGTH_SHORT).show();
swipeRefresh.setRefreshing(false);
}
});
}
});
HttpUtil.sendOkHttpRequest(weatherliveUrl, new Callback() {
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseText = response.body().string();
final Suggestion suggestion = Utility.handleliveindexResponse(responseText);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (suggestion != null ) {
editor.putString("weatherlive", responseText);
editor.apply();
showWeatherInfo3(suggestion);
} else {
Toast.makeText(WeatherActivity.this, "获取天气信息失败3", Toast.LENGTH_SHORT).show();
}
swipeRefresh.setRefreshing(false);
}
});
}
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(WeatherActivity.this, "获取天气信息失败", Toast.LENGTH_SHORT).show();
swipeRefresh.setRefreshing(false);
}
});
}
});
loadBingPic();
}
private void loadBingPic() {
String requestBingPic = "http://guolin.tech/api/bing_pic";
HttpUtil.sendOkHttpRequest(requestBingPic, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse( Call call, Response response) throws IOException {
final String bingPic = response.body().string();
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this).edit();
editor.putString("bing_pic", bingPic);
editor.apply();
runOnUiThread(new Runnable() {
@Override
public void run() {
Glide.with(WeatherActivity.this).load(bingPic).into(bingPicImg);
}
});
}
});
}
private void loadOnecontent(){
String apiUrl = "https://api.ghser.com/qinghua?type=json";
try {
URL url = new URL(apiUrl);
String response=OneContentRequest(url);
parseResponse(response);
}catch (Exception e){
Log.v("@@",Log.getStackTraceString(e));
e.printStackTrace();
}
SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(this);
String content=prefs.getString("One","每日一句获取失败");
Typeface typeface = ResourcesCompat.getFont(this, R.font.zt1);
One_content.setTypeface(typeface);
One_content.setText(content);
One_src.setText("----"+"Xaddwell");
}
public String OneContentRequest(URL url) throws IOException {//用于获取网站的Json数据
StringBuilder response = new StringBuilder();
HttpURLConnection httpconn = (HttpURLConnection) url.openConnection();
httpconn.setReadTimeout(10000);
httpconn.setConnectTimeout(15000);
httpconn.setRequestMethod("GET");
httpconn.setDoInput(true);
httpconn.connect();
if (httpconn.getResponseCode()==200){//HttpURLConnection.HTTP_OK
BufferedReader input = new BufferedReader(new InputStreamReader(httpconn.getInputStream()),8192);
String strLine = null;
while ((strLine = input.readLine()) != null){
response.append(strLine);
}
input.close();
}
return response.toString();
}
public void parseResponse(String resp){//用于解析Json数据
JSONObject root = null;
try {
root = new JSONObject(resp);
String data=root.getString("ishan");
SharedPreferences.Editor editor = PreferenceManager.
getDefaultSharedPreferences(WeatherActivity.this).edit();
editor.putString("One",data);
editor.apply();
} catch (JSONException e) {
e.printStackTrace();
}
}
private void showWeatherInfo1(Weather weather) {
List<County> countyList= DataSupport.where("countyId = ?", String.valueOf(mWeatherId)).find(County.class);
String countyName = countyList.get(0).getCountyName();
titleCity.setText(countyName);
forecastLayout.removeAllViews();
for (Forecast forecast : weather.forecastList) {
View view = LayoutInflater.from(this).inflate(R.layout.forecast_item, forecastLayout, false);
TextView dateText = (TextView) view.findViewById(R.id.date_text);
TextView infoText = (TextView) view.findViewById(R.id.info_text);
TextView tempText = (TextView) view.findViewById(R.id.temp_text);
dateText.setText(forecast.date);
if(forecast.textDay.equals(forecast.textNight))
infoText.setText(forecast.textDay);
else
infoText.setText(forecast.textDay+"转"+forecast.textNight);
tempText.setText(forecast.tempMax+"/"+forecast.tempMin);
forecastLayout.addView(view);
}
sunsetText.setText("日出"+weather.forecastList.get(0).sunset);
sunriseText.setText("日落"+weather.forecastList.get(0).sunrise);
weatherlayout.setVisibility(View.VISIBLE);
Intent intent=new Intent(this, AutoUpdateService.class);
startService(intent);
}
private void showWeatherInfo2(Now now) {
String degree = now.temperature + "℃";
String weatherInfo = now.text;
degreeText.setText(degree);
weatherInfoText.setText(weatherInfo);
winddirText.setText(now.windDir);
windscaleText.setText(now.windScale+"级");
humidityText.setText(now.humidity+"%");
pressureText.setText(now.pressure);
feelslikeText.setText(now.feelsLike+"℃");
weatherlayout.setVisibility(View.VISIBLE);
Intent intent=new Intent(this, AutoUpdateService.class);
startService(intent);
}
private void showWeatherInfo3(Suggestion suggestion) {
suggestionLayput.removeAllViews();
for (SuggestItem suggestItem: suggestion.suggestItemList) {
View view = LayoutInflater.from(this).inflate(R.layout.suggestion_item, suggestionLayput, false);
TextView nameText = (TextView) view.findViewById(R.id.name_text);
TextView levelText = (TextView) view.findViewById(R.id.level_text);
TextView categoryText = (TextView) view.findViewById(R.id.category_text);
TextView itemText = (TextView) view.findViewById(R.id.item_text);
nameText.setText(suggestItem.name+":");
levelText.setText(suggestItem.level+":");
categoryText.setText(suggestItem.category);
itemText.setText(suggestItem.text);
suggestionLayput.addView(view);
}
Intent intent=new Intent(this, AutoUpdateService.class);
startService(intent);
}
}
运行截图如下
每日一句设计:
UI设计 everyday.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/One_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:layout_marginRight="20dp"
android:layout_marginLeft="20dp"
android:textColor="#33ccff"
android:textSize="70px"
android:text="One_content" />
<TextView
android:id="@+id/One_src"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="10dp"
android:layout_marginRight="40dp"
android:textColor="#fff"
android:textSize="50px"
android:text="One_src" />
</LinearLayout>
根据API获取每日一句内容
流程:根据API获取内容 内容的JSON解析 内容提取的展示
private void loadOnecontent(){
String apiUrl = "https://api.ghser.com/qinghua?type=json";
try {
URL url = new URL(apiUrl);
String response=OneContentRequest(url);
parseResponse(response);
}catch (Exception e){
Log.v("@@",Log.getStackTraceString(e));
e.printStackTrace();
}
SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(this);
String content=prefs.getString("One","每日一句获取失败");
Typeface typeface = ResourcesCompat.getFont(this, R.font.zt1);
One_content.setTypeface(typeface);
One_content.setText(content);
One_src.setText("----"+"Xaddwell");
}
public String OneContentRequest(URL url) throws IOException {//用于获取网站的Json数据
StringBuilder response = new StringBuilder();
HttpURLConnection httpconn = (HttpURLConnection) url.openConnection();
httpconn.setReadTimeout(10000);
httpconn.setConnectTimeout(15000);
httpconn.setRequestMethod("GET");
httpconn.setDoInput(true);
httpconn.connect();
if (httpconn.getResponseCode()==200){//HttpURLConnection.HTTP_OK
BufferedReader input = new BufferedReader(new InputStreamReader(httpconn.getInputStream()),8192);
String strLine = null;
while ((strLine = input.readLine()) != null){
response.append(strLine);
}
input.close();
}
return response.toString();
}
public void parseResponse(String resp){//用于解析Json数据
JSONObject root = null;
try {
root = new JSONObject(resp);
String data=root.getString("ishan");
SharedPreferences.Editor editor = PreferenceManager.
getDefaultSharedPreferences(WeatherActivity.this).edit();
editor.putString("One",data);
editor.apply();
} catch (JSONException e) {
e.printStackTrace();
}
}
需要注意的点:android.os.networkonmainthreadexception
即主线程中申请网络资源可能会造成阻塞
解决方法:
第一种方法:
在MainActivity.java中的setContentView
后面添加
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
第二种方法:
将请求网络资源的代码使用Thread去操作。在Runnable中做HTTP请求,不用阻塞UI线程。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main_view);
new Thread(runnable).start();
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle data = msg.getData();
String val = data.getString("value");
Log.i(TAG,"请求结果:" + val);
}
}
Runnable runnable = new Runnable(){
@Override
public void run() {
// TODO: http request.
Message msg = new Message();
Bundle data = new Bundle();
data.putString("value","请求结果");
msg.setData(data);
handler.sendMessage(msg);
}
}
new Thread(new Runnable(){
@Override
public void run() {
cachedImage = asyncImageLoader.loadDrawable(imageUrl, position);
imageView.setImageDrawable(cachedImage);
}
}).start();
五、错误总结
javax.net.ssl.SSLHandshakeException: Chain validation failed
异常解决
解决方法一:
解决方法很简单,检查一下设备系统时间是否在证书有效期内,若没有就改到有效期即可(一般系统时间调整为跟网络一致)。
解决方法二:跳过https验证机制
问题解决了,只要将手机系统时间改为当前时间即可了。如果没有其他特殊需求,看到这里就可以结束了。既然是Https的SSL验证,那么通过okhttp跳过这个验证不就好了,在网上查了一下,发现了跳过验证的写法:在构建Okhttps时,自定义SSL验证流程,信任一切证书:
//自定义SS验证相关类
private static class TrustAllCerts implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
private static class TrustAllHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
private static SSLSocketFactory createSSLSocketFactory() {
SSLSocketFactory ssfFactory = null;
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
ssfFactory = sc.getSocketFactory();
} catch (Exception e) {
}
return ssfFactory;
}
使用
okBuilder.sslSocketFactory(createSSLSocketFactory());
okBuilder.hostnameVerifier(new TrustAllHostnameVerifier());
return okBuilder.build()
;
六、个人心得体会
下面列举了100多个国内常用API接口,并按照 笔记、出行、词典、电商、地图、电影、即时通讯、开发者网站、快递查询、旅游、社交、视频、天气、团队协作、图片与图像处理、外卖、消息推送、音乐、云、语义识别、语音识别、杂志、综合 进行了如下分类。
笔记
• OneNote - OneNote支持获取,复制,创建,更新,导入与导出笔记,支持为笔记添加多媒体内容,管理权限等。提供SDK和Demo。
• 为知笔记 - 为知笔记Windows客户端开放了大量的API,其中绝大部分,都通过COM提供,可以在javascript, C#, C++, Delphi等语言中使用。接口通过IDL(Interface description language)语言描述。
• 印象笔记 - 印象笔记提供了ActionScript 3, Android, C++, Windows, iOS, Java, JavaScript, OS X, Perl, PHP, Python, Ruby等平台的SDK和完整的API参考文档,可通过API进行认证,笔记,笔记本,附件,搜索,同步等操作,同时提供企业版和本地API。
• 有道云笔记 - 有道云笔记提供了Android SDK,同时Open API允许进行授权,用户,笔记本,笔记,分享,附件等方面的操作。
出行
• 滴滴 - 滴滴提供了iOS和Android SDK, 可实现拉起滴滴叫车等方面的操作。
• 神州专车 - 神州专车提供了API模式和H5模式两种接入模式,允许进行基础信息,订单,支付,充值,用户,发票,代金券,企业等方面的操作。
• Uber - Uber提供了Android和iOS的SDK,允许进行乘客,行程体验,司机,派送次数等四大方面的操作。
词典
• 百度翻译 - 百度翻译支持多种语言互相翻译,包含PHP, JS, Python, C, Java版Demo。
• 必应词典 - 微软翻译API支持文字和语音两种类型,支持多种语言互相翻译,提供C#版本Demo。
• 必应词典(非官方) - 支持单词和语句翻译。 #非官方
• 金山词霸 - 金山词霸支持简单的翻译操作。
• 金山词霸(非官方) - 金山词霸允许进行简单的翻译操作。 #非官方
• 扇贝 - 扇贝提供了完整的API,允许进行用户,查询,添加学习记录,忘记单词,例句,笔记等方面的操作。
• 译云翻译 - 译云支持进行中英互译,后续会支持更多的语言。
• 有道词典 - 有道词典允许进行简单的翻译操作。
• 有道词典(非官方) - 允许进行简单的翻译操作。 #非官方
电商
• 当当 - 当当允许商家用户和网站接入授权,可进行商品,订单,图片,问答,店铺和促销等方面的操作。
• 京东 - 京东提供了Java, PHP, .net的SDK,授权后可进行多种操作。
• 苏宁开放服务 - 苏宁提供了Java, PHP, .Net, Python版本的SDK,授权后可进行多种操作。
• 淘宝开放平台 - 淘宝提供了Java, .Net, PHP, Python版本的SDK,授权后提供多种操作。
• 亚马逊 - 亚马逊提供多种语言版本的SDK,授权后允许多种操作。
地图
• 百度地图 - 百度地图提供了Android, iOS版本的SDK和JavaScript API,可进行定位、地图、数据、出行、鹰眼轨迹和分析服务。
• 高德地图 - 高德地图提供了JavaScript和web服务API,Android和iOS SDK,支持地图,定位,搜索,路线规划,导航和室内地图等。
• 腾讯地图 - 腾讯地图提供了JavaScript API,Android和iOS SDK,支持定位,地图,地点搜索,路线和导航等。
• 天地图 - 天地图提供了H5 API和JavaScript API等web API,同时提供了Android和iOS SDK,支持基础地图服务,图层管理,地图覆盖物,地图工具,地名搜索和出行规划服务。
• 图吧地图 - 图吧提供了JavaScript和Flash API,Android和iOS SDK,支持定位,地址解析,位置标注,位置截图,路线规划,周边查询,兴趣点搜索和在线导航。
电影
• 豆瓣电影 - 豆瓣电影支持电影条目,影人条目,搜索和榜单等。
• 豆瓣电影(非官方) - 获取最近热映电影、短评、影评、图片等。 #非官方
• 猫眼电影(非官方) - 支持查询首页电影列表,电影详情(含评论),本地影院和影院详情,选座。 #非官方
• Time时光(非官方) - 支持获取时光网网站数据。 #非官方
• V电影(非官方) - 支持获取V电影网站的数据。 #非官方
即时通讯
• 环信 - 支持Android, iOS, WebIM, Linux, REST集成,支持多种消息类型。
• 融云 - 支持Android, iOS, Web, 游戏集成,支持多种消息类型。
• 网易云信 - 支持IM实时通讯,实时音视频,教学白班,专线电话,短信,聊天室,提供iOS, Android, Windows和Web SDK。
• 腾讯云通信IM - 提供iOS, Android, Windows和Web SDK,支持多种消息类型。
开发者网站
• Coding - 授权后可访问coding.net网站的内容。
• 干货集中营 - 提供妹子图和Android, iOS, 前端,拓展资源等内容。
• diycode - 授权后可访问diycode网站的内容。
• 开源中国 - 授权后可访问开源中国网站的内容。
• Laravel China - 授权后可访问 Laravel China 网站的内容。
• Ruby China - 授权后可访问Ruby China网站的内容。
• V2EX - 可访问V2EX网站的内容。
快递查询
• Trackingmore - Trackingmore目前支持500多家国内外快递商,免费版有使用次数限制。
• 快递100 - 快递100支持1000+家国内国际快递,免费版有使用次数限制。
• 快递100(非官方) - 快递100支持300家国内国际快递。 #非官方
• 快递鸟 -专业的第三方物流接口服务商,为开发者聚合全球600+物流接口一次性对接服务,免费版有使用限制。
旅游
• 12306(非官方) - 支持获取12306火车票票数、票价查询。 #非官方
• 去哪儿 - 支持获取去哪儿网的内容。
• 途牛 - 支持途牛网的内容,仅开放给供应商系统。
• 途牛火车票(非官方) - 支持获取途牛火车票票数、票价查询。 #非官方
• 携程 - 支持携程网的内容。
• 艺龙 - 支持获取产品数据,完成用户的预订,进行订单查询、更改或取消。提供在线工具,以及H5, Java, C#, PHP, Ruby版本的Demo。
社交
• 钉钉 - 支持免登,企业通讯录,服务窗,钉盘,地图,会话,DING,电话,音频,扫码,支付,分享等服务,提供SDK和Demo,PC版UI规范,调试工具和钉钉UI组件库。
• 豆瓣 - 支持图书,电影,音乐,同城,广播,用户,日记,相册,线上活动,论坛,回复和我去等功能,提供豆瓣组件,豆瓣标示和Demo。
• 开心网 - 支持用户信息,登录授权,好友,传播应用,支付,分享内容,消息,交互,开心网应用等内容,提供SDK,开源插件和标示素材。
• QQ互联 - 支持用户资料,QQ会员信息,空间相册,腾讯微博资料,分享到腾讯微博,微博好友信息,财付通信息等内容,提供SDK, Demo, 以及设计资源。
• 微博 - 支持粉丝服务,微博,评论,用户,关系,账号,收藏,搜索,提醒,短链,公共服务,位置服务,地理信息,地图引擎,支付以及OAuth2.0授权等内容,提供微博标示及SDK。
• 微信 - 支持移动应用,网站应用,公众账号,公众号第三方平台等内容,提供SDK, Demo, 以及设计资源。
视频
• 爱奇艺 - 支持弹幕,全色彩播放器,高清码流,视频托管,播放爱奇艺视频,应用分发,IOCP等内容。
• Bilibili(非官方) - 支持登录,我的信息,番剧专题,视频/专题收藏、关注,番剧,弹幕等。 #非官方
• Bilibili(非官方) - 支持获取Bilibili网站数据。#非官方
• 乐视 - 支持标准直播,标准点播,视频发行平台,移动直播等内容,提供SDK下载。
• 内涵段子(非官方) - 支持获取内涵段子中大部分模块信息。 #非官方
• 搜狐视频 - 支持一二级内容获取,内容分类获取,视频详情信息,专辑详情信息,分级列表获取,关键词搜索等内容。
• 土豆 - 支持视频模块,豆单模块,影视库模块,用户模块,转帖模块,字段定义模块等内容。
• 优酷 - 支持内容输出,视频搜索,智能推荐,用户登录,用户互动,用户信息,视频上传至优酷,视频互动等内容,提供SDK。
天气
• 彩云天气 - 支持全球天气数据,两种空气质量数据,天气预报,实况天气,独家降水预报,独家空气质量预报,六种天气数据,四种生活指数数据等内容,部分功能收费。
• 和风天气 - 支持7-10天预报,实况天气,每小时预报,生活指数,灾害预警,景点天气,历史天气,城市查询等内容,仅国内数据免费。
• 魅族天气(非官方) - 支持获取魅族天气。 #非官方
• 小米天气(非官方) - 支持获取小米天气数据。 #非官方
• 心知天气 - 支持天气实况,逐日预报和历史,24小时逐小时预报,过去24小时天气历史记录,气象灾害预警,空气质量实况与城市排行,逐日和逐小时空气质量预报,过去24小时空气质量历史记录,生活指数,农历、节气、生肖,机动车尾号限行,日出日落,月初月落和月像,城市搜索等内容,仅国内数据免费。
• 中央天气预报(非官方) - 支持获取中央天气预报数据。 #非官方
团队协作
• Teambition - 支持详细的文档说明,部分平台提供demo。
图片与图像处理
• 别样网 - 无版权免费大尺寸图片共享平台。
• Bing每日壁纸(非官方) - 支持图片URL和图片描述,可获取不同地区的数据。 #非官方
• Camera360 - 支持全帧率直播美白滤镜,提供SDK和Demo。
• 嗨图 - 支持图片标注,仅提供iOS版本SDK。
• 名片全能王 - 支持精准识别几十种语言的名片,自动切边并美化名片图像,自动返回识别结果,提供多种版本SDK,收费。
• pixabay - 在所有的图像和视频Pixabay释放自由版权下创作共用CC0。你可以下载、修改、分发,并使用它们在任何你喜欢的任何东西,即使在商业应用程序中使用它们。不需要归属权。
• 企业证件识别 - 支持身份证,驾驶证,护照等,收费。
• 扫描全能王 - 支持图像智能剪裁,五种图像增强模式,手动调节图像细节,自动返回扫描结果等,提供iOS与Android版本SDK,收费。
• 我知图 - 支持相似图像搜索,图像识别匹配,图像识别关键词推荐,重复图片探测等内容。
• 银行卡|信用卡识别 - 提供SDK和API,收费。
外卖
• 百度外卖 - 支持商户,菜品,商品,订单和基础数据等内容,提供SDK和Demo。
• 大众点评 - 支持商户,团购,在线预定,商品点评,数据统计,元数据等内容。
• 饿了么 - 支持查询,预定,订单,其他订单,数据推送,支付,评价,活动,账户同步,数据落地同步等内容。
• 美团外卖 - 支持门店,配送范围,菜品,药品,订单,订单推送等内容。
消息推送
• 百度云推送 - 支持iOS, Android和服务器端,支持推送,统计,组管理等Rest API接口。服务器端支持Java, Python, PHP, REST API。提供所支持各语言版本的SDK。
• 华为推送 - 支持Android,提供SDK。
• 极光 - 支持Android, iOS, WindowsPhone, 服务器端REST API, 提供Java, Python, PHP, Ruby, C#, Node.js等版本的SDK。
• LeanCloud - 支持Android, iOS, WindowsPhone和Web网页推送,使用云引擎和JavaScript创建推送,使用REST API推送消息。提供Objectvie-C(开放源码), JavaScript(开放源码), Android, Unity, .Net, WindowsPhone, Java(开放源码), Python(开放源码), PHP(开放源码), C++(开放源码), Swift(开放源码)版本SDK。同时提供Demo。
• 腾讯信鸽 - 支持iOS和Android平台,服务器端采用Rest API, 同时服务器端支持Java, PHP, Python等语言并提供SDK。
• 小米 - 支持Android和iOS平台,服务器端支持Java, Python并提供SDK。
• 友盟 - 支持Android和iOS平台,服务器端支持PHP, Java, Python并提供SDK。
音乐
• 百度音乐(非官方) - 支持频道歌曲列表,专辑的歌曲列表,歌曲的详细信息,歌手专辑信息,搜索,歌手的所有歌曲,排行榜,所有专辑,所有歌手,歌手的专辑列表,歌手信息,歌词搜索,歌曲文件详细信息。 #非官方
• 豆瓣音乐 - 支持音乐信息,评论信息,标签信息,搜索音乐,某个音乐中标记最多的标签,发表、修改、删除评论,用户对音乐的所有标签等内容。
• 考拉FM - 支持获取指定分类下列表和内容,搜索指定关键字内容,专辑/电台/直播详情,指定专辑下列表,指定电台播单,分类下专辑TOP50,指定期(碎片)所在专辑最新分页功能,分类下全部直播计划,版本升级接口,排行榜,精选,传统电台列表/详情/地区等。
• 酷狗音乐(非官方) - 支持搜索,各种排行榜,歌手专辑信息,下载和获取播放地址。 #非官方
• 企鹅FM - 支持获取电台分类列表,电台分类下的专辑信息列表,专辑下节目信息列表,电台节目播放链接,搜索关键字相关主播/专辑/节目,主播名下专辑,特定时间段内新增主播/更新的专辑/新增的专辑等。
• QQ音乐(非官方) - 支持歌曲榜单,歌曲/歌词地址,歌曲图片。 #非官方
• 蜻蜓FM - 支持OAuth2.0授权,音频数据中心,分类,点播,直播,临时直播,排行榜,搜索,内容更新状态,主播,此刻,专题,活动等内容。
• 网易云音乐(非官方) - 支持获取用户歌单,歌单详情,歌曲URL。 #非官方
• 喜马拉雅FM - 支持Android和iOS平台,并提供相应的SDK和Demo,具体支持内容请下载相关文件查看。
云
• 阿里云 - 支持弹性计算,数据库,存储与CDN,网络,应用服务,域名与网站等类别的内容,并提供了相关SDK。
• 百度云 - 支持计算和网络,存储和CDN,数据库,安全和管理,数据分析,智能多媒体服务,物联网服务,人工智能,应用服务,网站服务,数字营销服务等内容,并提供相关的SDK。
• Bmob - 支持云数据库,容器服务,消息推送,文件存储,短信验证码,及时通讯,云端逻辑,定时任务,地理位置等。
• LeanCloud - 支持云存储,数据分析,用户关系,实时通讯,消息推送,移动统计等。
• 七牛云 - 支持对象存储,融合CDN,直播云,数据处理等。
• 腾讯云 - 支持计算,网络,存储与CDN,数据库,安全服务,监控与管理,域名服务,视频服务,大数据与AI等内容,提供相关SDK。
• 野狗 - 支持实时数据同步,实时视频通话,及时通讯,短信,身份认证等。
语义识别
• BosonNLP玻森 - 支持REST API并提供Python SDK。
• 腾讯文智 - 支持词法类,句法类,篇章类,下载类API,目前平台能识别类别囊括了求职招聘、影视、音乐、健康养生、财经、广告推广、犯罪、政治等90多个类别,且算法支持快速迭代更新已有类别及增加新类别。提供Python SDK。
语音识别
• 百度语音 - 支持全平台REST API, 离线在线融合模式,深度语义解析,场景识别定制,自定义上传语料、训练模型,基础服务永久免费。提供相应SDK和Demo应用。
• 搜狗语音云开放平台 - 支持在线/离线语音识别,在线听歌识曲,离线语音合成等内容。提供相应平台SDK。
• 讯飞开放平台 - 支持语音听写/转写,在线/离线命令词识别,语音唤醒等内容,平台支持广泛,提供相应SDK。
杂志
• 豆瓣一刻(非官方) - 支持获取指定日期文章列表,栏目总览,推荐作者,作者信息,作者更多文章信息,栏目文章列表及翻页,文章评论及热门评论列表。 #非官方
• 开眼(非官方) - 支持获取未登录状态下开眼精选、发现、关注信息。 #非官方
• One一个(非官方) - 支持获取首页图片,文章,音乐及电影。 #非官方
• 图虫(非官方) - 支持获取图虫 app 所有信息。 #非官方
• 一席(非官方) - 支持获取一席主页、演讲、讲者、枝桠等内容 #非官方
• 知乎日报(非官方) - 支持获取界面启动图像,软件版本查询,最新消息,消息内容获取与离线下载,过往消息,新闻额外消息,新闻对应长/短评论查看,主题日报列表,主题日报内容,热门消息,栏目总览,栏目具体消息,新闻的推荐者,某个专栏之前的新闻,Editor的主页等。 #非官方
• 知乎专栏(非官方) - 支持获取指定专栏的信息,指定专栏的文章列表,指定的文章内容,评论列表,点赞信息。 #非官方
综合
• 阿凡达数据 - 支持金融股票,充值认证,便民类,新闻文章,医药交通,科教文艺,创意数据,及时通讯等内容。
• 阿里大于 - 支持验证码,短信通知,语音通知,流量钱包充值,私密专线,群发助手等内容。
• APiX - 支持基础征信数据,信用分析服务,支付缴费接口等数据,部分免费。
• 百度API STORE - 支持多种类型数据,提供SDK。
• HaoService - 支持多种类型数据。
• 聚合数据 - 支持多种类型数据,部分免费。
• 通联数据 - 提供金融类数据,支持免费试用。