[안드로이드] Error:Execution failed for task ':app:transformClassesWithDexForDebug'. 오류 해결 방법



신나게 코딩하고나서 모바일로 테스트 까지 다 해놓고


APK파일로 묶으려는데 저런 에러가 나서 당황스러운 경우가 있었다.



대체 뭐지.. 뭘까..


하고 뒤쪽의 에러를 더 봤더니



com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: 

com.android.dex.DexException: Multiple dex files define Lcom/google/zxing/BarcodeFormat;



이런 내용의 로그가 나타났고


저기서 잘 보아야 할것은


Multiple dex files define 


바로 이부분이었다


음... 뭐 다중 어쩌구 파일을 못찾겠다 뭐 이런건지


일단 잘 모르니까 검색을 해보니


역시나 스택오버플로우 형님들이 좋은 답변들을 알려주었다



안드로이드 build.gradle (app 레벨)에 들어가서


몇줄 추가해 주도록 하자


dependencies {
compile 'com.android.support:multidex:1.0.1'
}


디펜던시에서 저 한줄을 추가 해주고



android {

.......
defaultConfig {

.........
multiDexEnabled true
}

.....
}


저렇게 하나 추가해 주도록 하자



그리고 AdnroidManifest.xml에 가서


<application
.....
android:name="android.support.multidex.MultiDexApplication">

......
</application>


어플리케이션단에 추가를 해준다



그럼 해결이 된다!

[Java] 문자열 바이트로 자르기 


전문통신을 하다보니


한글의 경우는


바이트수가 바뀌어서 


난감했던 경우가 있다.


예를들어 300바이트 짜리 전문인데


영문과 숫자만 있으면 길이가 300이지만


한글이 섞여있으면


한글 1글자당 길이가 1개씩 줄어든다.


한글은 2바이트를 차지하기 때문인데


이때 바이트 단위로 끊어내고 다시 문자열로 반환해 주는 코드 이다.





public  String getString(String str, int sPoint, int length) throws Exception{
String EncodingLang = "euc-kr";
byte[] bytes = str.getBytes("euc-kr");

byte[] value = new byte[length];

if(bytes.length < sPoint + length){
throw new Exception("Length of bytes is less. length : " + bytes.length + " sPoint : " + sPoint + " length : " + length);
}

for(int i = 0; i < length; i++){
value[i] = bytes[sPoint + i];
}

/* System.out.println("utf-8 -> euc-kr : " + new String(word.getBytes("utf-8"), "euc-kr"));
System.out.println("utf-8 -> ksc5601 : " + new String(word.getBytes("utf-8"), "ksc5601"));
System.out.println("utf-8 -> x-windows-949 : " + new String(word.getBytes("utf-8"), "x-windows-949"));
System.out.println("utf-8 -> iso-8859-1 : " + new String(word.getBytes("utf-8"), "iso-8859-1"));
System.out.println("iso-8859-1 -> euc-kr : " + new String(word.getBytes("iso-8859-1"), "euc-kr"));
System.out.println("iso-8859-1 -> ksc5601 : " + new String(word.getBytes("iso-8859-1"), "ksc5601"));
System.out.println("iso-8859-1 -> x-windows-949 : " + new String(word.getBytes("iso-8859-1"), "x-windows-949"));
System.out.println("iso-8859-1 -> utf-8 : " + new String(word.getBytes("iso-8859-1"), "utf-8"));
System.out.println("euc-kr -> utf-8 : " + new String(word.getBytes("euc-kr"), "utf-8"));
System.out.println("euc-kr -> ksc5601 : " + new String(word.getBytes("euc-kr"), "ksc5601"));
System.out.println("euc-kr -> x-windows-949 : " + new String(word.getBytes("euc-kr"), "x-windows-949"));
System.out.println("euc-kr -> iso-8859-1 : " + new String(word.getBytes("euc-kr"), "iso-8859-1"));
System.out.println("ksc5601 -> euc-kr : " + new String(word.getBytes("ksc5601"), "euc-kr"));
System.out.println("ksc5601 -> utf-8 : " + new String(word.getBytes("ksc5601"), "utf-8"));
System.out.println("ksc5601 -> x-windows-949 : " + new String(word.getBytes("ksc5601"), "x-windows-949"));
System.out.println("ksc5601 -> iso-8859-1 : " + new String(word.getBytes("ksc5601"), "iso-8859-1"));
System.out.println("x-windows-949 -> euc-kr : " + new String(word.getBytes("x-windows-949"), "euc-kr"));
System.out.println("x-windows-949 -> utf-8 : " + new String(word.getBytes("x-windows-949"), "utf-8"));
System.out.println("x-windows-949 -> ksc5601 : " + new String(word.getBytes("x-windows-949"), "ksc5601"));
System.out.println("x-windows-949 -> iso-8859-1 : " + new String(word.getBytes("x-windows-949"), "iso-8859-1"));*/




return new String(value, EncodingLang).trim();
}


