2016年7月4日 星期一

使用 okHttp 的 GET 方式讀取 XML 資料

一般在解析 XML 資料大致上有分成 DOMSAXJDOMDOM4J 四種解析方式,我比較有接觸過的 DOMSAX 這兩種,所以只就介紹介紹 DOMSAX 的差異。接著本範例會使用 OKHttp 來讀取政府提供的XML格式資料(顯著有感地震報告資料),並由 DOM 來解析 XML 格式資料,在由App顯示出相關訊息。

呈現效果:


1.build.gradle(picasso和okhttp 衝突到,需要加okhttp-urlconnection )

2.layout.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context="gae.melvin.com.app_okhttp_xml.MainActivity">     <ImageView         android:layout_width="match_parent"         android:layout_height="match_parent"         android:id="@+id/imageView"         android:layout_gravity="left|top"         android:src="@mipmap/ic_launcher" />     <LinearLayout         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:orientation="vertical">         <TextView             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:textSize="20sp"             android:text="Large Text"             android:layout_marginTop="30dp"             android:id="@+id/textView"             android:textColor="#e12222" />         <TextView             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_marginTop="30dp"             android:textSize="26sp"             android:text="Large Text"             android:textColor="#5500aa"             android:id="@+id/textView2" />     </LinearLayout> </FrameLayout>


3.MainActivity.java
package gae.melvin.com.app_okhttp_xml; import android.content.Context; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ImageView; import android.widget.TextView; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import com.squareup.picasso.Picasso; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; public class MainActivity extends AppCompatActivity {     private TextView textView,textView2;     private Context context;     private ImageView imageView;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         context= this;         findViews();         new RunWork().start();     }     private void findViews(){         textView = (TextView)findViewById(R.id.textView);         textView2 = (TextView)findViewById(R.id.textView2);         imageView = (ImageView)findViewById(R.id.imageView);     }     /*上網抓資料,需要另外開執行緒做處理(Android機制)*/     private class RunWork extends Thread     {         //宣告變數         String result_xml = "";        String path = "http://opendata.cwb.gov.tw/govdownload?dataid=E-A0015-001R&authorizationkey=rdec-key-123-45678-011121314";        Runnable task = new Runnable(){             @Override             public void run() {                 parseXml(result_xml);             }         };         //OkHttpClient官網範例使用         OkHttpClient client = new OkHttpClient();        String run(String url) throws IOException {             Request request = new Request.Builder()                     .url(url)                     .build();             Response response = client.newCall(request).execute();             return response.body().string();         }         @Override         public void run()         {             try{                 //1.抓資料                 result_xml = run(path);                 //2.改變畫面內容只能用主執行緒(Android機制)               runOnUiThread(task);             } catch(IOException e) {                 e.printStackTrace();             }         }     }     //DOM來解析XML格式資料     private void parseXml(Stringresult_xml){         try {             //取得XML根節點            InputStream is = new ByteArrayInputStream(result_xml.getBytes(StandardCharsets.UTF_8));
           DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);            Element root = document.getDocumentElement();             //取得 TagName 裡的內容            String reportContent = root.getElementsByTagName("reportContent").item(0).getTextContent();
String magnitudeValue = root.getElementsByTagName("magnitudeValue").item(0).getTextContent();
            String shakemapImageURI = root.getElementsByTagName("shakemapImageURI").item(0).getTextContent();             StringBuilder sb = new StringBuilder();             //取得 Node List            NodeList shakingAreas = root.getElementsByTagName("shakingArea");
            //取得 Node             for(int i=0;i<shakingAreas.getLength();i++){                 Element element = (Element) shakingAreas.item(i);                 String areaName = element.getElementsByTagName("areaName").item(0).getTextContent();                 String areaIntensity = element.getElementsByTagName("areaIntensity").item(0).getTextContent();                 //取得 Node內參數值               String unit = element.getElementsByTagName("areaIntensity").item(0).getAttributes().getNamedItem("unit").getTextContent();               sb.append(areaName).append("  ").append(areaIntensity).append(unit).append("\n");             }             //設定顯示畫面資料              /*Picasso第三方套件:用來抓 url 圖片*/            Picasso.with(context).load(shakemapImageURI).into(imageView);             textView.setText(reportContent +"\n" + magnitudeValue);             textView2.setText(sb);         } catch(ParserConfigurationException e) {
          e.printStackTrace();         } catch(SAXException e) {             e.printStackTrace();         } catch(IOException e) {             e.printStackTrace();         }     } }



參考資料:

1: 文件物件模型(Document Object Model, DOM)

Android 中HttpURLConnection 使用詳解- 壹讀




2016年7月2日 星期六

Android App 登入畫面動畫

