onCreate에서 getIntent로 Activity가 실행되었을 때의 Intent를 가져와 extra에 있는 필드 유무에 따라 동작을 달리 하는 코드를 짰는데, Activity가 destory되도 Recents app에서 실행하면 기존 intent가 그대로 유지되는 상황이 발생.


이리저리 찾아보다가 아주 간단히 해결할 수 있는 방법이 있었다.


Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY


위 flag가 설정되었는지만 확인하면 간단히 해결.!

출처 : http://blog.projectnibble.org/2011/07/17/android-source-code-in-windows-the-easy-way/


전체 버전의 소스를 다 받는것 같음 -_-;; 각각의 버전별로 받으려면 shell script파일 수정 필요



Note: as Rahul comments, the script points to the old repository urls:

The script uses old links: open it using a text editor and replace all

git://android.git.kernel.org/ with

https://android.googlesource.com/

  1. Head over to msysGit and get the latest release (I got Git-1.7.6-preview20110708.exe). Install that thing with all the defaults.
  2. Execute Git Bash from the start menu folder added by the installation
  3. Much like a command prompt, you can change drives and add folders. Create a folder at the location where you want the android sources. For me this was:

    1. cd /d
    2. cd temp
    3. mkdir android_source
    4. cd android_source
  4. Now download the excellent autogit.sh shellscript created by Brad, that downloads all Android repos, to your new folder
  5. Finally, go back to the Git Bash window and execute ‘sh autogit.sh

It’ll take a while to get all of the almost 14 GB of sourcecode.

autogit.sh


출처 : http://cdkkcdkktoandroid.tistory.com/14


저도 아직 자세히는 파악을 하지 못했지만 WebView.java를 보니깐 WebView로 url를 로드 하면 로드 할때마다 쿠키를 사용하지 못하더군요. 아 사용 못하는게 아니고 대략 테스트를 해보니 로드된 페이지에서 쿠키를 저장하고 있는데 약 5분 정도가 지나야 WebView에서도 적용이 되더군요. 이상해서 WebView를 까보니 WebView로 로드 하게되면 로드 될때마다 쿠키를 초기화 하더군요. 

이를 해결하기 위해서는  CookieSyncManager를 사용해야 합니다.

액티비티를 호출하게 되면 그 생명주기에 맞게 Override한 메소드를 타게 되어있는데 그에 맞게 CookieSyncManager를 사용하면 WebView로 띄운 Url의 쿠키를 어플에 바로 적용이 되더군요

  @Override 

    public void onStart() { 

        super.onStart(); 

        CookieSyncManager.createInstance(this);

    }   

액티비티가 호출되면 onStart 메소드를 타는데 이때  인스턴스를 생성하고

@Override

    public void onResume(){

     super.onResume();

     CookieSyncManager.getInstance().startSync();

    }

액티비티가 상호작용이 이루지면 onResume 메소드를 거칩니다. 이때 생성한 인스턴스를 

startSync() 해줍니다.


그리고 액티비티가 종료될 수 도 있는 상태인 일시정지 상태(종료되는건 아님)에 stopSync() 해줍니다.

 @Override

    public void onPause(){

     super.onPause();

     CookieSyncManager.getInstance().stopSync();

    }

이렇게 해놓으면 액티비티 생명주기에 따라 쿠키를 동기화 시켜주게 됩니다.

그리고 하나더 중요한 부분이

 WebView를 띄울때 브라우저에서 제어권을 넘겨 받는 부분인 setWebViewClient의 페이지 로딩이 끝나면 타는 메소드인 onPageFinished 안에 쿠키를 분석해놔야 합니다.

webView.setWebViewClient(new MyWebClient{

        public boolean shouldOverrideUrlLoading(WebView view, String url){

     view.loadUrl(url);

     return true;

     }

   

     //WebView가 로딩이 끝나면 시작

     public void onPageFinished(WebView view, String url){

     CookieSyncManager.getInstance().sync();

     }

        });

참고로 말씀들이면 이 방법이 틀렸을 수도 있습니다. 한동안 WebView로 해당 URL의 쿠키를 사용할 수 있게 하기 위해서 별짓을 다 해봤는데 이 방법으로 하니 잘 되더군요.

