언어&플랫폼/Android 2015. 10. 15. 15:50

oncreate에서 

mWvWebView.loadUrl("javascript:myfunctoin(\"2al\")"); 로 바로 실행하였더니 javascript 함수가 실행하지 않고 다음과 같은 로그가 뜬다.


Uncaught ReferenceError: testAlert is not defined



WebViewClient를 구현한 클래스에서 onPageFinished 함수를 오버라이딩 하여

그 부분에서 자바스크립트 함수를 실행하면 된다.


페이지가 전부 로드되기도 전에 함수를 실행하려 해서 안되었나보다.




posted by cozyboy
:
언어&플랫폼/Android 2015. 6. 29. 20:07

인증모듈때문에 NICE ID 페이지와 연동하는 부분이 있었는데 키캣은 잘 동작하였으나 롤리팝에서 was loaded over HTTPS, but is submitting data to an insecure location at 와 같은 로그가 찍혔다.


TLS/SSL Default Configuration Changes

These changes may lead to breakages in HTTPS or TLS/SSL connectivity in a small number of cases listed below.
이러한 변화는 아래 의 경우 소수 HTTPS 또는 TLS / SSL 연결 의 파손 으로 이어질 수 있습니다.


5.0의 변화부분에 위와 같은 글이 있었고, 아래글과 같은 과정으로 해결을 하였다.





안드로이드 롤리팝 Webview 에서 발생한 문제들..
몇일전부터 안드로이드 5.0 버전으로 테스트중인 Nexus 5 에서 결제작업을 연동중에

문제점들이 발견되기 시작했다.

첫번째 : 의외로 간단하게 해결된 문제

HTTPS > HTTP 전송시 내장 브라우저에서 block 시켜 데이터 전송이 안되는 문제였다. 


[blocked] The page at 'https://xxx' was loaded over HTTPS, but ran insecure content from http://xxx.css': this content should also be loaded over HTTPS.


라는 메세지를 콘솔창으로 마구 뱉는 문제였다...

이 문제는 롤리팝에서 변경된 문제였다.

구글링 해보았으나 실제로 안드로이드 관련정보는 찾을수 없었고

해결방안은 Anroid 5.0 Changes 를 보고 찾을 수 있었다.

WebView



If your app targets API level 21 or higher:
  • The system blocks mixed content and third party cookies by default. To allow mixed content and third party cookies, use the setMixedContentMode() and setAcceptThirdPartyCookies() methods respectively.
  • The system now intelligently chooses portions of the HTML document to draw. This new default behavior helps to reduce memory footprint and increase performance. If you want to render the whole document at once, disable this optimization by calling enableSlowWholeDocumentDraw().
  • If your app targets API levels lower than 21: The system allows mixed content and third party cookies, and always renders the whole document at once.


혼합된 컨텐츠와 서드파티 쿠키가 설정에 따라 Webview 에서 Block 시키는 게 기본이 됬다는 내용이였다.


public abstract void setMixedContentMode (int mode)


Configures the WebView's behavior when a secure origin attempts to load a resource from an insecure origin. By default, apps that target KITKAT or below default to MIXED_CONTENT_ALWAYS_ALLOW. Apps targeting LOLLIPOP default toMIXED_CONTENT_NEVER_ALLOW. The preferred and most secure mode of operation for the WebView is MIXED_CONTENT_NEVER_ALLOW and use of MIXED_CONTENT_ALWAYS_ALLOW is strongly discouraged.


MIXED_CONTENT_ALWAYS_ALLOW : 항상 허용



MIXED_CONTENT_COMPATIBILITY_MODE : 호환성 모드



MIXED_CONTENT_NEVER_ALLOW : 허용 안함


해결 소스

if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
set.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.setAcceptThirdPartyCookies(mWeb, true);
}




http://developer.android.com/about/versions/android-5.0-changes.html#ssl

롤리팝(5.0) change log 를 살펴보시면

