Didn't find class "android.support.v4.view.ViewPager"

 넷상에 업로드된 안드로이드 패키지를 다운받아 빌드를 한 후 안드로이드에 실행하였을 경우 다음과 같은 오류가 발생하는 경우가 있습니다.


Didn't find class "android.support.v4.view.ViewPager"


 android.support.v4 패키지는 안드로이드가 새로운 버전에 추가된 기능(클래스)들을 이전 버전에서도 사용할 수 있도록 해주는 패키지입니다. 최근에는 안드로이드 프로젝트를 새로 만들 때 해당 프로젝트에 자동으로 로딩이 될 수 있게 해주기 때문에 따로 추가하는 등의 번거로운 과정을 덜 수 있었습니다.

 그렇다면 android.support.v4를 적용하는 방법을 알아보도록 하겠습니다.


 1. Android SDK Manager를 실행하여 Extra(가장 아랫쪽 목록)에서 Android Support Library를 설치합니다. 




2. 이클립스를 실행한 후 android.support.v4 패키지를 추가할 프로젝트를 클릭한 후 Project->Properties-> Java build Path->Libraries 를 선택합니다.



3. 위와 같은 화면이 나올 경우 오른쪽 메뉴에서 Add External JARs를 선택하여  android.support.v4 패키지를 추가합니다.

  android.support.v4 패키지는 Android SDK Tool을 설치한 폴더에 있으며 Windows 기준으로 다음 경로에서 확인하실 수 있습니다.

 C:\Program Files\Android\android-sdk\extras\android\support\v4



4.android.support.v4 패키지를 추가한 후 Order and Export 탭으로 들어간 후  android-support-v4.jar를 체크한 후 맨 위로 옮겨놓습니다.




 다음과 같이 설정하시면  android.support.v4 패키지가 적용된 프로그램이 정상적으로 동작하는 것을 확인하실 수 있습니다.

300x250

URL을 통해 안드로이드로 xml 파일 다운로드

 안드로이드 프로그램에서 필요한 자료를 받기 위해서는 URL을 통해 해당 주소에 있는 원하는 자료를 다운로드 받아 사용할 수 있습니다.

 특히 RSS와 같이 지속적으로 갱신되는 파일의 경우 실시간으로 새로운 정보를 수신해야 하기 때문에 이를 활용해 xml 파서를 이용하기도 하지요.


 만약 용량이 큰 파일을 다운로드할 경우 프로그램이 다운로드를 완전히 마치지 않고 바로 다음 단계로 넘어가는 경우가 있습니다. 다운로드를 완전히 끝내기 위해서 자바의 Thread를 사용하였습니다. Thread의 join() 함수는 Thread가 종료될 때 까지 함수가 선언한 단계에서 다음 단계로 넘어가지 않고 기다립니다.


 아래는 rss를 다운로드 하여 String으로 객체화 시킨 예제입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
 
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
 
public class MainActivity extends ActionBarActivity {
    TextView textview1;
    String xml;
    URL url;
    HttpURLConnection conn;
    InputStreamReader isr;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        textview1 = (TextView) findViewById(R.id.textview1);
 
        try {
            rcvXml RX = new rcvXml();
            RX.start();
            RX.join();
            textview1.setText(xml);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    class rcvXml extends Thread {
        public void run() {
            try {
                url = new URL("http://www.kma.go.kr/wid/queryDFS.jsp?gridx=60&gridy=126");
                BufferedReader in = new BufferedReader(new InputStreamReader(
                        url.openStream(), "UTF-8"));
                xml = in.readLine();
                while(true){
                    String temp;
                    temp = in.readLine();
                    if(temp==null)
                        break;
                    xml += temp;
                }
            } catch (Exception e) {
 
            }
        }
    }
}
 
 
 


300x250

(JSON) 기상청으로부터 지역코드 받아오기

 날씨과 관련된 프로그램을 제작하는 분들이라면 기상청에서 제공하는 api가 거의 반드시 필요하실 것이라 생각합니다.

