NanoHTTPを使用してHTMLファイルを提供しようとしています。ただし、NanoHTTPは比較的文書化されておらず、私はAndroidを初めて使用します。私の質問は、htmlファイルをどこに保存するのか、そしてNanoHTTPを使用してどのように具体的に提供できるのかということです。
5 に答える
遅い答えですが、他の人には役立つかもしれません。
これは単純なhelloWebサーバーであり、正確には要求されたものではありませんが、ここから続行できます。次のプログラムはwww
、SDカードのルートにディレクトリがあり、そのindex.html
中にファイルがあることを前提としています。
主な活動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);
}
}
}
明らかに、NanoHTTPD
クラスは同じパッケージに含まれている必要があります。
でインターネット許可を与える必要がありますAndroidManifest.xml
。
<uses-permission android:name="android.permission.INTERNET" />
外部ストレージ権限を読み取ります。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
編集:サーバーにアクセスするには、デバイスのIPを使用してWebブラウザを開きます192.168.1.20:8080
。
ノート:
- Android2.3でテスト済み
- ポート80の使用は、rootユーザー(http://www.mail-archive.com/android-developers@googlegroups.com/msg47377.html)に制限されています。
かなり良いソースコードはここで見つけることができます: https ://github.com/Teaonly/android-eye
htmlおよびJavaScriptファイルが保存されているChceckアセットフォルダー https://github.com/Teaonly/android-eye/tree/master/assets
TeaServer-サーバーの実装 https://github.com/Teaonly/android-eye/blob/master/src/teaonly/droideye/TeaServer.java
MainActivity-サーバーの初期化 https://github.com/Teaonly/android-eye/blob/master/src/teaonly/droideye/MainActivity.java
現在のNanoHTTPDバージョンで動作する更新されたWebServer
クラス(rendonの応答を参照):
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);
}
}
HTMLファイルやその他の種類のファイルを提供する方法も見てください。Nanohttpdクラスを拡張するAndroidWebServerクラスがあります。これが私の応答方法です->
public Response serve(IHTTPSession session) {
String uri=session.getUri();
String msg = "<html><body><h1>Hello server</h1>\n";
File [] arrayfile;
int i=0;
try{
session.parseBody(new HashMap<String, String>());
}catch (ResponseException | IOException r){
r.printStackTrace();
}
Map<String, String> parms = session.getParms();
if (parms.get("username") == null) {
msg += "<form action='?' method='get'>\n <p>Your name: <input type='text' name='username'></p>\n" + "</form>\n";
} else {
msg += "<p>Hello, " + parms.get("username") + "!</p>";
}
msg += "<br><br><a href='/Open_rap'>Open Image of Lionel Messi</a><br><br>";
msg += "<br><br><a href='/files'>Browse Files</a><br><br>";
msg += "<br><br><a href='/getmethod'>GET METHOD OPERATION</a><br><br>";
msg += "<br><br><a href='/postmethod'>POST METHOD OPERATION</a><br><br>";
msg += "<br><br><a href='/jquery'>JQUERY OPERATION</a><br><br>";
if(uri.equals("/hello")){
String response="Hello World";
return newFixedLengthResponse(response);
}
else if(uri.equals("/getmethod")){
String html="<html><head><h1>Welcome to the Form</h1><head/><body>";
if(parms.get("name")==null){
html +="<form action='' method='get'> \n " +
"<p>Enter Your Name:</p> <input type='text' name='name'>" +
"</form>" +
"</body>";
}
else{
html +="<p>Hello Mr. "+ parms.get("name") +"</p>"+
"</body> ";
}
html +="</html>";
return newFixedLengthResponse(html);
}
else if(uri.equals("/postmethod")){
String html="<html><head><h1>Welcome to the Form</h1><head/><body>";
Map<String, String> files = new HashMap<String, String>();
Method method = session.getMethod();
String postParameter="";
html +="<form action='' method='post'> \n " +
"<p>Enter Your Name:</p> <input type='text' name='name'>" +
"</form>";
if (Method.POST.equals(method) || Method.PUT.equals(method)) {
try {
session.parseBody(files);
} catch (IOException ioe) {
try {
// return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
} catch (Exception e) {
e.printStackTrace();
Log.d("Exception", e.getMessage());
}
} catch (ResponseException re) {
try {
// return newFixedLengthResponse(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
} catch (Exception e) {
e.printStackTrace();
Log.d("Exception", re.getMessage());
}
}
}
html +="</body></html>";
String postBody = session.getQueryParameterString();
postParameter = session.getParms().get("name");
Log.d("Postbody",postBody+"\n"+postParameter);
if(postParameter!=null){
String html1="<html><head><h1>"+ postParameter +"</h1><head></html>";
return newFixedLengthResponse(html1);
}
return newFixedLengthResponse(Response.Status.OK,"text/html",html);
}
else if(uri.equals("/Open_rap")){
File root= Environment.getExternalStorageDirectory();
FileInputStream fis = null;
File file = new File(root.getAbsolutePath() + "/www/messi.jpg");
Log.d("Path",root.getAbsolutePath());
try{
if(file.exists())
{
fis = new FileInputStream(file);
}
else
Log.d("FOF :", "File Not exists:");
}catch (FileNotFoundException e)
{
e.printStackTrace();
}
return newFixedLengthResponse(Response.Status.OK,"image/jpeg",fis, file.length() );
}
else {
return newFixedLengthResponse(msg + "</body></html>\n");
}
}
ご覧のとおり、GETメソッドとPOSTメソッドを実装しました。uri.equals("/getmethod")
コードのこの部分とでそれぞれを見つけることができますuri.equals("/getmethod")
。
また、->の部分を見ることができますuri.equals("/openrap")
。ここでは、JPGファイルをクライアントのブラウザに提供しており、画像は/www/
フォルダの内部ディレクトリにあります。
疑問がある場合は、私に連絡してください。
これを試してください...組織専用の2つのパッケージ(activity、util)を作成します。アクティビティでは、utilでクラスMainActivity.javaを作成し、クラス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);
}
}
}
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" );
}
}
Manifest.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" />
そして最後
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>