이 글의 요약 

-  로컬에 있는  웹 파일들을 불러와서 작업할때


웹뷰를 사용하는데 있어서 두드러지는 장점은 , 앱안에 필요한 웹 리소스들을 저장할수있다는것이다.

그것은 오프라인일때도 작업을 가능케 해주며, 로딩시간을 증진시킬것이다. 

HTML, JavaScript, CSS  를 assets 디렉토리 (src/main/assets 등에 만듬)로부터 가져와보자.

주의:   CSS 나 Javascript  를 참조할때 절대경로는  WebView 에서 작동하지 않는다.  다음과 같이 상대경로로  설정해야한다. ("/pages/somelink.html"  -> "./pages/index.html" )

아래와 같이 로딩하자.  ( 리모트에 있는 URL 을 읽어와서 작업하기 전에 전처리할것들을 이렇게 처리해도될듯)

mWebView.loadUrl("file:///android_asset/www/index.html");

( assets 안에 www 만들었어도, 링크는 저렇게'android_asset'  해야한다.)


shouldOverrideUrlLoading  를 요렇게 하면 로컬페이지가 아닐경우 브라우저를 오픈한다. 

public class MyAppWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if(Uri.parse(url).getHost().length() == 0) {
            return false;
        }

        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        view.getContext().startActivity(intent);
        return true;
    }

}




레퍼런스 :

https://developer.chrome.com/multidevice/webview/gettingstarted  




WRITTEN BY
[前草] 이승현 (wowlsh93@gmail.com)
스타코프 (데이터지능플랫폼pd) (관심분야: 에너지IoT, 시계열(NILM) 데이터, 폴리글랏 프로그래밍 )

트랙백  0 , 댓글이 없습니다.
secret

이 글의 요약 

-  원하는 URL 만 웹뷰로 보여주고, 나머지는 모바일 브라우저를  새창으로 띄우고 싶을때 



webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://www.html5rocks.com/");

안드로이드에 webview 를 추가한후에 이것만 코딩한후에  실행시켜보면 , 의도와는 다르게 

앱 내부의 webview 에서 페이지가 뜨는것이아니라, 외부 브라우저를 통해서 띄우려고 할것인데..

이벤트가 일어나는 순서는 :

  1. WebView 는 리모트서버로부터 원래  URL 로딩을 시도하고, 새로운  URL 로 리다이렉트를 갖는다.
  2. WebView 는 시스템이 URL 에 대해 뷰 인텐트를 핸들링할수있는지 체크하고 만약 그렇다면 시스템은 URL 네비게이션을 핸들링한다. 그렇지 않으면  웹뷰는 내부적으로 네비게이트할것이다. (즉, 디바이스에 브라우저가 없다면)
  3. 시스템은 사용자의 http:// URL 을 핸들링할수있는 더 나은 어플리케이션을 선택한후 (즉, 사용자 디폴트 브라우저) 만약, 브라우저가 많으면 아래처럼 선택창을 띄운다.

browser selection dialog

만약 , 어플리케이션의 내부의 웹뷰를 통해서 보고싶으면 WebView 로 부터의 다양한 이벤트를 핸들링할수있 WebViewClient 를 오버라이딩해야한다. 

아래 같은 기본 WebViewClient 구현은 웹뷰에서 어떤 URL 이나 열수있게 한다.

// 브라우저 대신해 WEBVIEW 로 열기위해 강제로 링크하고 리다이렉트한다.

webView.setWebViewClient(new MyAppWebViewClient());

public class MyAppWebViewClient extends WebViewClient {

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url){
         return false;
}
}


return true 로 하면 처리하지 않는다. (웹뷰에 아무것도 나타나지 않음) 


그럼 다른 싸이트 말고, 원하는 싸이트만 열수있게 하려면 어떻게 해야하는가?

shouldOverrideUrlLoading  메소드를 오버라이딩하면 된다. 

아래와 같이 코드를 추가해보자.


  1. public class MyAppWebViewClient extends WebViewClient {
            
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if(Uri.parse(url).getHost().endsWith("html5rocks.com")) {
                    return false;
                }
                 
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                view.getContext().startActivity(intent);
                return true;
            }
        }

    URL 이 html5rocks.com 으로 끝나는것은 내부 웹뷰에서 처리한다는 뜻이다.  리턴 false 는 그 자신이 처리한다는 뜻이고, 만약 다른 URL 이라면 새로운 안드로이드 Intent 를 사용해서 새로운 액티비티 (설치된 모바일 브라우저) 를 호출하게된다.



레퍼런스 :