本範例要介紹的是 Android App 登入畫面動畫的特效功能,登入畫面動畫的好處是可以展示產品的LOGO, 或是把一些使用者常用的資料, 在開啟程式之前就先抓好或啟動起來, 這樣一來使用者一旦進入程式,就可以很迅速地將程式開啟。

1.res部分在 anim 裡建立 xml 的特效動畫設定(透明度變化),drawable裡放置顯示圖片。


2.layout部分設兩個畫面供畫面轉換。


 3.使用 Animation.AnimationListener 的介面,在 onAnimationEnd 裡當動畫結束後做intent的切換。
WelcomeActivity.java
package gae.melvin.com.app_welcomeview;

import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;

public class WelcomeActivity extends AppCompatActivity implements Animation.AnimationListener{

    private ImageView imageView;
    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);
        context = this;

        //取消ActionBar
        getSupportActionBar().hide();
        //取消狀態欄
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        imageView = (ImageView)findViewById(R.id.imageView);

        //imageView 設定動畫元件(透明度調整)
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.welcome_anim);
        animation.setFillEnabled(true);
        animation.setFillAfter(true);
        animation.setAnimationListener(this);
        imageView.setAnimation(animation);
    }
    /*實作 Animation.AnimationListener 的三種方法*/
    @Override
    public void onAnimationStart(Animation animation) {}

    @Override
    public void onAnimationEnd(Animation animation) {
        startActivity(new Intent(context,MainActivity.class));
        finish();
    }

    @Override
    public void onAnimationRepeat(Animation animation) {}

}

MainActivity.java
package gae.melvin.com.app_welcomeview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("主畫面");
    }

}

4.呈現效果


2016年7月1日 星期五

使用 okHttp 的 GET 方式讀取 JSON 資料

如下圖所示,本範例使用 OKHttp 來讀取 JSON 多筆資料,並由 GSON(GSON是Google 開發用來解析JSON 格式資料的 Library) 來解析 JSON 格式資料,並由App顯示出相關訊息。
34.png


1.找到對應的module ,依照步驟下載 GSON 和 OKHttp 的 Library。


2.OKHttp官網裡有提供GET的範例,可直接套用。


3.lauout.xml。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical"     tools:context="gae.melvin.com.app_welcomeview.WelcomeActivity">     <ImageView         android:layout_width="match_parent"         android:layout_height="match_parent"         android:id="@+id/imageView"         android:src="@drawable/diary"         android:layout_gravity="center_vertical"         android:scaleType="fitCenter" /> </LinearLayout>
4.Book.java。
package gae.melvin.com.app_okhttp_gson;

public class Book {
    private long key;
    private String title;
    private String author;
    private String price;
    private long time;

    public long getKey() {
        return key;
    }

    public void setKey(long key) {
        this.key = key;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }
}

5.MainActivity.java。
package gae.melvin.com.app_okhttp_gson;


import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.google.gson.Gson;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.IOException;



public class MainActivity extends AppCompatActivity {

    private TextView textView;

    @Override

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView)findViewById(R.id.textView);
        new RunWrok().start();

    }


    /*上網抓資料,需要另外開執行緒做處理(Android機制)*/
    class RunWrok extends Thread
    {
        String path_json ="http://android0620-1348.appspot.com/query";
        String result_json = null;

        /* This program downloads a URL and print its contents as a string.*/
        OkHttpClient client = new OkHttpClient();
        String run(String url) throws IOException {
            Request request = new Request.Builder()
                    .url(url)
                    .build();

            Response response = client.newCall(request).execute();
            return response.body().string();
        }

        Runnable task = new Runnable()
        {
            @Override
            public void run() {
                //使用 gson 解析 json 資料
                Gson gson = new Gson();
                Book[] books = gson.fromJson(result_json,Book[].class);

                StringBuilder sb = new StringBuilder();
                for(Book book :books){
                    sb.append("書名:").append(book.getTitle()).append(" ")
                            .append("作者:").append(book.getAuthor()).append(" ")
                            .append("價錢:").append(book.getPrice()).append("\n\n");
                }
                textView.setText(sb);

            }
        };

        @Override
        public void run()
        {
            try {
                //1.抓資料
                result_json = run(path_json);
                //2.改變畫面內容只能用主執行緒(Android機制)
                runOnUiThread(task);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }


}

6.AndroidManifest.xml,上網權限要開。


[java] 條件控制

前言: 在 java 的條件控制中可分為 if-else 架構、三元運算子、switch-case 架構這三類,其中 if-else、三元運算子為條件型的判斷,條件必須為 true/false布林值;switch-case 為比對變數型的判斷,條件值比較多可以是 char、...