마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

하이브리드 앱에서 안드로이드 공유기능을 호출하려면

0 추천

 

안녕하세요.

폰갭을 기반으로한 하이브리드 앱을 만들어 마켓에 올렸는데요.

이 앱을 홍보하는 메시지를 앱안에서 트위터나 카톡 등으로 보내기 위해

안드로이드 공유 기능을 활용하고자  합니다.

 

인터넷 뒤지니까 아래처럼 구현하라고 하는데 

어느 파일에다 어떻게 적어넣으라는 이야기인지 도저히 감을 못잡겠습니다.

java는 전혀 모르는 상태이지만 눈치껏 붙여넣을 수는 있습니다.

 

Intent shareIntent = new Intent (android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "제목");
shareIntent.putExtra(Intent.EXTRA_TEXT, "내용");
startActivity(Intent.createChooser(shareIntent, "팝업창 제목"));

 

자세히 알으켜 주시는 분은 새해에 모든 일이 잘 풀릴겁니다 ^^

 

 

we3355 (210 포인트) 님이 2013년 12월 26일 질문

4개의 답변

0 추천
 
채택된 답변

답변이 조금 늦었네요.. ^^
해결은 좀 보셨는지 모르겠습니다.

우선
   // 위 두 줄은 Droidgap의 type에서 정의된 것이 아니다.
이 부분은, 제가 잘못 알려 드렸네요..
다음과 같이 해보시기 바랍니다.

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

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


  WebSettings webSettings = super.appView.getSettings();
  webSettings.setJavaScriptEnabled(true);

  super.appView.addJavascriptInterface(new CustomJavascriptInterface(), "aaaaa");
 }

그리고, Java에서 사용되는 대부분의 클래스는 import 라는것을 해 주어야 합니다. (java.lang.* 패키지 제외)
    // new Handler 부터 여기까지는 하나의 type으로 resolved 될 수 없다.
이 부분은, 해당 클래스 (Handler, Intent 등) 이 import 되지 않아서 그렇습니다.
코드만 봐서는 다음과 같은 것들이 import 되어야 할것으로 보입니다.
 

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.webkit.WebSettings;

다음은 제가 구성해 본 전체 소스 입니다.

package org.apache.cordova;


import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.webkit.WebSettings;


public class DroidGap extends CordovaActivity {
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);


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


  WebSettings webSettings = super.appView.getSettings();
  webSettings.setJavaScriptEnabled(true);

  super.appView.addJavascriptInterface(new CustomJavascriptInterface(), "aaaaa");
 }


 private class CustomJavascriptInterface {
  public void doShare() {
   new Handler().post(new Runnable() {
    public void run() {
     Intent shareIntent = new Intent (android.content.Intent.ACTION_SEND);
     shareIntent.setType("text/plain");
     shareIntent.putExtra(Intent.EXTRA_SUBJECT, "제목");
     shareIntent.putExtra(Intent.EXTRA_TEXT, "내용");
     startActivity(Intent.createChooser(shareIntent, "팝업창 제목"));
    }
   });
  }
 }

}

html 소스는 다음과 같습니다.

<html>
  <head>
    <title></title>
    <script src="cordova.js"></script>
    <script type="text/javascript">
     function callApp() {
      window.aaaaa.doShare();
     }
 </script>
  </head>
  <body>
 <a href="javascript:callApp();">Click</a>
  </body>
</html>

그리고... 에러메시지는 한글로 번역해 주시면 더 어려워요 ^^
그냥
// Handler cannot be resolved to a type
라고 적어 주시는게 알아보기 쉽습니다.

수고하세요~

밍이~ (5,780 포인트) 님이 2013년 12월 31일 답변
we3355님이 2013년 12월 31일 채택됨
와우, 밍이~님 정말 감사합니다.
먼저 새해 복 많이 받으세요^^

올려주신 대로 했더니 세 군데에서 오류 메시지가 나오는데
이클립스에서 고치라는대로 하고 테스트하니까 작동이 되네요^^

하나는 10번줄의 DroidGap 을  MainActivity로 바꿨고
두번째는 27번줄 위에   @SuppressWarnings("unused") 가 삽입되었고
세번째는 import android.annotation.SuppressLint; 와
@SuppressLint("SetJavaScriptEnabled") 가 추가되었습니다.

다시 한 번 진심으로 감사드립니다.
새해에 하시는 일이 다 잘 될거에요^^

참고로 제가 만드는 어플 가운데 하나입니다.
http://goo.gl/UvV1D
고생하셨습니다. ^^
aaaaa 는 적당히 바꿔서 사용하시면 될것 같고,
public class DroidGap extends CordovaActivity 부분은
public class MainActivity extends DroidGap 라고 하시는게 나을것 같네요.
(물론 DroidGap import 가 필요할겁니다.)