TLSv1.1과 TLSv1.2, AES-GCM(AEAD)가 지원되고

MD5, 3DES, ECDH등은 더이상 지원하지 않는다고 합니다.

TLS/SSL 기본 설정값이 달라졌기 때문에, 서버가 MD5나 3DES만 지원한다면, 이것을 먼저 고쳐야 한다는 내용인 듯 싶어요




참고, 펌

http://www.masterqna.com/android/40747/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EB%A1%A4%EB%A6%AC%ED%8C%9D%EC%97%90%EC%84%9C-ssl-https-%ED%86%B5%EC%8B%A0%EC%9D%B4-%EC%95%88%EB%90%A9%EB%8B%88%EB%8B%A4

http://kalesst.blogspot.kr/2015/01/android-50-lollipop-webview-issue.html


posted by cozyboy
:
언어&플랫폼/Android 2015. 6. 18. 17:05



IDE : android studio


샘플 코드 주소git clone https://github.com/googlesamples/google-services.git


사용 코드google-services/android/gcm


프로젝트 import : 외부 프로젝트 import 로 실행



과정 참고 : https://developers.google.com/cloud-messaging/android/start

위 싸이트의 설명에 기반한 샘플코드



 https://developers.google.com/cloud-messaging/android/start 에서 설정 파일 받기




위에서 다운받은 google-services.json 파일을 내 프로젝트의 app/ 폴더로 옮긴다.


위에 적힌 Server API key 값을 

GcmSender.java 31 째 줄에 있는 API_KEY에 기입한다.





PUSH 테스트

환경변수에 JAVA_HOME 설정 ( 내컴퓨터 ->속성 -> 설정변경 -> 고급 _> 환경변수)

각자 Jdk가 깔려있는 폴더를 적어두자(java.exe, javaw.exe 같은 파일이 있는 폴더)

위 설정을 하지 않으면 샘플 push 프로그램이 동작하지 않는다.


브로드캐스트 push

1. cmd.exe 를 실행

2. 소스가 깔려있는 곳으로 이동

$ cd {소스폴더경로}\gcm

$ gradlew.bat run -Pargs="푸쉬 할 메시지"

위와 같이 하면 내 어플리케이션이 설치된 모든 앱들에 "What!!!! the"란 문구의 노티피케이션이 뜬다.



유니캐스트 push

유니캐스트 push를 하려면 내 폰이 발급받은 registration id를 알아야 한다.

RegistrationIntentService 클래스에서 57 line에 
Log.i(TAG, "GCM Registration Token: " + token);

이 있다. 이값이 내폰의 레지스트 아이디 값인데 logcat에서 "RegIntentService"로 필터를 해서 키값을 기억하고 있자.


$ gradlew.bat run -Pargs="푸쉬 할 메시지, {레지스트 아이디}"

를 실행하면 특정 폰에만 push가 가게 된다.


위의 registration id를 자신의 서버에 저장해두어 관리해야 나중에 push를 자유롭게 할 수 있겠다.





GcmSender

push 형태를 보면

https://android.googleapis.com/gcm/send 주소에

request 에 서버키를 설정한후

{message:{내매세지}, to:{특정 폰의 레지스트 아이디}} 형태의 json Data를 write 하는 것을 볼 수 있다.


posted by cozyboy
:
언어&플랫폼/Android 2015. 6. 12. 16:31

redo : ctrl + z

forward : ctrl + shift + z


File > Settings > Keymap

Keymaps 선택할 수 있는 선택박스가 있는데 Eclipse 선택하면 완벽히는 아니어도 이클립스처럼 사용할 수 있다.


Editing

 

Ctrl + Space : 기본 코드 완성

Ctrl + Shift + Space : 스마트 코드 완성(예상되는 타입의 메소드또는 변수명 )

Ctrl + Q : 빠른 문서보기