 기상청으로부터 자신이 원하는 지역의 날씨를 받아오기 위해서는 기상청에서 제공하는 RSS를 수신하여 이를 가지고 날씨를 알아낼 수 있습니다. 이를 위해서는 기상청에서 제공하는 지역코드를 통해 해당 지역의 날씨를 받아와야 하지요.

 기상청에서는 해당 지역코드를 알아내기 위해 다음과 같은 JSON파일을 제공합니다.


각 지역 시,도의 코드를 제공합니다.

http://www.kma.go.kr/DFSROOT/POINT/DATA/mdl.11.json.txt
mdl.11.json에서 11은 위에서 알아댄 시,도 코드입니다. 해당 코드를 입력하면 해당 시,도의 시군구 목록이 나타납니다.

leaf.11545,json에서 11545는 위의 과정에서 알아낸 시군구 코드입니다. 이 코드를 통해 자신이 원하는 자료를 알아내실 수 있습니다.

위의 주소로 접속할 경우 다음과 같이 알 수 없는 메시지가 나오는 경우가 있습니다.


이는 JSON파일을 읽어들이는데 인코딩 문제로 인해 나타는 경우입니다. 이를 제대로 보기 위해서 오른쪽 버튼을 클릭한 후 인코딩 → UTF-8 로 변경하시면 됩니다.





그럼 이 JSON파일을 사용하여 지역코드를 받아오는 코드를 간단하게 짜보도록 하겠습니다.


※안드로이드에서는 기본적으로 JSON을 활용하는 클래스가 설정되어 있어 간단하게 사용이 가능합니다. 순수 자바로 구현할 경우 별도의 과정이 추가로 필요합니다.

import org.json.JSONArray;

import org.json.JSONObject;



1. 먼저 JSON을 통해 인터넷에 접속하기 위해서는 안드로이드에 인터넷 접속을 허용하는 permission을 다음과 같이 추가합니다.


AndroidMenifest.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.framework.json" >
 
    <uses-permission android:name="android.permission.INTERNET" />
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>
cs


2. 다음으로 아래의 코드를 삽입해줍니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
public class MainActivity extends AppCompatActivity {
    URL RSSurl = null;
    rcvJson RJ;
    URLConnection connect;
    JSONObject JStoken;
    String getJSON;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ....
 
 
        TextView textview = (TextView) findViewById(R.id.textView);
 
        try {
            String Local1 = "서울특별시";
            String Local2 = "용산구";
            String Local3 = "서빙고동";
            String temp;
            String x="0",y="0";
            JSONArray JSA;
 
            RSSurl = new URL("http://www.kma.go.kr/DFSROOT/POINT/DATA/top.json.txt");
            RJ = new rcvJson();
            RJ.start();
            RJ.join();
            JSA = new JSONArray(getJSON);
 
            temp="";
 
            for(int i=0; i < JSA.length(); i++){
                JStoken = JSA.getJSONObject(i);
                if(JStoken.get(JStoken.names().getString(0)).equals(Local1)){
                    temp += JStoken.get(JStoken.names().getString(1));
                    break;
                }
            }
 
            RSSurl = new URL("http://www.kma.go.kr/DFSROOT/POINT/DATA/mdl."+temp+".json.txt");
            RJ = new rcvJson();
            RJ.start();
            RJ.join();
            JSA = new JSONArray(getJSON);
 
            temp="";
 
            for(int i=0; i < JSA.length(); i++){
                JStoken = JSA.getJSONObject(i);
                if(JStoken.get(JStoken.names().getString(0)).equals(Local2)){
                    temp += JStoken.get(JStoken.names().getString(1));
                    break;
                }
            }
 
            RSSurl = new URL("http://www.kma.go.kr/DFSROOT/POINT/DATA/leaf."+temp+".json.txt");
            RJ = new rcvJson();
            RJ.start();
            RJ.join();
            JSA = new JSONArray(getJSON);
 
            temp="";
 
            for(int i=0; i < JSA.length(); i++){
                JStoken = JSA.getJSONObject(i);
                x = JStoken.get(JStoken.names().getString(2)).toString();
                y = JStoken.get(JStoken.names().getString(1)).toString();
                if(JStoken.get(JStoken.names().getString(0)).equals(Local3))
                    break;
            }
 
            textview.setText(x + ","+ y);
 
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
 
 
 
    }
 
}
cs

1
2
3
4
5
6
7
8
9
10
11
12
class rcvJson extends Thread {
        public void run() {
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(
                        RSSurl.openStream(), "UTF-8"));
                getJSON = in.readLine();
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }


위의 소스코드를 실행하면 아래와 같은 결과를 확인하실 수 있습니다.



300x250

좌표값 위도와 경도로 위치주소 구하기