[톰캣] 서버 실행시 CMD창 바로 사라지는 문제 해결 방법






톰캣의 startup.bat 파일을 실행시킬때


cmd창이 떳다가 바로 사라지는 경우가 있었다.


뭐 에러 메세지라도 보여야 뭐가 잘못된건지 볼텐데


로그도 쌓이지 않고 그냥 사라져 버리는 문제에 대한 해결 방법이다.



일단 일반 cmd 창을 띄우고


톰캣이 설치된 경로로 이동한다



C:\apache-tomcat-7.0.76-windows-x64\apache-tomcat-7.0.76\bin



빈폴더 까지 이동 후


startup.bat  명령어를 입력하면


메세지가 나타나게 되는데


JRE_home environment variable is not defined correctly

a fatal exception has occurred. program will exit


요런 메세지가 나타난다.


JRE_home 가 아니라 JAVA_HOME 가 나타날 수도 있다


혹은 그외의 메세지가 나타날 수도 있으니


해당 메세지를 보고 오류를 해결하면 된다.


JRE_home environment variable is not defined correctly


이런 오류 메세지가 나타날떄의 해결 방법은


톰캣 bin 폴더의 catalina.bat 파일을 편집기로 열어서


JRE_HOME 나 JAVA_HOME의 경로를 


재지정 해주면 된다.



만약 JRE_HOME이나 JAVA_HOME 에 $JRE_HOME$ 이런 식으로


지정이 되어 있다면


시스템변수에 JAVA_HOME이나 JRE_HOME이 정상적으로


등록이 되어 있는지 확인 한다.



나의 경우는 JRE_HOME을 따로 지정하지 않았는데


톰캣 카탈리나에 JRE_HOME이 $JRE_HOME$ 으로 지정이 되어 있어서


시스템 변수에 JRE_HOME을 등록해 주고 난 후 오류를 해결 했다.



.




혹은 톰캣 윈도우를 실행 할때


지정된 서비스가 설치된 서비스로는 없습니다.


라는 메세지가 뜨는 경우


CMD창을 열어서


톰캣 빈폴더로 이동 후


service.bat install tomcat7


이라는 명령어를 입력하면


해결이 된다.






[안드로이드] 기기의 카메라에 오류가 생겼습니다. 기기를 재시작해야할수도있습니다. 해결방법 






QR코드나 BAR코드 리딩 기능을 넣거나


OCR 문자 인식 관련해서 API 23 이상부터 나타나는 에러이다


해결방법은 간단하다


API23 이전엔 그냥 매니페스트에 권한요청만 하면 되었는데


API23 이후부터는 아얘 권한 요청 팝업을 띄워서


허용을 받아야 한다.


해결방법은 어디서 찾아다가 프로젝트에 적용시켰는데 어디서 본건지 기억이 잘 안난다;





