Build a server on Android to "realize telemetry"

This article has been originally published on my public account hongyangAndroid.
You can view the collection
of historical articles here

Overview

When I was browsing Jianshu today, I found a library:

The main function is like this, firstly, when you open the app, you can access an address through the browser, and then you can upload the apk to the mobile phone through the browser (also supports the deletion of existing apk), and then the mobile phone can install and uninstall the apk .

Three pictures to understand:

After the app starts:

gekong02.png

Then access the PC side:

gekong01.gif

Drag and drop the apk to upload, you can upload it to the mobile phone.

gekong03.png

ok, the general introduction is clear.

Note that it must be on the same network segment.

Let's not talk about how useful it is. Many times when I see a project, I rarely think about what it can do. The most consideration is how it can be realized. If I know it, then I will learn it. As for what I can do , that will wait until I learn it?

Then think about his implementation. This way of uploading files is more common on the PC side, uploading files to the server.

Speaking of this, it can be imagined that this app may build a server on the mobile phone.

Well, that's right. A server is built on the mobile phone, so that the files from the PC can be sent to the mobile phone through html, and then the mobile phone can synchronize the interface after receiving it.

At the same time, the files on the Sdcard on the mobile phone can also be completely presented on the PC.

The server on the mobile phone uses this library:

If you are interested in parsing the source code, you can learn it yourself, and then start the feature film.

A friend's question

The reason why I paid attention to this library is because in the wanandroid group, a buddy has been asking a question for a long time. The question is:

  • How to play a video on a mobile phone by entering an address in the browser

At that time, many people answered, and the core of the answer was correct.

Of course, I happened to see this library, and I haven't pushed related content before, so I decided to write a simple Demo.

Of course, Demo has nothing to say about beauty, just to quickly achieve the effect.

The renderings are as follows:

gekong04.gif

The page displays a list of videos on your phone, and then click on a video to start playing the video.

With the above example reference, it is very simple.

Note: Part of the code is copied directly from the above example.
This case requires network and Sdcard permissions!

Set up the server first

Dependency library

First, rely on the libraries we need to build the Server:

compile 'com.koushikdutta.async:androidasync:2.+'

Write simple html

Then we write an html file under assets for browser access, index.html

The simplest is:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
</head>

<body>

嘿嘿嘿,连通了...

</body>

</html>

Start the service and listen on the port


public class MainActivity extends AppCompatActivity {
    private AsyncHttpServer server = new AsyncHttpServer();
    private AsyncServer mAsyncServer = new AsyncServer();

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