그리고 구지 이 방법으로 하지 않아도 됩니다. 웹서버에서 쿠키를 저장하게 하지 않고 해당 URL이 로딩하게 되면 비지니스 로직에 맞게 해당 페이지에서 App을 호출해서 값을 넘겨서 App에서 강제로 쿠키매니저로 저장하시면 됩니다. 하지만 별로 권하고 싶지 않군요

이유는 웹에서 이미 쿠키를 저장하고 있는데(하이브리드 App 이니깐용) 구지 그걸 어플에서 다시 getCookie 해서 set을 하던지 해서 조작할 필요없다고 생각합니다. 뭐 물론 특별한 상용에서는 논외로 해야하지만용~ 아무튼 그냥 단순히 모바일 웹에서 잘 되던 쿠키가 WebView로 로딩하니깐 안된다면 위 방법을 한번 사용해 보시기 바랍니다.(거듭강조하지만 이 방법이 정확한건 아닙니다.)

그럼 참고해주시고 혹시 제가 파악한 위 사항이 잘못되었다면 저에게도 좀 알려주시기 바랍니다 ㅜ.ㅜ 그럼 잡스형에게 삿대질 할 그날까지 ~~

참고 : http://devian.tistory.com/159


PlayStore 에 등록시 보안이슈 발생 해결방안 보기


로컬 HTML(JavaScript)과 App 영역이 통신(함수호출)을 함으로써 간단한 하이브리드 앱을 만들어볼 수 있다.

1. HTML에서 App 함수 호출
   1) 멤버로 android.os.Handler 를 생성한다. 호출 시 thread 처리를 위해서 이용된다.
        private final Handler handler = new Handler();

   2) App과 Javascript간 Bridge 클래스를 생성하고, 호출될 함수를 implement 한다.
       (이 때 파리메터는 반드시 final로 선언)
       Javascript에서 호출시 별도의 Thread로 구동될 수 있도록 아래와 같이 구현한다.

          private class AndroidBridge {
            public void setMessage(final String arg) { // must be final
                handler.post(new Runnable() {
                    public void run() {
                        Log.d("HybridApp", "setMessage("+arg+")");
                        mTextView.setText(arg);
                    }
                });
            }
          }
   3) onCreate 함수에서 WebView에서 JavaScript를 Enable 하고, JavaScriptInterface로 Bridge 인스턴스를 등록한다.
        // 웹뷰에서 자바스크립트실행가능
        mWebView.getSettings().setJavaScriptEnabled(true);
        // Bridge 인스턴스 등록
        mWebView.addJavascriptInterface(new AndroidBridge(), "HybridApp");
 
    4) HTML 내에서 JavaScript에서 선언된 함수를 다음과 같이 호출 한다.
            window.<interfaceName>.<functionName>

  window.HybridApp.setMessage(msg);


2. App에서 HTML의 Javascript 함수 호출
   이부분은 간단하다....HTML에거 링크걸 때를 생각하면 되는데....
   그냥 버튼을 눌렀을 때 다음과 같이 호출하면 된다.
    mWebView.loadUrl("javascript:<함수명>('<arg>')");

    실제 구현은 다음과 같이 된다.
       mButton.setOnClickListener( new OnClickListener(){
        public void onClick(View view) {
            mWebView.loadUrl("javascript:setMessage('"+mEditText.getText()+"')");            
        }
       });

위의 방법으로 연결된 간단한 하이브리드 어플리케이션이다...




1. Android에서 Javascript함수 호출하기

 

webView.loadUrl("javascript:callJS('Hello from Android')");

 

다음과 같은 방식으로 javascript:methodname 과 같은 문자열을 넣어 WebView.loadUrl 메소드의 인자로 호출한다.



2. Javascript에서 Android 호출하기

 

/** Object exposed to JavaScript */
    private class AndroidBridge {
       public void callAndroid(final String arg) { // must be final
          handler.post(new Runnable() {
             public void run() {
                Log.d(TAG, "callAndroid(" + arg + ")");
                textView.setText(arg);
             }
          });
       }
    }

 

다음과 같이 브릿지 역활을 할 Class를 만든다.

WebView의 세팅을 바꾸고

           webView.getSettings().setJavaScriptEnabled(true);