Shift + F1 : 외부 문서보기(http://developer.android.com/reference로 이동)

Ctrl + mouse over code : 간단한 설명.

Alt + Insert : Generate code( Getters, Setters, Constructors, hashCode/equals, toString )

Ctrl + O : Override methods

Ctrl + I : Implement methods

Ctrl + Alt + T : Surround with… (if..else, try..catch, for, synchronized, etc.)

Ctrl + / : 한줄주석

Ctrl + Shift + / : 블럭주석

Ctrl + W : 연속적인 코드블럭 선택

Alt + Enter : 빠른수정.

Ctrl + Alt + L : Reformat code
Ctrl + Alt + O : Optimize imports
Ctrl + Alt + I : Auto-indent line(s)

Ctrl + Shift + V : 이전에 클립보드에 복사한 히스토리 열기.

Ctrl + D : 라인복제 또는 선택블록 복제

Ctrl + Y : 라인삭제

Ctrl + Shift + J : 라인합치기(Smart line join)

Ctrl + Enter : 라인분리(Smart line split)

Ctrl + Shift + U : 대소문자 변환

Ctrl + Shift + ] / [ : 코드블럭 처음또는 끝까지 선택

Ctrl + Delete : 단어끝까지 삭제

Ctrl + Backspace : 단어처음까지 삭제

 

 

 

Search/Replace

 

Double Shift : 모든곳에서 찾기.

Ctrl + F : 찾기

F3 : 다음찾기

Shift + F3 : 이전찾기

Ctrl + R : 바꾸기

Ctrl + Shift + F : 경로에서 찾기(Find in path)
Ctrl + Shift + R : 경로에서 바꾸기(Replace in path)

 

 

 

Usage Search

 

Alt + F7 / Ctrl + F7 : 사용내용 전체찾기 / 파일에서 사용한것 찾기
Ctrl + Shift + F7 : 현재파일에서 하이라이트
Ctrl + Alt + F7 : 사용된것 새창으로 보여줌.

 

 

 

Compile and Run

 

Shift + F10 : Run

 

 

 

Debugging


F8 : Step over
F7 : Step into
Shift + F7 : Smart step into
Shift + F8 : Step out
Alt + F9 : Run to cursor
Alt + F8 : Evaluate expression
F9 : Resume program
Ctrl + F8 : Toggle breakpoint
Ctrl + Shift + F8 : View breakpoints

 

 

 

Navigation


Ctrl + N : 클래스 열기
Ctrl + Shift + N : 파일열기
Ctrl + Alt + Shift + N : Go to symbol
Alt + Right/Left : 문서탭이동

F12 : 이전에 사용한 도구창 열기

Shift + Esc : 마지막에 사용한 도구창 닫기
Ctrl + G : 줄번호로 이동.
Ctrl + E : 이전에 열었던파일 목록창 열기
Ctrl + B or Ctrl + Click : Go to declaration
Ctrl + Alt + B : Go to implementation(s)
Ctrl + Shift + I : Open quick definition lookup
Ctrl + Shift + B : Go to type declaration
Ctrl + U : super-method/super-class 이동.
Alt + Up/Down : 이전/다음 함수 이동

Ctrl + ] / [ :  코드블럭 처음/끝 이동
Ctrl + F12 : 파일 구조보기

F2 / Shift + F2 : 다음/이전 하이라이트된 에러로 이동.
F4 : 해당 소스로 이동

 

 

 

Refactoring

 

F5 : 복사
F6 : 이동
Alt + Delete : 안전하게 삭제(지우기전에 사용된곳 확인 가능)

Shift + F6 : 이름바꾸기

 

 

 

Live Templates


Ctrl + Alt + J : Surround with Live Template
Ctrl + J : Insert Live Template
iter : Iteration according to Java SDK 1.5 style
inst : Check object type with instanceof and downcast it
itco : Iterate elements of java.util.Collection
itit : Iterate elements of java.util.Iterator
itli : Iterate elements of java.util.List
psf : public static final
thr : throw new


출처 http://blog.naver.com/komseki/130185867089

posted by cozyboy
:
언어&플랫폼/Android 2015. 6. 12. 10:50



절차 

1. 웹뷰 인터페이스 만들기

2. webview에서 intent를 활용해 파일 선택하여 경로 얻기

3. javascript에서 android 함수 호출하기(하이브리드앱-웹뷰와 모바일 브라우저 구분해서 호출)


안드로이드 샘플 코드 -> 웹서버 샘플 코드



안드로이드 샘플 코드

package com.example.i.test1;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;


public class MainActivity extends Activity {

private WebView mWebView;
private WebViewInterface mWebViewInterface;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.activity_main_webview);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.setWebChromeClient(new WebChromeClient());
mWebView.setWebViewClient(new MyAppWebBiewClient());

mWebViewInterface = new WebViewInterface(MainActivity.this, mWebView); //JavascriptInterface 객체화

mWebView.addJavascriptInterface(mWebViewInterface, "Android"); //웹뷰에 JavascriptInterface를 설정

//인자로는 인터페이스 객체와, javascript에서 사용될 객체이름(window.Android)


mWebView.loadUrl("http://내 웹서버/");
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

@Override
public void onBackPressed() {
if(mWebView.canGoBack()){
mWebView.goBack();
}
else{
super.onBackPressed();
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case 1: {
if (resultCode == RESULT_OK){
Uri uri = data.getData();
String filePath = uri.getPath();
Toast.makeText(this, filePath, Toast.LENGTH_LONG).show();    //intent data로 받은 파일 경로를 출력
}
}
}


}

public class WebViewInterface extends Activity {

private WebView mAppView;
private Activity mContext;

/**
* 생성자.
* @param activity : context
* @param view : 적용될 웹뷰
*/
public WebViewInterface(Activity activity, WebView view) {
mAppView = view;
mContext = activity;

}
/**
* 안드로이드 토스트를 출력한다. Time Long.
* @param message : 메시지

*/
@JavascriptInterface
public void toastLong (String message) {
Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
Intent chooseFile;
Intent intent;
chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("file/*");
intent = Intent.createChooser(chooseFile, "Choose a file");
mContext.startActivityForResult(intent, 1);
//파일을 오픈할 앱을 선택->파일선택->파일경로 data에 넣고 resultData에 넣어주기
}

/**
* 안드로이드 토스트를 출력한다. Time Short.
* @param message : 메시지
*/
@JavascriptInterface
public void toastShort (String message) { // Show toast for a short time
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
}


}


웹서버 샘플 코드

var mobileKeyWords = new Array('iPhone', 'iPod', 'BlackBerry', 'Android', 'Windows CE', 'LG', 'MOT', 'SAMSUNG', 'SonyEricsson');

//모바일인지 체크

    for (var word in mobileKeyWords){

        if (navigator.userAgent.match(mobileKeyWords[word]) != null){

    // 모바일 작업a

            if(window.Android != null) 

                window.Android.toastLong( "JavscriptInterface Test" );

//안드로이드 webviewInterface 사용부분

            break;

        }   

    }


위에서 window.Andriod의 null 체크를 하는 이유는, 웹뷰를 사용한 하이브리드 앱과 모바일 브라우져에서 접속했을때를 구분하기 위해서이다. null 체크를 하지 않는다면 모바일 브라우져에서 페이지를 직접 열때 스크립트 오류가 발생할 것이다.






참고

- webView DOC

http://developer.android.com/reference/android/webkit/WebView.html


-webView Code

http://arabiannight.tistory.com/54

http://tjandroid.blogspot.kr/2013/02/webview.html

- addJavaInterface DOC

http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)


- Javascript interface(WebviewInterface) 사용

http://fimtrus.tistory.com/76


- 파일열기 intent

http://twigstechtips.blogspot.kr/2011/08/android-how-to-select-file.html


- 모바일 agent 구분하기

http://faildev.blogspot.kr/2012/10/javascript-mobile-agent.html





posted by cozyboy
: