簡易安卓APP

簡介

  如今來分享期末作的安卓大做業——生活百科。
  本項目只是單純的一個大做業,沒有考慮實際的需求,因此有設計不合理的地方,請見諒。
  這個項目有三大功能(由於是使用了側邊欄因此是能夠繼續往裏面添加功能的),首先有單詞查詢,其次是天氣查詢,後來是機器聊天功能。單詞查詢是使用了扇貝單詞提供的免費API;天氣查詢是使用了聚合數據提供的天氣API,這裏須要註冊使用(有限的無償使用);機器聊天是使用了圖靈機器人的API。因此,總結一下,這裏個人主要工做不會不少,主要是調用API而後進行數據的分析和顯示工做。
  本次使用的IDE是idea(Android studio)。
  
  文章的最後將會給出源碼,可是一些API接口須要本身去申請Keyhtml

在項目開始前的學習階段
安卓基礎入門 http://www.runoob.com/android/android-tutorial.html
安卓省市聯動(天氣的位置選擇) http://blog.csdn.net/qq_20521573/article/details/51914180
安卓fragment的使用 http://www.jikexueyuan.com/course/708.html
機器聊天界面的HTML源碼 http://www.lanrenzhijia.com/js/3930.html
以上即是我着手項目的累積步驟,但願有幫助android

1. 項目準備階段

1.1. 新建項目

  使用Android Studio(IDEA)新建安卓項目->選擇SDK版本(Android 4.0爲好)->選擇Navigation Drawer Activity模板->完成項目建立。項目新建以後就會獲得咱們基本的界面模板了。然後,只須要刪除右側邊和底部的元素就可獲得下圖所示的界面git

固然,這裏使用Android ADT也是能夠的,不過好像新建出來的模板不同,比較醜一點(本身對於Android的UI不太行),因此就使用了Android Studio。github

1.2. 添加依賴

  因爲須要使用省市聯動的功能,因此須要添加外部依賴,在上面給出的連接上有詳細說明,所以須要在app文件夾下的build.gradle裏面的dependencies加入
  web

compile 'com.contrarywind:Android-PickerView:3.2.5'//自定義控件
    compile 'com.google.code.gson:gson:2.7'//解析JSON

  作完了準備工做以後就進入主題api

2. 單詞查詢功能

  考慮文章的篇幅過長,因此有些詳細的過程可能會省略(像界面的修改工做等等)。網絡

  當咱們輸入了單詞以後點擊查詢是須要訪問網絡的,這裏採用了異步的任務機制去訪問網絡而且得出結果,部分代碼以下:
  app

//這是繼承OnQueryTextListener 的內部類,用於處理搜索框監聽事件
public class SearchViewClickListener implements SearchView.OnQueryTextListener {

        @Override
        public boolean onQueryTextSubmit(String s) {
            if (!lastSearchResult.equals(s)){//判斷上一個結果和目前查詢的是否相同
                System.out.println("上個結果:"+lastSearchResult);
                SearchWordTask task = new SearchWordTask();//新建查詢任務
                task.execute("https://api.shanbay.com/bdc/search/?word="+s);//訪問網絡的地址
                searchResult.setVisibility(View.VISIBLE);//設置查詢結果的TextView可見
            }
            lastSearchResult = s;//更新最後查詢結果
            System.out.println("最新結果:"+s);
            return true;
        }

        @Override
        public boolean onQueryTextChange(String s) {
            return true;
        }
    }

在訪問網絡然後傳回數據我這裏將這個功能提取到了一個工具類,代碼以下:異步

public class HttpUtil {