WebView에 Javascript Interface를 추가해준다.

           webView.addJavascriptInterface(new AndroidBridge(),"android2");

HTML페이지에서 다음과 같은 방식으로 호출한다.

           window.android2.callAndroid('Hello from Browser')

android2는 addJavascriptInterface의 두번째 인자와 같다.



3. Javascript Listener 걸기

 

 webView.setWebChromeClient(new WebChromeClient() {
           @Override
           public boolean onJsAlert(final WebView view,
                 final String url, final String message,
                 JsResult result) {
              Log.d(TAG, "onJsAlert(!" + view + ", " + url + ", "
                    + message + ", " + result + ")");
              Toast.makeText(LocalBrowser.this, message, 3000).show();
              result.confirm!();
              return true; // I handled it
           }
        });

 

다음과 같이 WebView의 setWebChromeClient를 이용한다.

위 예제는 Javascript의 alert메소드 발생시 이벤트이다.



=============================================================================================================


'develop > android' 카테고리의 다른 글

Recents App List에서 실행됐는지 체크  (0) 2013.12.10
Windows에서 git로 안드로이드 소스 받기  (0) 2013.07.29
Webview cookie 설정  (2) 2012.11.26
공유하기 메뉴  (0) 2012.08.03
URL 받기  (0) 2012.08.03

intent filter를 통해 설정.

인터넷 브라우저에서 메뉴-페이지 공유 라던가.... 암튼 메뉴의 공유 라는 명령을 실행할 때 내 앱도 받을 수 있게 해주는 방법이다.

받고자 하는 Activity에 설정한다


<intent-filter>

<action android:name="android.intent.action.SEND" />

<category android:name="android.intent.category.DEFAULT" />


<data android:mimeType="image/*" />

<data android:mimeType="video/*" />

<data android:mimeType="audio/*" />

<data android:mimeType="text/*" />

<data android:mimeType="application/*" />

<data android:mimeType="plain/*" />

</intent-filter>

<intent-filter>

<action android:name="android.intent.action.SEND_MULTIPLE" />

<category android:name="android.intent.category.DEFAULT" />


<data android:mimeType="image/*" />

<data android:mimeType="video/*" />

<data android:mimeType="audio/*" />

<data android:mimeType="text/*" />

<data android:mimeType="application/*" />

<data android:mimeType="plain/*" />

</intent-filter>


android:mimeType이 실제로 내 어플에서 받을 데이터의 유형이다.

예를들어 브라우저에서 페이지 공유를 하면 웹URL을 text형태로 받을 수 있다.


===


반대로 내 앱에서 공유하기 메뉴를 만들어 다른 어플에 데이터를 전송하고자 하려면 startActivity를 사용한다.


Intent i = new Intent(Intent.ACTION_SEND);

i.setType("text/plain");

i.putExtra(android.content.Intent.EXTRA_TEXT, "Share Data");

startActivity(Intent.createChooser(i,"Share using"));


Intent:setType에 설정되는 값에 따라서 받을 수 있는 앱의 목록이 달라진다.

text/plain은 SNS앱에 공유하기가 가능한 타입이다.

intent filter를 설정하여 받을 수 있다.

받고자 하는 Activity에 설정.


<intent-filter>

<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />

<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="myapp"/>

</intent-filter>

<intent-filter>

<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />

<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="http" android:host="www.daum.net" android:pathPrefix="/"/>

</intent-filter>



custom scheme 설정과 http scheme에 대한 intent filter이다.


URL을 받기 위한 intent filter를 설정할 때에는 android.intent.category.BROWSABLE을 필히 설정해야한다.
또 한, 하나의 intent filter에는 1개의 scheme에 대한 정보만 들어가야 된다. (처음에 하나에 두가지를 같이 넣었었는데 이상 동작을 함. 심심하면 테스트 하면서 차이를 아는것도 좋은 방법일듯)


http scheme에 대한 설정을 할 경우 android:pathPrefix를 필히 설정해야 거의 모든 android폰에서 동작한다. android:host는 특정 host에 대한것만 처리하기 위해 넣을때만 필요하다.


http scheme은 삼성폰의 icecream 이상 버전에서는 동작하지 않는다. (현재로선 절대 안되니 굳이 동작하게 하려고 고민할 필요도 없다)

+ Recent posts