해결 방법은 아래와 같다


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
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        /**********권한 요청************/
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            /**
             * 사용자 단말기의 권한 중 "카메라" 권한이 허용되어 있는지 확인한다.
             *  Android는 C언어 기반으로 만들어졌기 때문에 Boolean 타입보다 Int 타입을 사용한다.
             */
            int permissionResult = checkSelfPermission(Manifest.permission.CAMERA);
 
 
            /** * 패키지는 안드로이드 어플리케이션의 아이디이다. *
             *  현재 어플리케이션이 카메라에 대해 거부되어있는지 확인한다. */
            if (permissionResult == PackageManager.PERMISSION_DENIED) {
 
 
                /** * 사용자가 CALL_PHONE 권한을 거부한 적이 있는지 확인한다. *
                 * 거부한적이 있으면 True를 리턴하고 *
                 * 거부한적이 없으면 False를 리턴한다. */
                if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
                    AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
                    dialog.setTitle("권한이 필요합니다.").setMessage("이 기능을 사용하기 위해서는 단말기의 \"카메라\" 권한이 필요합니다. 계속 하시겠습니까?")
                            .setPositiveButton("네"new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
 
                                    /** * 새로운 인스턴스(onClickListener)를 생성했기 때문에 *
                                     * 버전체크를 다시 해준다. */
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                        // CALL_PHONE 권한을 Android OS에 요청한다.
                                        requestPermissions(new String[]{Manifest.permission.CAMERA}, 1000);
                                    }
                                }
                            })
                            .setNegativeButton("아니요"new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Toast.makeText(MainActivity.this"기능을 취소했습니다", Toast.LENGTH_SHORT).show();
                                }
                            }).create().show();
                }
                // 최초로 권한을 요청할 때
                else {
                    // CALL_PHONE 권한을 Android OS에 요청한다.
                    requestPermissions(new String[]{Manifest.permission.CAMERA}, 1000);
                }
            }
            // CALL_PHONE의 권한이 있을 때
            else {
 
            }
        }
        /************권한요청 끝**************/
 
 
    }
 
 
 
/** * 권한 요청에 대한 응답을 이곳에서 가져온다. * *
     *  @param requestCode 요청코드 *
     *  @param permissions 사용자가 요청한 권한들 *
     *  @param grantResults 권한에 대한 응답들(인덱스별로 매칭) */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 1000) {
            // 요청한 권한을 사용자가 "허용" 했다면...
            if (grantResults.length > 0 && grantResults[0== PackageManager.PERMISSION_GRANTED) {
                // 이곳에 허용했을때 실행할 코드를 넣는다
                // 근데 난 안넣음
 
            } else {
                // 거부했을때 띄워줄 
                Toast.makeText(MainActivity.this"권한요청을 거부했습니다.", Toast.LENGTH_SHORT).show();
            }
        }
    }
 
 
cs



액티비티에서 onCreate 부분에서 권한요청을 날려주면 된다.


메인액티비티에 걸어놨다면 어플을 실행할때 메세지가 뜰 것이다.


최적화를 위해서는


권한이 필요한 액션이 일어날때 권한요청을 물어보는 것이 좋다고 하는데


내가 하는 프로젝트는 웹뷰로 띄워놓고 하는거라


액티비티가 메인액티비티 하나뿐이다.


그리고 귀찮다.



만약 카메라 권한이 아니라 


전화걸기, 데이터접근 등의 권한이라면



Manifest.permission.CAMERA


이부분에서


CAMERA 만 원하는 퍼미션으로 바꿔주면 된다.


물론 하나만 바꾸는게 아니라 저거 적혀있는 모든 코드를 바꿔야 하는건 기본



[자바스크립트] 자바스크립트 다국어 적용 방법



1. 자바스크립트


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
// 언어팩 선언.
$.lang = {};
 
$.lang.ko = {
    0'자바스크립트 다국어 처리.',
    1'안녕하세요',
    2'오늘은 금요일 입니다.',
    3'불금을 즐겨 보아요.'
};
 
$.lang.en = {
    0'Javascript Language Localization.',
    1'Hello.',
    2'Today is Friday',
    3'Fire~!!'
};
    
$.lang.ja = {
    0'JavaScriptの言語',
    1'こんにちは',
    2'今日は金曜日です。',
    3'ガンバレ~!!'
};
 
/**
* setLanguage 
* use $.lang[currentLanguage][languageNumber]
*/
function setLanguage(currentLanguage) {
  console.log('setLanguage', arguments);
  
  $('[data-langNum]').each(function() {
    var $this = $(this); 
    $this.html($.lang[currentLanguage][$this.data('langnum')]); 
  });    
}  
 