Lint 에러 때문에 두번째,세번째 부분 추가하신부분은 별 문제 없어 보이네요.

WebSettings webSettings = super.appView.getSettings();
webSettings.setJavaScriptEnabled(true);
요고는요..
super.appView.getSettings().setJavaScriptEnabled(true);
요롷게 한줄로 하셔도 아마 될겁니다.
저렇게 하면 WebSettings 을 명시적으로 사용한게 아니어서
WebSettings import 도 필요없습니다.

새해 복 많이 받으세요~
감사합니다.
말씀하신대로 고쳐 봤는데 잘 되네요.
사실상 코드를 전부 짜주시다시피 했는데
어떻게 감사드려야 할 지 모르겠습니다.
내내 행복하시길 바랍니다^^
0 추천
공유버튼을 Tap 했을 때 적어주신 코드를 수행하도록 구성하시면 됩니다.

 

만약 공유버튼이 html 에 구성되어 webview 로 보여주고 있다면,

JavascriptInterface 구성하셔서 Javascript 로 통신하면 됩니다.

html 에서 Javascript 로 Native App 에 정의된 메소드를 Call 하고,

Native App 에서 정의된 메소드에서는 위의 공유 코드를 수행하면 됩니다.
밍이~ (5,780 포인트) 님이 2013년 12월 26일 답변
밍이~님 답변 감사드립니다^^

이제 뭔가 원리는 좀 알 것 같지만 java 자체를 모르기 때문에
어떤 java파일에 어떻게 메소드를 적어넣고,
또 javascript로는 어떻게 호출해야 되는지
조금만 더 인심을 써주시면 안될까요^^
밍이님, 잘 지내셨는지요.

위에 알려주신대로 해서 잘 사용하고 있었는데
오늘 안드로이드 4.2 단말기(삼성제품) 에서는 작동이 안되는 걸 알고 염치없지만 다시 문의드립니다.

혹시 바쁘시면 답주지 않아도 괜찮습니다.
좋은 날 되세요.
아이코... 질문을 좀 늦게 봤네요 ^^

질문만으로는 정확한 내용을 판단하기 어려운데,
혹시 작동 안될때의 Log 를 올려주실수 있으실까요?

4.2 는 그렇게 많이 활성화 된 버전이 아니어서
제가 테스트 하기가 좀 어렵네요 .. ㅜ.ㅡ
hsa no method 'doshare'
대강 이런 메시지가 나오네요.

갤럭시3 나 최근 폰들은 다 4.2 나 4.3으로  업그레이드 되어 나오는 듯 싶습니다.

4.1 이하에서는 잘 작동되는 걸로 봐서
문법적으로 하자가 있는 거 같진 않습니다만..
doShare 메소드 정의 바로 위에
@JavascriptInterface
라고 해보세요. 4.2 부터 해당 어노테이션 지정이 필수로 된것 같네요.

어노테이션도 클래스 이므로 import 가 필요합니다.

예)
import android.webkit.JavascriptInterface;
... (중략) ...
 private class CustomJavascriptInterface {
  @JavascriptInterface
  public void doShare() {
... (후략) ...
아, 감사합니다.
이 부분은 다시 질문을 올려 어느 분의 힌트로 간신히 해결을 봤습니다.

그런데 새로운 고민은
asset 아래에 있는 jpg나 png 파일을 카카오스토리로  보내려고
     shareIntent.setType("image/png");
    shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///android_asset/www/img/tokki.png"));

이렇게 추가했더니 경로가 잘못되었다고 나오네요.
글은 전달되는데 그림은 다른 방법을 써야 하는가 봅니다.
공유기능을 통해서 asset 에 있는 파일을 전달할 방법이 있을까요?
아, 여기에 대한 답은 주지 않으셔도 됩니다.

하여간 끝까지 책임져 주셔서 정말 감사합니다.
좋은 날 되세요^^
0 추천

질문과 댓글을 보니 Android 개발자 분이 아니신것 같은데요 ^^

Android 개발자께서 확인해 주셔야 하는 내용입니다.

 

폰갭 플랫폼을 사용하셔서 Android 개발이 거의 없이 진행되신것 같습니다.

어쨌든 Android 소스에서

webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new CustomJavascriptInterface(), "aaaaa");

식으로 webview에다가 Javascript Interface 를 붙여야 하고,

다음과 같은 Javascript Interface 를 정의하여서 구성하셔야 합니다.

 private class CustomJavascriptInterface {
  public void doShare() {
   new Handler().post(new Runnable() {
    public void run() {
     // TODO: 공유코드
    }
   });
  } 
 }

WebView 셋팅이 완료 되었다면,

html 에서는 javascript 로

window.aaaaa.doShare();

이런식으로 호출해 주시면 됩니다만...

 

이해가 되실지 모르겠습니다. ㅜㅜ

밍이~ (5,780 포인트) 님이 2013년 12월 26일 답변
와우~ 정성스런 답변 정말 감사합니다^^

MainActivity.java 파일에 보니까  폰갭부분이 아래처럼 있는데
이 안에다 위에 webview 관련 코드들을 다 적어주면 되나요?

public class MainActivity extends DroidGap {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.loadUrl("file:///android_asset/www/index.html");
    }

// 여기다?
}
혼자 개발하는데다 나이도 많아서 주변에 물어볼 사람이 없습니다.
감사한 마음에 답변을 채택을 했지만 위에 소스코드를 어떻게 붙여야 할지 난감하군요.
0 추천

