2013-01-13 9 views
23

Próbuję użyć NanoHTTP do wyświetlenia pliku HTML. Jednak NanoHTTP jest stosunkowo nieudokumentowany i jestem nowy na Androida. Moje pytanie brzmi: gdzie mam przechowywać plik html i jak konkretnie mogę obsłużyć go przy użyciu NanoHTTP.Używanie NanoHTTPD w Androidzie

+1

O ile nie jest to jakiś istniejący port NanoHTTPD Android, masz trochę pracy przed tobą, a nie coś, co polecam dla kogoś „nowego na Androida ". Jeśli to * jest * jakimś istniejącym portem Android NanoHTTPD, autorzy tego portu mieli nadzieję, że dostarczysz trochę sposobów na określenie głównego katalogu dokumentu poprzez "Plik". – CommonsWare

+2

Cóż, jestem nowy na Androida, ale nie jestem nowy w Javie ani w sieci. Wszystko, czego potrzebuję, to trochę popchnąć we właściwym kierunku. – Zwade

Odpowiedz

33

Późna odpowiedź, ale może być przydatna dla innych.

Oto prosty hello Web Server, niezupełnie o to pytasz, ale możesz kontynuować tutaj. Poniższy program zakłada, że ​​masz katalog www w katalogu głównym karty SD i plik index.html w środku.

Główna działalność Httpd.java:

package com.inforscience.web; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Environment; 
import android.util.Log; 
import java.io.*; 
import java.util.*; 


public class Httpd extends Activity 
{ 
    private WebServer server; 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     server = new WebServer(); 
     try { 
      server.start(); 
     } catch(IOException ioe) { 
      Log.w("Httpd", "The server could not start."); 
     } 
     Log.w("Httpd", "Web server initialized."); 
    } 


    // DON'T FORGET to stop the server 
    @Override 
    public void onDestroy() 
    { 
     super.onDestroy(); 
     if (server != null) 
      server.stop(); 
    } 

    private class WebServer extends NanoHTTPD { 

     public WebServer() 
     { 
      super(8080); 
     } 

     @Override 
     public Response serve(String uri, Method method, 
           Map<String, String> header, 
           Map<String, String> parameters, 
           Map<String, String> files) { 
      String answer = ""; 
      try { 
       // Open file from SD Card 
       File root = Environment.getExternalStorageDirectory(); 
       FileReader index = new FileReader(root.getAbsolutePath() + 
         "/www/index.html"); 
       BufferedReader reader = new BufferedReader(index); 
       String line = ""; 
       while ((line = reader.readLine()) != null) { 
        answer += line; 
       } 
       reader.close(); 

      } catch(IOException ioe) { 
       Log.w("Httpd", ioe.toString()); 
      } 


      return new NanoHTTPD.Response(answer); 
     } 
    } 

} 

Oczywiście klasa NanoHTTPD musi być w tym samym opakowaniu.

Musisz zezwolić na dostęp do Internetu pod numerem AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET" /> 

i odczytać uprawnienia do zewnętrznego magazynu.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

EDIT: dostęp do serwera otworzę przeglądarkę internetową z adresem IP urządzenia, na przykład 192.168.1.20:8080.

UWAGI:

+1

Dzięki za napisanie tego, powinienem był dodać swój własny kod, gdy go wymyśliłem (co trwało chwilę). – Zwade

+2