    /**
     * 獲取訪問網絡後傳回的數據
     * @param urlString URL
     * @return String
     */
    public static String getJSONResult(String urlString){
        try {
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36");

            InputStream is = conn.getInputStream();
            byte[] buff = new byte[1024];
            int hasRead;
            StringBuilder result = new StringBuilder("");
            while ((hasRead = is.read(buff)) > 0) {
                result.append(new String(buff, 0, hasRead));
            }
            return result.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

在上面中SearchWordTask是一個繼承了AsyncTask的內部類,主要是實現了訪問扇貝提供的英文單詞查詢API,部分代碼以下:ide

class SearchWordTask extends AsyncTask<String, Void, String> {

        
        @Override
        protected String doInBackground(String... arg0) {
            //arg0是執行AsyncTask的execute函數傳入的可變參數
            //這裏arg0[0]是"https://api.shanbay.com/bdc/search/?word="+s
            return HttpUtil.getJSONResult(arg0[0]);
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            if (result == null || "".equals(result)){
                Toast.makeText(getActivity(), "查詢出錯!", Toast.LENGTH_LONG).show();
            }else
                fillResultForJSON(result);

        }

        /**
         * 解析查詢的結果
         * @param JSON JSON數據
         */
        private void fillResultForJSON(String JSON){
            try {
                JSONObject object = new JSONObject(JSON);
                if ("SUCCESS".equals(object.getString("msg"))){
                    final JSONObject dataObject = object.getJSONObject("data");
                    paraphrase.setText("基本釋義:"+dataObject.getString("definition"));
                    final String uk_audio = dataObject.getString("uk_audio");
                    final String us_audio = dataObject.getString("us_audio");
                    detail.setOnClickListener(new View.OnClickListener() {
                        //若是詳細釋義按鈕點擊則訪問以下頁面
                        @Override
                        public void onClick(View view) {

                            webView.setVisibility(View.VISIBLE);
                            webView.loadUrl("https://www.shanbay.com/bdc/mobile/preview/word?word="+lastSearchResult);
                            webView.setWebViewClient(new WebViewClient());
                        }
                    });
                    //如下是發音按鈕被點擊時的監聽事件
                    UKButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            try {
                                //使用UKMediaPlayer 播放聲音
                                UKMediaPlayer = new MediaPlayer();
                                UKMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                                UKMediaPlayer.setDataSource(uk_audio);
                                UKMediaPlayer.prepare(); // 這個過程可能須要一段時間,例如網上流的讀取
                                UKMediaPlayer.start();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    });

                    USButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                           //同上面的播放聲音步驟
                           ...
                    });

                    JSONObject pronunciations =dataObject.getJSONObject("pronunciations");
                    UKPronunciation.setText("英式發音:["+pronunciations.getString("uk")+"]");
                    USPronunciation.setText("美式發音:["+pronunciations.getString("us")+"]");
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

以上即是單詞查詢的主體功能了,固然,考慮文章篇幅因此不能一一解析。

3. 天氣查詢功能

  在天氣查詢功能中比較重要的就是使用了網友所寫的省市聯動功能,這裏請參考上面連接中的文章。下面我將不會涉及這方面的講解,這裏主要是說一下訪問聚合數據所提供的API,這個功能的效果以下圖:

  在上面功能中的業務代碼主要是跟上面的單詞查詢差很少,都是使用了異步查詢,由內部類實現,代碼以下:
  

class WeatherTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... arg0) {

            try {
                return HttpUtil.getJSONResult(arg0[0] + URLEncoder.encode(arg0[1], "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            if (result != null){
                parseWeatherJSON(result);
            }
        }

        /**
         * 根據JSON數據解析
         * @param result JSON
         */
        private void parseWeatherJSON(String result){
            try {
                JSONObject object = new JSONObject(result);
                if (object.getInt("error_code") == 0){
                    JSONObject resultObj = object.getJSONObject("result");
                    JSONObject todayObj = resultObj.getJSONObject("today");
                    String weatherResult = "溫度:"+todayObj.getString("temperature")+"\n";
                    weatherResult += "天氣情況:"+todayObj.getString("weather")+"\n";
                    weatherResult += "風向:"+todayObj.getString("wind")+"\n";
                    weatherResult += "穿衣建議:"+todayObj.getString("dressing_advice");
                    todayWeather.setText(weatherResult);
                }else {
                    todayWeather.setText("請求出錯!");
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

4. 機器聊天功能

  機器聊天功能是使用了HTML頁面來進行人機交互,因此,這裏基本上沒有涉及到Java上面的問題,主要是加載HTML頁面以及開啓JavaScript功能,代碼以下:

WebView webView = (WebView) rootView.findViewById(R.id.chat_robot);
//加載本地的HTML頁面(將文件置於src/main/assets/)       webView.loadUrl("file:///android_asset/chat_robot.html");
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());

  功能的實現效果如圖:

  固然了,要是用以上的聊天功能須要註冊圖靈機器人申請Key,源碼中不會提供Key,因此請自行註冊。
  在接收圖靈機器人返回的數據時,它會有代碼來肯定返回的是什麼類型,因此,須要咱們來判斷類型來進行相應的解析(這裏的JS代碼就不貼出來了)。

5. 總結

  此次的是一個安卓的期末做業,可是卻沒有很認真的對待的樣子,並且項目仍是不完善的,好比,在查詢了單詞後作其餘功能的操做再次返回單詞查詢功能則以前的數據不可以保存,用戶體驗很差。這裏固然我也知道一些解決的方案,保存當前的fragment狀態,可是,我仍是偷懶了。懶惰真的是宿敵。
  文章上寫的詳細程度不夠,可是主要的代碼都已經寫出。我知道,有時候解決一個功能並非功能自己,而是要防止功能附帶出來的bug,固然了,這就是個人經歷。
  還有就是可能我對於面向對象仍是理解上有所誤差,對於抽象仍是作得很爛,接下來但願看看別人的源碼來改善這個問題。
  

項目源碼已上傳GitHubCSDN資源,若是資源分不少的朋友就使用CSDN下載吧。下載後須要去註冊相應的Key以後填入,不然沒法使用,註冊地址在簡介中已經給出

相關文章
相關標籤/搜索