安卓-天气预报系统

一、实验目的

练习掌握 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

The exception that is thrown when an application attempts to perform a networking operation on its main thread.This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it’s heavily discouraged. See the document Designing for Responsiveness.

即主线程中申请网络资源可能会造成阻塞
解决方法:

第一种方法:

在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 - 支持多种类型数据。
• 聚合数据 - 支持多种类型数据,部分免费。
• 通联数据 - 提供金融类数据,支持免费试用。

代码见我发布的资源

  • 3
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值