// 언어 변경
$('button').click(function() {
  var lang = $(this).data('lang');
  setLanguage(lang); 
});
cs





2. HTML


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-1.8.3.min.js"></script>
  <meta charset="utf-8">
  <title>자바스크립트 다국어 처리.</title>
</head>
<body>
  <div id="wrap">
    <h1 data-langNum="0">자바스크립트 다국어 처리</h1>
    <button data-lang="ko">한국어</button>
    <button data-lang="ja">일본어</button>
    <button data-lang="en">영어</button>
    <hr>
  
    <h2 data-langNum="1">안녕하세요</h2>
    <h2 data-langNum="2">오늘은 금요일 입니다.</h2>
    <h2 data-langNum="3">불금을 즐겨 보아요.</h2>
  </div>
</body>
</html>
cs





출처 : http://jsbin.com/losejo/edit?html,js,output

[안드로이드] 웹뷰 자바스크립트와 안드로이드 자바 연동 방법


안드로이드의 웹뷰를 사용해 개발을 하다 보면 웹뷰에서 띄운 자바스크립트와


안드로이드의 자바 소스간에 연동을 해야 하는 경우가 생긴다



즉 자바스크립트에서 안드로이드 메소드를 호출 하거나


안드로이드에서 자바스크립트 함수를 호출해야 하는 경우인데.


그 방법에 대해서 알아 보도록 하자.



1. mainActivity.java 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final DBHelper dbHelper = new DBHelper(getApplicationContext(), "MoneyBook.db"null1);
        // 웹뷰 셋팅팅
        mWebView = (WebView) findViewById(webView);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.loadUrl(myUrl + "/html/test.html");
        mWebView.setWebChromeClient(new WebChromeClient());
        mWebView.setWebViewClient(new WebViewClientClass());
    
 
        // Bridge 인스턴스 등록
        mWebView.addJavascriptInterface(new AndroidBridge(mWebView, dbHelper, newtwork), "HybridApp");
 
 
 
    }
cs



메인 액티비티의 oncreate 메소드에 웹뷰 셋팅을 해놓고 그 아래에 안드로이드브릿지를 등록 한다.



2. AndroidBridge.java


1번의 15번 라인의 안드로이드 브릿지를 사용하기 위해 클래스를 추가 해 주도록 한다.



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
package com.xxx.xxxxx;
 
import android.os.Handler;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
 
import java.text.SimpleDateFormat;
import java.util.Date;
 
/**
 * Created by Administrator on 2017-08-03.
 */
 
public class AndroidBridge {
    private final Handler handler = new Handler();
    private WebView mWebView;
    private DBHelper dbHelper;
    private  boolean newtwork;
 
    // 생성자
    // 따로 사용할일 없으면 이거 안만들고 위의 변수도 안만들어도 됨.
    public AndroidBridge(WebView mWebView, DBHelper dbHelper, boolean newtwork) {
        this.mWebView = mWebView;
        this.dbHelper = dbHelper;
        this.newtwork = newtwork;
    }
 
    // DB데이터 가져오기
    @JavascriptInterface
    public void requestData() { // must be final
        handler.post(new Runnable() {
            public void run() {
                Log.d("HybridApp""데이터 요청");
                String test  =  dbHelper.getResult();
                Log.d("HybridApp", test);
                mWebView.loadUrl("javascript:getAndroidData('"+test+"')");
            }
        });
    }
 
    // DB에 데이터 저장하기
    @JavascriptInterface
    public void saveData(final String item, final int num) { // must be final
        handler.post(new Runnable() {
            public void run() {
                Date d = new Date();
 
                String s = d.toString();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 
                dbHelper.insert(sdf.format(d), item, num);
                Log.d("HybridApp""데이터 저장");
                String test  =  dbHelper.getResult();
                mWebView.loadUrl("javascript:getAndroidData('"+test+"')");
            }
        });
    }
 
 
 
}
cs



DB데이터 가져온다는 내용은 신경쓰지 말자


일단 1번과 2번을 완료 했다면 안드로이드에서 할일은 끝났다.


여기서 봐야 할 것은


30번 43번 라인의 어노테이션이다. API17이상부터 저 어노테이션을 달아주지 않으면


정상 작동하지 않는다.