Dodaję moje podziękowania. Poważnie, bardzo pomocny. Jest to pierwszy przykład nanohttpd, jaki odkryłem, że faktycznie działa z bieżącym nanohttpd. Mój proces: Utwórz nowy projekt aplikacji dla systemu Android, wklej do głównej aktywności (zmieniając nazwę pakietu i nazwę działania, aby pasował do mojego projektu), kopiuj w pliku NanoHTTPD.java (z nanohttpd-master/core/src/main/java/fi/iki/elonen/w bieżącym pobraniu https://github.com/NanoHttpd/nanohttpd), dodaj uprawnienie INTERNET, utwórz plik www/index.html i to było to. Bum. Uruchomiłem aplikację na mojej Notatniku II i przeglądałem stronę z mojego komputera. Prace! –

+1

Nie ma za co. Użyłem serwera do projektu uczelnianego (https://bitbucket.org/rendon/smsserver), a NanoHTTPD tak dobrze wykonało pracę. – rendon

8

Całkiem dobry kod źródłowy można znaleźć tutaj: https://github.com/Teaonly/android-eye

folderu aktywa Chceck gdzie są przechowywane HTML i JavaScript pliki https://github.com/Teaonly/android-eye/tree/master/assets

TeaServer - wdrożenie serwera https://github.com/Teaonly/android-eye/blob/master/src/teaonly/droideye/TeaServer.java

główną działalność - inicjalizacji serwer https://github.com/Teaonly/android-eye/blob/master/src/teaonly/droideye/MainActivity.java

+0

To nie działa na Androidzie 3 i nowszych wersjach, ponieważ nie możesz tworzyć sieci z poziomu interfejsu użytkownika – Paulus

+0

Działa to w systemie Android 3+ i wyświetla obrazki/skrypty/etc. Szukałem czegoś, co działało przez kilka dni. Ich implementacja obsługuje typy MIME bez konieczności ręcznego określania. Bardzo dziękuję za te informacje :) – suomi35

4

Updated WebServer klasy (patrz Rendon na odpowiedź), który współpracuje z aktualnej wersji NanoHTTPD:

private class WebServer extends NanoHTTPD { 

    public WebServer() { 
     super(8080); 
    } 

    @Override 
    public Response serve(IHTTPSession session) { 
     String answer = ""; 
     try { 
      // Open file from SD Card 
      File root = Environment.getExternalStorageDirectory(); 
      FileReader index = new FileReader(root.getAbsolutePath() + 
        "/www/index.html"); 
      BufferedReader reader = new BufferedReader(index); 
      String line = ""; 
      while ((line = reader.readLine()) != null) { 
       answer += line; 
      } 
      reader.close(); 

     } catch(IOException ioe) { 
      Log.w("Httpd", ioe.toString()); 
     } 

     return newFixedLengthResponse(answer); 
    } 

} 
+0

Niestety nie działa dla mnie .... – GvSharma

1

spróbować tego ... Tworzenie 2 opakowania (aktywność, util), wyłącznie dla organizacji Aktywność tworzyć MainActivity.java klasa w util utworzyć klasę AndroidWebServer.java

package awserverfatepi.com.activity; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.net.wifi.WifiManager; 
import android.support.design.widget.CoordinatorLayout; 
import android.support.design.widget.FloatingActionButton; 
import android.support.design.widget.Snackbar; 
import android.support.v4.content.ContextCompat; 
import android.support.v7.app.AlertDialog; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.KeyEvent; 
import android.view.View; 
import android.widget.EditText; 
import android.widget.TextView; 

import awserverfatepi.com.R; 
import awserverfatepi.com.util.AndroidWebServer; 

public class MainActivity extends AppCompatActivity { 

    private static final int DEFAULT_PORT = 8080; 

    private AndroidWebServer androidWebServer; 
    private BroadcastReceiver broadcastReceiverNetworkState; 
    private static boolean isStarted = false; 

    private CoordinatorLayout coordinatorLayout; 
    private EditText editTextPort; 
    private FloatingActionButton floatingActionButtonOnOff; 
    private View textViewMessage; 
    private TextView textViewIpAccess; 

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

     initGui(); 
     setIpAccess(); 
     floatingActionButtonOnOff = (FloatingActionButton) findViewById(R.id.floatingActionButtonOnOff); 
     floatingActionButtonOnOff.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (isConnectedInWifi()) { 
        if (!isStarted && startAndroidWebServer()) { 
         isStarted = true; 
         textViewMessage.setVisibility(View.VISIBLE); 
         floatingActionButtonOnOff.setBackgroundTintList(ContextCompat.getColorStateList(MainActivity.this, 
           R.color.colorGreen)); 
         editTextPort.setEnabled(false); 
        } else if (stopAndroidWebServer()) { 
         isStarted = false; 
         textViewMessage.setVisibility(View.INVISIBLE); 
         floatingActionButtonOnOff.setBackgroundTintList(ContextCompat.getColorStateList(MainActivity.this, 
           R.color.colorRed)); 
         editTextPort.setEnabled(true); 
        } 
       } else { 
        Snackbar.make(coordinatorLayout, getString(R.string.wifi_message), Snackbar.LENGTH_LONG).show(); 
       } 
      } 
     }); 

     initBroadcastReceiverNetworkStateChanged(); 
    } 

    private void initGui() { 
     coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout); 
     editTextPort = (EditText) findViewById(R.id.editTextPort); 
     textViewMessage = findViewById(R.id.textViewMessage); 
     textViewIpAccess = (TextView) findViewById(R.id.textViewIpAccess); 
    } 

    private boolean startAndroidWebServer() { 
     if (!isStarted) { 
      int port = getPortFromEditText(); 
      try { 
       if (port == 0) { 
        throw new Exception(); 
       } 
       androidWebServer = new AndroidWebServer(port); 
       androidWebServer.start(); 
       return true; 
      } catch (Exception e) { 
       e.printStackTrace(); 
       Snackbar.make(coordinatorLayout, "A porta " + port + " não está funcionando, por favor altere para outra no intervalo" + 
         " entre 1000 e 9999.", Snackbar.LENGTH_LONG).show(); 
      } 
     } 
     return false; 
    } 

    private boolean stopAndroidWebServer() { 
     if (isStarted && androidWebServer != null) { 
      androidWebServer.stop(); 
      return true; 
     } 
     return false; 
    } 

    private void setIpAccess() { 
     textViewIpAccess.setText(getIpAccess()); 
    } 

    private void initBroadcastReceiverNetworkStateChanged() { 
     final IntentFilter filters = new IntentFilter(); 
     filters.addAction("android.net.wifi.WIFI_STATE_CHANGED"); 
     filters.addAction("android.net.wifi.STATE_CHANGE"); 
     broadcastReceiverNetworkState = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context context, Intent intent) { 
       setIpAccess(); 
      } 
     }; 
     super.registerReceiver(broadcastReceiverNetworkState, filters); 
    } 

    private String getIpAccess() { 
     WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); 
     int ipAddress = wifiManager.getConnectionInfo().getIpAddress(); 
     final String formatedIpAddress = String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), 
       (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); 
     return "http://" + formatedIpAddress + ":"; 
    } 

    private int getPortFromEditText() { 
     String valueEditText = editTextPort.getText().toString(); 
     return (valueEditText.length() > 0) ? Integer.parseInt(valueEditText) : DEFAULT_PORT; 
    } 

    public boolean isConnectedInWifi() { 
     WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); 
     NetworkInfo networkInfo = ((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo(); 
     if (networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected() 
       && wifiManager.isWifiEnabled() && networkInfo.getTypeName().equals("WIFI")) { 
      return true; 
     } 
     return false; 
    } 

    public boolean onKeyDown(int keyCode, KeyEvent evt) { 
     if (keyCode == KeyEvent.KEYCODE_BACK) { 
      if (isStarted) { 
       new AlertDialog.Builder(this) 
         .setTitle(R.string.warning) 
         .setMessage(R.string.dialog_exit_message) 
         .setPositiveButton(getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           finish(); 
          } 
         }) 
         .setNegativeButton(getResources().getString(android.R.string.cancel), null) 
         .show(); 
      } else { 
       finish(); 
      } 
      return true; 
     } 
     return false; 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     stopAndroidWebServer(); 
     isStarted = false; 
     if (broadcastReceiverNetworkState != null) { 
      unregisterReceiver(broadcastReceiverNetworkState); 
     } 
    } 

} 