https://developer.chrome.com/multidevice/webview/gettingstarted  


WRITTEN BY
[前草] 이승현 (wowlsh93@gmail.com)
스타코프 (데이터지능플랫폼pd) (관심분야: 에너지IoT, 시계열(NILM) 데이터, 폴리글랏 프로그래밍 )

트랙백  0 , 댓글이 없습니다.
secret

기존에 스위치를 켜고/끄는 IOT 용 솔루션이 모바일웹으로 만들어져있었다. 

서버로 1번이나 2번스위치 ID 를 입력하여 스위치 조작을 할수있었다.

근데 매번 ID 를 입력하기는 귀찮은 일이었다.

따라서 전력공급원(콘센트)에 QR 코드를 붙혀놓고,자동으로 읽어서 자동으로 스위치를 켜주려했다.

하지만 모바일웹에서는 카메라를 조작하여 QR 코드를 읽을수 없었다.

그래서 하이브리드앱을 만들어야했다.

하이브리드 앱은 보통 2가지로 하나는 아이오닉(폰갭) 같은것을 이용하는것인데

이것의 목적은 하나의 앱을 개발해서 다양한 플랫폼에서 사용하기 위함이고

다른 종류의 하이브리드앱은 다음이나 네이버앱처럼 네이티브기능을 쓰면서

기존의 모바일웹 방식의 (자주 업데이트가 생기는 컨텐트) 를 그대로 가져다 사용하기 위함이다.

2번째의 하이브리드앱 형태가 다양한 앱개발 형태중에서 내가 만들 앱에 맞다고 판단하여

안드로이드 네이티브 앱을 이용하여 기존 모바일웹은 웹뷰로 대체하고 QR 스캐너를 부착하였다.

다음은 웹뷰와 QR 스캐닝의 간단한 예를 보여준다.


<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" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="@+id/loadButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" 열기 "
android:padding="4dp"
android:textSize="20dp"
/>
<EditText
android:id="@+id/urlInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:inputType="textUri"
/>
</LinearLayout>

<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

</LinearLayout>

                                                      res/layout/activity_main.xml



public class MainActivity extends ActionBarActivity {

private static final String TAG = "MainActivity";

private WebView webview;


private Button loadButton;


private Handler mHandler = new Handler();

@SuppressLint("JavascriptInterface")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// 웹뷰 객체 참조
webview = (WebView) findViewById(R.id.webview);

// 웹뷰 설정 정보
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);

webview.setWebChromeClient(new WebBrowserClient());
webview.addJavascriptInterface(new JavaScriptMethods(), "sample");

// assets 폴더에 있는 메인 페이지 로딩
webview.loadUrl("file:///android_asset/www/sample.html");

final EditText urlInput = (EditText) findViewById(R.id.urlInput);

// 버튼 이벤트 처리
loadButton = (Button) findViewById(R.id.loadButton);
loadButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// 입력한 URL의 페이지 로딩
webview.loadUrl(urlInput.getText().toString());
}
});

}

/**
* 자바스크립트 함수를 호출하기 위한 클래스 정의
*/
public class JavaScriptMethods {

JavaScriptMethods() {

}

@android.webkit.JavascriptInterface
public void clickOnFace() {
mHandler.post(new Runnable() {
public void run() {
// 버튼의 텍스트 변경
loadButton.setText("클릭후열기");
// 자바스크립트 함수 호출
webview.loadUrl("javascript:changeFace()");
}
});

}
}

final class WebBrowserClient extends WebChromeClient {
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.d(TAG, message);
result.confirm();

return true;
}
}


...
}

                                                               MainActivity.java


웹뷰관련 링크 

http://blog.acronym.co.kr/528

http://kimhs20.com/wp/?p=334

https://opentutorials.org/module/1234/8081



QR 스캐너 


public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View view)
{
// QR코드/바코드 스캐너를 구동합니다.
IntentIntegrator.initiateScan(MainActivity.this);
}
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
// QR코드/바코드를 스캔한 결과 값을 가져옵니다.
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);

// 결과값 출력
new AlertDialog.Builder(this)
.setTitle(R.string.app_name)
.setMessage(result.getContents() + " [" + result.getFormatName() + "]")
.setPositiveButton("확인", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.show();
}
}

QR 스캐너 관련 링크

http://hs36.tistory.com/36  


WRITTEN BY
[前草] 이승현 (wowlsh93@gmail.com)
스타코프 (데이터지능플랫폼pd) (관심분야: 에너지IoT, 시계열(NILM) 데이터, 폴리글랏 프로그래밍 )

트랙백  0 , 댓글이 없습니다.
secret