그리고 31 44번의 requestData, saveData 이 메소드명이 자바스크립트에서 호출하는 이름이 된다.


그리고 37 55번라인은 안드로이드에서 자바스크립트로 데이터를 날려주면서 


자바스크립트 function을 호출하는 부분이다.



3. javascript


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
$(function(){
    window.HybridApp.requestData();
});
 
function saveData(){
    var item = $("#item").val();
    var num = $("#num").val();
    window.HybridApp.saveData(item, num);
}
 
 
function getAndroidData(data){
    alert(data);
 
    var dataArr = data.split("*nn*");
    $("#testDiv").empty();
    for(var count=0; count < dataArr.length; count++){
        $("#testDiv").append("<p>"+dataArr[count]+" </p>");
    }
 
}
cs



자바스크립트에서 안드로이드 메소드를 호출할땐


window.1의 15번라인에서 선언한 이름.2에서 선언한 메소드명();


이런식으로 호출을 해주면 된다.


만약 3번라인의 리퀘스트데이터를 호출하면


2의 31번 메소드가 응답하며 2의 37번 라인이 동작해 자바스크립트 3의 13번function이 동작한다.




물론 위에 보는 것 처럼 안드로이드와 자바스크립트간의 텍스트 데이터도 전송이 가능 하다.



[안드로이드] androidBridge they will not be visible in API 17 오류 해결 방법




none of the methods in the added interface(androidBridge) have been annotated with @android.webkit   they will not be visible in API 17 


이 오류의 해결 방법 입니다.



1. 원인


안드로이드 버전 API 17 이상부터 androidBridge 사용시 메소드에 어노테이션을 사용해야 정상 구동 하도록

바뀌어서 생기는 오류


2. 해결 방법


간단하게 androidBridge에서 사용하는 메소드위에 어노테이션을 추가 하면 됩니다.



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
package com.xxx.xxxx;
 
import android.os.Handler;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import java.text.SimpleDateFormat;
import java.util.Date;
 
/**
 * Created by Administrator on 2017-08-03.
 */
 
public class AndroidBridge {
    private final Handler handler = new Handler();
    private WebView mWebView;
    private DBHelper dbHelper;
    private  boolean newtwork;
 
    // 생성자
    public AndroidBridge(WebView mWebView, DBHelper dbHelper, boolean newtwork) {
        this.mWebView = mWebView;
        this.dbHelper = dbHelper;
        this.newtwork = newtwork;
    }
 
    // 네트워크 상태 확인
    @JavascriptInterface
    public void requestNetwork() { // must be final
        handler.post(new Runnable() {
            public void run() {
                Log.d("HybridApp""네트워크 상태 요청");
                mWebView.loadUrl("javascript:getNetwork("+newtwork+")");
            }
        });
    }
 
 
 
    @JavascriptInterface
    public void setMessage(final String arg) { // must be final
        handler.post(new Runnable() {
            public void run() {
                Log.d("HybridApp""setMessage("+arg+")");
                mWebView.loadUrl("javascript:getAndroidMessage('ANDROID -> JAVASCRIPT CALL!!')");
            }
        });
    }
 
 
}
cs


간단하게 다른거 볼 필요 없이


28번라인에 추가한 어노테이션을 29번같은 메소드 위에 선언하기만 하면 해당 오류가 해결 된다.



[안드로이드] 인터넷 연결상태 확인하는 방법



개발 하는 프로젝트중 인터넷이 연결 되었을땐 서버DB에서 값을 가져오고

연결이 되지 않았을땐 안드로이드의 sqlite에서 값을 가져와야 하는 기능이 있었다


그래서 찾아서 만들었다.




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
public class MainActivity extends AppCompatActivity {
    private WebView mWebView;
    private String myUrl = "file:///android_asset";
    public static final String WIFE_STATE = "WIFE";
    public static final String MOBILE_STATE = "MOBILE";
    public static final String NONE_STATE = "NONE";
    private boolean newtwork = true;
 
 
    @Override
 
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 앱 실행시 체크
        String getNetwork =  getWhatKindOfNetwork(getApplication());
        if(getNetwork.equals("NONE")){
            newtwork = false;
        }
 
    }
 
    // 인터넷 
    public static String getWhatKindOfNetwork(Context context){
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (activeNetwork != null) {
            if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                return WIFE_STATE;
            } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                return MOBILE_STATE;
            }
        }
        return NONE_STATE;
    }
}
 