다음과 같이 구성해 보시겠어요?

실제 컴파일 해보지 못해서 잘 돌아갈지 모르겠습니다만,  (아... 이 무책임한 답변이네요... -_-;;)

대충 흐름을 이해 하시면 될것 같습니다.

public class MainActivity extends DroidGap {

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  super.getSettings().setJavaScriptEnabled(true);
  super.addJavascriptInterface(new CustomJavascriptInterface(), "aaaaa");
  
  super.loadUrl("file:///android_asset/www/index.html");
 }

 private class CustomJavascriptInterface {
  public void doShare() {
   new Handler().post(new Runnable() {
    public void run() {
     // TODO: 공유코드
    }
   });
  }
 }
}

기본 Android Native 개발을 조금 공부해 보시는건 어떠실지

조심스레 건의드려 봅니다.

Android 개발을 공부하신다면 기본적인 Java 지식도 필요할것 입니다.

제3자가 공부해라 이래라 저래라 하기 조금 죄송스럽습니다만,

기본적인 html 지식은 있으신것 같고,

앞으로 계속 App (혹은 웹앱, 하이브리드앱)을 개발하실 계획이시라면

Android 기본적인 개발공부를 해 보시는게 도움이 되실것 같아

조금은 건방지지만 의견드려 봅니다.

기본적인 개발공부를 하신 후 폰갭 같은 플랫폼을 활용하시면

훨씬 더 퀄리티 있는 결과물을 만들어 내실수 있으실것 같습니다.

금요일이네요... 한주 마무리 잘 하시고, 주말 잘 보내시기 바랍니다.

밍이~ (5,780 포인트) 님이 2013년 12월 27일 답변
아, 추가적인 답변까지 다시 한 번 진심으로 감사드립니다.

java 는 배워보고 싶은 마음이 있지만 사실 제 입장이 조금 애매한 상태랍니다.
전문개발자라기 보다는 컨텐츠 쪽에 비중이 더 가 있습니다.
그렇다고 전문적으로 하기에는 아직 수익이 많지 않아서 개발자를 쓸 형편도 되지 않습니다.
다만 내 뜻대로 전달하기 위해서 직접 개발까지 손대고 있는 형편입니다.
아무래도 책을 좀 보긴 해야 할 것 같습니다^^
이 부분 조언 감사드립니다.

............

올려주신 코드대로 해봤지만 또 오류가 뜨네요.
아마 뭐가 정의되지 않았다고 하는 것 같습니다.

혹시 귀찮더라도 전체 코드를 올리니 한 번만 더 봐주실 수 없는지요.

package com.My.Happy.App.Life;

import android.os.Bundle;
//import android.view.KeyEvent;
// import android.widget.Toast;
//import android.app.AlertDialog;
//import  content.DialogInterface;
//import android.app.Activity;
// import android.view.Menu;
import org.apache.cordova.*;

public class MainActivity extends DroidGap {
     
     @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
       
      super.getSettings().setJavaScriptEnabled(true);
      super.addJavascriptInterface(new CustomJavascriptInterface(), "aaaaa");
   
//위 두 줄은 Droidgap의 type에서 정의된 것이 아니다.
   
      super.loadUrl("file:///android_asset/www/index.html");
     }
     
     private class CustomJavascriptInterface {
      public void doShare() {
       new Handler().post(new Runnable() {
        public void run() {
            Intent shareIntent = new Intent (android.content.Intent.ACTION_SEND);
            shareIntent.setType("text/plain");
            shareIntent.putExtra(Intent.EXTRA_SUBJECT, "제목");
            shareIntent.putExtra(Intent.EXTRA_TEXT, "내용");
            startActivity(Intent.createChooser(shareIntent, "팝업창 제목"));

// new Handler 부터 여기까지는 하나의 type으로 resolved 될 수 없다.
이런 에러 메시지가 각각 뜨네요.
        }
       });
      }
     }
    }
DroidGap 클래스가 webview를 상속한것인지 webview를 composition으로 구성한건지 wrapping 되어있어서 알수가 없지만 오류로 보면 상속이 아니라 composition으로 된거 같고 DroidGap 클래스를 수정해야 할거 같네요.
관심에 감사드립니다 ^^
...