2012-05-26 3 views
5

그래, 약간의 배경 지식이 필요합니다. 먼저 PhoneGap 1.7에서 jquery-mobile을 사용하고 있습니다. ServerSocket 객체를 사용하는 매우 간단한 Java 서버를 코딩했습니다. 안드로이드 전화에서 서버에 연결하면 서버가 소켓을 통해 데이터를 보냅니다. 이 부분이 효과적입니다.Android PhoneGap 1.7 자바 스크립트 함수 호출

내가 붙어있는 부분은 데이터 수신시 jquery 모바일 UI를 업데이트해야하는 소켓을 통해 데이터를 보내려고한다는 것입니다.


답변 : 사이먼은 대규모 도움이었고, 나는 그의 도움과 this tutorial

정말 나를 폰갭 플러그인 자체 양산 스레드를 가지고 있었다 명중 부분을 다음과 같이 그것을 알아 냈다. 일단 내가 깨달으면, 모든 것이 제자리에 떨어졌습니다. 그러나 여기에 관심있는 사람은 코드입니다. 명심해라, 나는 튜토리얼에서 많은 것을 얻었다. 또한이 개념을 테스트하기 위해 만든 매우 간단한 Java 서버도 포함 시켰습니다. 나는 아마도 이것이 미래에 누군가를 도울 것이라고 생각했습니다. 이것은 기본적으로 개념을 증명하는 것임을 기억하십시오.

가 내 실제 필요에 따라이 플러그인을 개편해야합니다

안드로이드 활동 : 수입 org.apache.cordova.DroidGap;

import android.os.Bundle; 

public class ISSAndroidActivity extends DroidGap { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     super.loadUrl("file:///android_asset/www/index.html"); 
    } 
} 

폰갭 플러그인 :

import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.InetSocketAddress; 
import java.net.Socket; 
import java.net.SocketAddress; 
import java.net.SocketException; 

import org.apache.cordova.api.*; 
import org.apache.cordova.api.PluginResult; 
import org.apache.cordova.api.PluginResult.Status; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import android.util.Log; 

public class InvokeJavaScriptPlugin extends Plugin { 
    public static String PLUGIN_TAG = "InvokeJavaScriptPlugin"; 
    public static String PROCESS_DATA_ACTION = "processData"; 
    private String callBackId = ""; 

    @Override 
    public PluginResult execute(String action, JSONArray args, String callbackId) { 
     PluginResult pluginResult = null; 
     Log.d(PLUGIN_TAG, "Invoking Javascript w\\ NO_RESULT"); 

     if (action.equals(PROCESS_DATA_ACTION)) { 
      this.callBackId = callbackId; 
      startProcessingData(); 
      pluginResult = new PluginResult(Status.NO_RESULT); 
      pluginResult.setKeepCallback(true); 
     } else { 
      pluginResult = new PluginResult(Status.INVALID_ACTION); 
      Log.e(PLUGIN_TAG, "Invalid action : " + action); 
     } 
     return pluginResult; 
    } 

    /** 
    * Spawns a thread that connects to a server, and receives data from it 
    */ 
    private void startProcessingData() { 
     new Thread() { 
      @Override 
      public void run() { 

       // Socket Testing 
       ObjectOutputStream out; 
       ObjectInputStream in; 
       Socket requestSocket = new Socket(); 
       Object inboundObject; 

       SocketAddress ipAddr = new InetSocketAddress("192.168.1.2", 
         2012); 
       try { 
        requestSocket.connect(ipAddr); 

        out = new ObjectOutputStream(
          requestSocket.getOutputStream()); 
        out.flush(); 
        in = new ObjectInputStream(requestSocket.getInputStream()); 

        do { 
         inboundObject = in.readObject(); // Data is received 
                 // here 
         int processedData = ((Number) inboundObject).intValue(); 
         onProcessDataReadSuccess(processedData); 

        } while (requestSocket.isConnected()); 

       } catch (SocketException ex) { 
        Log.d(PLUGIN_TAG, "Connection to Server lost"); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
      } 
     }.start(); 
    } 

    /** 
    * Callback method for startProcessingData(). Sends the result up to 
    * javascript layer via Plugin.success()<br> 
    * This method is automatically called asynchronously when processing is 
    * finished. 
    * 
    * @param processedData 
    *   the result of data processing which will be passed back to 
    *   javascript. 
    */ 
    private void onProcessDataReadSuccess(int processedData) { 
     Log.d(PLUGIN_TAG, "Processing data: " + processedData); 
     PluginResult result; 
     try { 
      JSONObject resultJSON = new JSONObject(); 
      resultJSON.put("processedData", processedData); 
      result = new PluginResult(Status.OK, resultJSON); 
     } catch (JSONException jsonEx) { 
      Log.e(PLUGIN_TAG, "Got JSON Exception " + jsonEx.getMessage()); 
      jsonEx.printStackTrace(); 
      result = new PluginResult(Status.JSON_EXCEPTION); 
     } 

     result.setKeepCallback(true); 
     this.success(result, this.callBackId); 
    } 
} 

index.html을 :

<!DOCTYPE html> 
<html> 
<head> 
<title></title> 
<meta name="viewport" content="width=device-width, initial-scale=1" /> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>Insert title here</title> 
<link type="text/css" href="css/jquery.mobile-1.1.0.min.css" 
    rel="stylesheet" /> 
</head> 
<script type="text/javascript" charset="utf-8" 
    src="scripts/cordova-1.7.0.js"></script> 
<script type="text/javascript" src="scripts/jquery-1.7.2.min.js"></script> 
<script type="text/javascript" src="scripts/jquery.mobile-1.1.0.min.js"></script> 
<script type="text/javascript" src="scripts/InvokeJavaScript.js"></script> 
<script type="text/javascript" charset="utf-8"> 
    document.addEventListener('deviceready', function() { 
     window.plugins.InvokeJavaScript.processData(function(result) { 
      displayProcessedData(result) 
     }, function(error) { 
      console.log(error) 
     }); 
    }, true); 