        server.get("/", new HttpServerRequestCallback() {
            @Override
            public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
                try {
                    response.send(getIndexContent());
                } catch (IOException e) {
                    e.printStackTrace();
                    response.code(500).end();
                }
            }
        });

        server.listen(mAsyncServer, 54321);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (server != null) {
            server.stop();
        }
        if (mAsyncServer != null) {
            mAsyncServer.stop();
        }
    }

    private String getIndexContent() throws IOException {
        BufferedInputStream bInputStream = null;
        try {
            bInputStream = new BufferedInputStream(getAssets().open("index.html"));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int len = 0;
            byte[] tmp = new byte[10240];
            while ((len = bInputStream.read(tmp)) > 0) {
                baos.write(tmp, 0, len);
            }
            return new String(baos.toByteArray(), "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (bInputStream != null) {
                try {
                    bInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

It can be seen that it is very simple to create an AsyncHttpServer object, we call get in onCreate, and set up a get-type url monitor externally. The monitored url is / that is the root directory.

Then call listen, pass in the port number 54321, and start listening on this port.

Stop the server when onDestroy.

When the access to "/" is captured, read the index.html under assets and return it to the browser.

Remember to add network permissions.

Ok, run the demo and test it.

Enter the address, your phone's IP:port number.

Note that the computer and mobile phone are on the same network segment!

Then you should see the following renderings:

gekong05.png

If you don't see it, then don't go down, look for the problem first~

Perfect Demo

Next, we return the mp4 on the phone to display it on the browser.

Very simple, since we can listen to / and return an index.html, we can listen to another url and return the file directory.

server.get("/files", new HttpServerRequestCallback() {
    @Override
    public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
        JSONArray array = new JSONArray();
        File dir = new File(Environment.getExternalStorageDirectory().getPath());
        String[] fileNames = dir.list();
        if (fileNames != null) {
            for (String fileName : fileNames) {
                File file = new File(dir, fileName);
                if (file.exists() && file.isFile() && file.getName().endsWith(".mp4")) {
                    try {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("name", fileName);
                        jsonObject.put("path", file.getAbsolutePath());
                        array.put(jsonObject);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        response.send(array.toString());
    }
});

We monitor the Url of /files, and then return the video file in the root directory of Sdcard, splicing it into JSON and returning it.

Here if you reboot, type on your browser:

http://192.168.1.100:54321/files

You will see a bunch of JSON data:

gekong06.png

But we need to display it on the html just now, so this request should be initiated by the html page just now:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="jquery-1.7.2.min.js" type="text/javascript"></script>

    <title>文档的标题</title>
    <script type="text/javascript">
        $(function() {
            var now = new Date();
            var url = 'files' + '?' + now.getTime();
            // 请求JSON数据
            $.getJSON(url, function(data) {
                // 编辑JSON数组
                for (var i = 0; i < data.length; i++) {
                    // 为每个对象生成一个li标签,添加到页面的ul中
                    var $li = $('<li>' + data[i].name + '</li>');
                    $li.attr("path", data[i].path);
                    $("#filelist").append($li);

                }
            });
        });

    </script>
</head>

<body>
    <ul id="filelist" style="float:left;"></ul>

</body>

</html>

Many friends may not know js, but they should be able to understand, $.getJSONget the returned JSON array, and then traverse to generate a li tag for each Json object and add it to the page.

jQuery is used here, and js also needs to be processed. It is omitted here. It is very simple. Just look at the source code.

At this point, the video directory can already be displayed:

gekong07.png

The next step is to click to play. There is a tag called video in the html for playing the video. It has a src attribute for setting the video path for playback.

So all we have to do is:

  • Click the name, get the url corresponding to the video, and then set the src attribute to the video.

So what is the url of the video?

We just returned the path of the video, so we just need to monitor another url, and the video file stream will be returned according to the incoming video path.

server.get("/files/.*", new HttpServerRequestCallback() {
    @Override
    public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
        String path = request.getPath().replace("/files/", "");
        try {
            path = URLDecoder.decode(path, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        File file = new File(path);
        if (file.exists() && file.isFile()) {
            try {
                FileInputStream fis = new FileInputStream(file);
                response.sendStream(fis, fis.available());
            } catch (Exception e) {
                e.printStackTrace();
            } 
            return;
        }
        response.code(404).send("Not found!");
    }
});

We monitored another url as files/xxx.*, after capturing, get the file name, go to SDCard to find the file, and return to the file stream.

The code on the html side is:

<script type="text/javascript">
    $(function() {
        var now = new Date();
        // 拿到video对象
        var $video = $("#videoplayer");
        var url = 'files' + '?' + now.getTime();
        $.getJSON(url, function(data) {
            for (var i = 0; i < data.length; i++) {
                var $li = $('<li>' + data[i].name + '</li>');
                $li.attr("path", data[i].path);
                $("#filelist").append($li);

                // 点击的时候,获取路径,设置给video的src属性
                $li.click(function() {
                    var p = "/files/" + $(this).attr("path");
                    $video.attr("src", "/files/" + $(this).attr("path"));
                    $video[0].play();
                });
            }
        });
    });

</script>

Of course, there is also a video tag inside the body tag on the page.

 <video id="videoplayer" controls="controls">
 </video>

Here, so the code is introduced~~

summary

Looking back, it is actually starting the server in the app, listening to some urls, and then returning text, json, file streams, etc. in a targeted manner.

Of course, there are a lot of things that can be done, even a PC version of the file browser.

There may be many people who are not familiar with html and js, but it is recommended to have a brief understanding, or type this example, because there is very little code in this example, and it is worth a start-up tutorial.

Source address:

https://github.com/hongyangAndroid/demo_ShowPhoneMp4

Welcome to my new website:
http://www.wanandroid.com/index

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325685494&siteId=291194637