cs




일반적인 메인액티비티에 담았다


원래는 저기에 웹뷰셋팅이나 sqlite관련된 소스들도 있는데 보기 힘드니까 다 지움


중요한건 인터넷이 연결된 상태인지만 체크 하는 것


4~7번은 그냥 편의를 위해 전역변수로 지정해놨는데 사용하지 않아도 된다.


25번의 메소드에서 단순하게 true false만 반환해줘도 되는데


저렇게 쓰면 현재 연결된게 와이파이 인지 모바일네트워크인지 구분이 가능하기 때문에 넣은 것.




[안드로이드] 간단하게 웹뷰 구현


간다하게 안드로이드의 웹뷰를 구현해 보도록 하자



1. 메인 액티비티 소스 (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
package com.pois.mtrs_test;
 
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
 
import static com.pois.mtrs_test.R.id.webView;
public class MainActivity extends AppCompatActivity {
    private WebView mWebView;
    private String myUrl = "file:///android_asset"// 접속 URL (내장HTML의 경우 왼쪽과 같이 쓰고 아니면 걍 URL)
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 웹뷰 셋팅팅
        mWebView = (WebView) findViewById(webView);
        mWebView.getSettings().setJavaScriptEnabled(true);
        //mWebView.loadUrl("http://www.pois.co.kr/mobile/login.do");
 
        mWebView.loadUrl(myUrl + "/html/test.html"); // 접속 URL
        mWebView.setWebChromeClient(new WebChromeClient());
        mWebView.setWebViewClient(new WebViewClientClass());
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
            mWebView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
 
    private class WebViewClientClass extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            Log.d("check URL",url);
            view.loadUrl(url);
            return true;
        }
    }
 
 
}
cs




14번 라인의 myurl은 http를 포함한 도메인 주소를 넣으면 된다. 나중에 편하게 쓸일 있을까 해서 걍 변수 처리 한것


23번 라인은 자바스크립트 허용 유무에 대한 것



27번은 웹뷰에 크롬을 사용한다고 하는 건데 저거 안하고 그냥 웹뷰만 쓰면


alert같은 알림창이 뜨지 않는다.


28번 라인에서 셋웹뷰를 한것은


39번부터 시작하는 클래스를 사용하는데


저거 안하면 html 내부에서 다른 페이지로 이동을 할 수가 없다. 그떄그떄 해당 url을 웹뷰에 셋팅해주는 역할을 한다.



2. AndroidManifest.xml 설정 인터넷 퍼미션 추가



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



5번 라인의 인터넷 퍼미션을 추가해줘야 해당 앱에서 인터넷에 접속할수 있다.


간단하게 앱에서 인터넷 사용할 권한을 주는 것이다.



3. layout



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.xxx.xxxx.MainActivity">
 
    <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/webView"
        >
 
 
    </WebView>
 
</LinearLayout>
cs



레이아웃 구조는 이렇게 해주자


웹뷰는 그냥 꽉차게 보여줄거니까 매치 패런트로 해놓는다.



.


[centOS] PHP 5.2 make 설치 오류 해결 방법


dereferencing pointer to incomplete type RETVAL_STRINGL((char *) buf->buffer->content, ret, 1);


php 파일 풀고나서 make 명령어를 치면 저런 에러가 뿜어져 나온다



보안관련 문제인지 일단 php에서 5.2버전은 지원을 중단했기 때문에 나타나는 에러다



https://code.google.com/p/php52-backports/issues/detail?id=16

여기서 패치파일 다운 받고


패치파일을 php 소스 경로에다가 옮겨놓은 다음


# patch -p0 < ./libxml29_compat.patch 

이 명령어를 치면 된다


centos 7 patch 명령을 찾을 수 없습니다 라는 메세지가 나타난다면




#sudo yum install patch


이 명령어로 패치 설치한후


위의 명령어를 실행하면 정상 작동이 된다.






+ Recent posts