w AndroidWebserver.java

package awserverfatepi.com.util; 
import java.util.Map; 
import fi.iki.elonen.NanoHTTPD; 

public class AndroidWebServer extends NanoHTTPD { 

    public AndroidWebServer(int port) { 
     super(port); 
    } 

    public AndroidWebServer(String hostname, int port) { 
     super(hostname, port); 
    } 

    @Override 
    public Response serve(IHTTPSession session) { 
     String msg = "<html><body><h1>Hello World</h1>\n"; 
     Map<String, String> parms = session.getParms(); 
     if (parms.get("username") == null) { 
      msg += "<form action='?' method='get'>\n <p>Seu nome: <input type='text' name='username'></p>\n" + "</form>\n"; 
     } else { 
      msg += "<p>Hello, " + parms.get("username") + "!</p>"; 
     } 
     return newFixedLengthResponse(msg + "</body></html>\n"); 
    } 
} 

Nie zapomnij o manifeście.xml

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

I ostatni

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/coordinatorLayout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical"> 

     <ImageView 
      android:layout_width="match_parent" 
      android:layout_height="150dp" 
      android:scaleType="centerCrop" 
      android:src="@drawable/header" /> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="0dp" 
      android:layout_weight="1" 
      android:background="@color/colorPrimaryLight" 
      android:gravity="center" 
      android:orientation="vertical"> 

      <LinearLayout 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:orientation="horizontal"> 

       <TextView 
        android:id="@+id/textViewIpAccess" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="http://000.000.000.000:" 
        android:textColor="@android:color/white" 
        android:textSize="20sp" 
        android:textStyle="bold" /> 

       <EditText 
        android:id="@+id/editTextPort" 
        android:layout_width="60dp" 
        android:layout_height="wrap_content" 
        android:gravity="center" 
        android:hint="8080" 
        android:inputType="numberDecimal" 
        android:maxLength="4" 
        android:text="8080" 
        android:textColor="@android:color/white" 
        android:textSize="20sp" 
        android:textStyle="bold" /> 

      </LinearLayout> 

      <TextView 
       android:id="@+id/textViewMessage" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_marginLeft="50dp" 
       android:layout_marginRight="50dp" 
       android:layout_marginTop="50dp" 
       android:gravity="center" 
       android:text="@string/message" 
       android:textColor="@android:color/white" 
       android:textSize="18sp" 
       android:visibility="invisible" /> 

     </LinearLayout> 

    </LinearLayout> 

    <android.support.design.widget.FloatingActionButton 
     android:id="@+id/floatingActionButtonOnOff" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="end|bottom" 
     android:layout_margin="16dp" 
     android:elevation="4dp" 
     android:src="@drawable/on_btn" 
     app:backgroundTint="@color/colorRed" /> 

</android.support.design.widget.CoordinatorLayout> 
Powiązane problemy