    function displayProcessedData(result) { 
     document.getElementById("processedData").innerHTML = result.processedData; 
    } 
</script> 

<body> 
    <div data-role="page"> 
     <div data-role="header" data-position="fixed"> 
      <h1>Demo</h1> 
     </div> 
     <div data-role="content"> 
      Result: 
      <div id="processedData"></div> 
     </div> 
     <div data-role="footer" data-position="fixed"> 
      <div data-role="navbar"></div> 
     </div> 
    </div> 
</body> 
</html> 

Server.java

import java.io.BufferedReader; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class ISSServer { 

    private static Socket androidSocket; 
    private static ServerSocket serverSocket; 
    static ObjectOutputStream out; 
    static BufferedReader in; 

    public static void main(String[] args) { 
     System.out.println("Listen Thread: Waiting for connection"); 
     int port_number = 2012; // The default port 

     try { 
      serverSocket = new ServerSocket(port_number); 
      androidSocket = serverSocket.accept(); 

      System.out.println("Connection established"); 

      out = new ObjectOutputStream(androidSocket.getOutputStream()); 
      out.flush(); 
      // in = new BufferedReader(new 
      // InputStreamReader(androidSocket.getInputStream())); 

      out.writeObject(1337); 
      out.flush(); 
      out.reset(); 
      System.out.println("1337 sent"); 
      Thread.sleep(2000); 

      out.writeObject(9999); 
      out.flush(); 
      out.reset(); 
      System.out.println("9999 sent"); 
      Thread.sleep(2000); 

      out.writeObject(1234); 
      out.flush(); 
      out.reset(); 
      System.out.println("1234 sent"); 
      Thread.sleep(2000); 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 
+0

이것 좀보세요. http://stackoverflow.com/questions/7947559/calling-javascript-from-eclipse-for-phonegap –

답변

7

당신은 자신에 하드에이 방법을 만들고있다. PhoneGap 플러그인을 사용하면 초기 JavaScript 호출의 콜백 ID를 저장 한 다음 result.setKeepCallback (true)을 호출하고 PluginResult.Status.NO_RESULT 상태를 반환하는 PluginResult를 다시 보낼 수 있습니다.

자바 측에서 가져 와서 업데이트 할 때마다 새로운 PluginResult가 생성됩니다. 상태를 OK로 설정하고 데이터를 보내려는 모든 데이터를 반환하고 setKeepCallback (true)을 반환합니다. 그런 다음 this.success (callbackId, result)를 호출하면 JS 측에서 지속적인 업데이트를 받게됩니다.

+0

재미있을 것 같습니다. 나는 그것에 시간을 할애 할 것이다. 장치 준비 이벤트 리스너에 초기 함수 호출을 배치하면 소켓 연결이 설정되기 전에 장치가 준비되었는지 확인하는 문제가 해결됩니다. 하지만 NO_RESULT에 대해 궁금합니다. 이니셜은 아무 결과도 없을 것이고, 나는 그것이 합리적이라고 생각합니다. 그러나 나중에 실제로 행동을 연기 할 때 나는 Status.OK를 사용할 것입니다. 그 기능을 더 이상 사용하지 않으시겠습니까? 아니면 callbackid의 전체 요점은 무엇입니까? 이것은 다른 JS 작업이 수행하는 것을 막지 않을 것입니까? – Rakshasas

+0

아니요, 다른 JS 작업의 수행을 막지는 못합니다. 요청은 비동기 적이므로 JS의 UI 스레드를 차단하지 않습니다. 또한, PluginResult를 반환하기 전에 KeepCallback (true)을 설정하면 JavaScript 측에서 콜백을 지우지 않습니다. 나를 신뢰하십시오, 이것은 Accelerometer와 Network Status가 PhoneGap 안드로이드 핵심 코드에서 작동하는 방법입니다. –

+0

감사합니다.내가 처음에는 이해하지만 당신이 위의, 다른 [stackoverflow에 대한 게시물] (http://stackoverflow.com/a/7849762/865868) 당신과이 [튜토리얼] (http : // www .speakingcode.com/2012/05/29/call-native-android-java-code-from-html5javascript-using-phonegap-plugins-and-implement-async-callbacks /) 나는 그것을 알아 냈다. 정말 고맙습니다! – Rakshasas

관련 문제