 지도 기반의 프로그램을 개발하시는 분들이라면 GPS와 같은 기능을 통해 원하는 위치의 좌표값을 구하실 수 있습니다. 안드로이드에서는 이를 활용하여 해당위치의 주소를 불러올 수 있는데요 이는 Geocoder 클래스를 사용하여 만들 수 있습니다.

 Geocoder를 활용하여 간단한 프로그램을 만들어보았습니다. 동작환경은 2.3.3 진저브레드입니다.

MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import java.io.IOException;
import java.util.List;
import java.util.Locale;
 
import android.support.v7.app.ActionBarActivity;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
 
public class MainActivity extends ActionBarActivity {
 
    TextView textview1;
    EditText edittext1, edittext2;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        textview1 = (TextView) findViewById(R.id.textView1);
        edittext1 = (EditText) findViewById(R.id.editText1);
        edittext2 = (EditText) findViewById(R.id.editText2);
 
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
 
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
    public void OnClick(View v){
        double lat, lng;
        String getDouble;
        switch(v.getId()){
        case R.id.button1:
            getDouble = edittext1.getText().toString();
            if(getDouble.equalsIgnoreCase("")){
                Toast.makeText(MainActivity.this"위도값을 입력하세요.", Toast.LENGTH_LONG).show();
                break;
            }else{
                lat = Double.parseDouble(getDouble);
            }
            getDouble = edittext2.getText().toString();
            if(getDouble.equalsIgnoreCase("")){
                Toast.makeText(MainActivity.this"경도값을 입력하세요.", Toast.LENGTH_LONG).show();
                break;
            }else{
                lng = Double.parseDouble(getDouble);
            }
            getLocation(lat, lng);
        }
    }
    
    public void getLocation(double lat, double lng){
        String str = null;
        Geocoder geocoder = new Geocoder(this, Locale.KOREA);
        
        List<Address> address;
        try {
            if (geocoder != null) {
                address = geocoder.getFromLocation(lat, lng, 1);
                if (address != null && address.size() > 0) {
                    str = address.get(0).getAddressLine(0).toString();
                }
            }
        } catch (IOException e) {
            Log.e("MainActivity""주소를 찾지 못하였습니다.");
            e.printStackTrace();
        }
        
        textview1.setText(str);
        
    }
    
}


activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
 
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="주소 출력" />
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
 
        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="위도" />
 
        <EditText
            android:id="@+id/editText1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="numberDecimal" >
 
            <requestFocus />
        </EditText>
 
    </LinearLayout>
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
 
        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="경도" />
 
        <EditText
            android:id="@+id/editText2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="numberDecimal" />
 
    </LinearLayout>
 
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="주소확인"
        android:onClick="OnClick" />
 
</LinearLayout>


Manifest.xml에는 다음과 같이 퍼미션을 설정시켜 줍니다.

1
2
3
4
5
6
7
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <library android:name="com.google.android.maps"/>


프로그램을 실행하면 다음과 같은 결과를 얻으실 수 있습니다.


300x250