2

I want to serve a file, an image for example, to Chromecast. I used nanoHTTPD so I can reach the content via url and here is the code I use to get the url:

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) {
        File rootDir = Environment.getExternalStorageDirectory();
        File[] filesList = null;
        String filepath = "";
        if (uri.trim().isEmpty()) {
            filesList = rootDir.listFiles();
        } else {
            filepath = uri.trim();
        }
        filesList = new File(filepath).listFiles();
        String answer = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>sdcard0 - TECNO P5 - WiFi File Transfer Pro</title>";
        if (new File(filepath).isDirectory()) {
            for (File detailsOfFiles : filesList) {
                answer += "<a href=\"" + detailsOfFiles.getAbsolutePath()
                        + "\" alt = \"\">"
                        + detailsOfFiles.getAbsolutePath() + "</a><br>";
            }
        } else {
        }
        answer += "</head></html>" + "uri: " + uri + " \nfiles " + files
                + " \nparameters " + parameters + " \nheader ";
        return new NanoHTTPD.Response(answer);
    }

    }

This way I can get the url like "192.168.X.XX:8080/image.gif". Then I create a regular MediaInfo for this url:

private void startVideo() {
    MediaMetadata mediaMetadata = new MediaMetadata(     MediaMetadata.MEDIA_TYPE_PHOTO );
    mediaMetadata.putString( MediaMetadata.KEY_TITLE, getString( R.string.titulo_video ) );

    MediaInfo mediaInfo = new MediaInfo.Builder( getString( R.string.video_url ) )
            .setContentType( getString( R.string.content_type_gif ) )
            .setStreamType( MediaInfo.STREAM_TYPE_BUFFERED )
            .setMetadata( mediaMetadata )
            .build();
    try {
        mRemoteMediaPlayer.load( apiClient, mediaInfo, true )
                .setResultCallback( new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
                    @Override
                    public void onResult( RemoteMediaPlayer.MediaChannelResult mediaChannelResult ) {
                        if( mediaChannelResult.getStatus().isSuccess() ) {
                            mVideoIsLoaded = true;
                            mButton.setText( getString( R.string.pause_video ) );
                        }
                    }
                } );
    } catch( Exception e ) {
    }
}

where <string name="video_url">http://192.168.1.38:8080/sdcard/logo_etsiit.gif</string> is the url I got before, but nothing happens when I try to cast the image.

Is it possible to serve the file directly to the MediaInfo without having to copy and paste the url from a web browser?

Tell me if some more code is needed.

Log errors:

08-07 20:30:35.568  14669-14669/com.example.httpserver W/Httpd﹕ Web server initialized.
08-07 20:30:35.601  14669-14669/com.example.httpserver I/MediaRouter﹕ Found default route: MediaRouter.RouteInfo{ uniqueId=android/.support.v7.media.SystemMediaRouteProvider:DEFAULT_ROUTE, name=Teléfono, description=null, enabled=true, connecting=false, playbackType=0, playbackStream=3, volumeHandling=1, volume=3, volumeMax=15, presentationDisplayId=-1, extras=null, providerPackageName=android }
08-07 20:30:35.610  14669-14669/com.example.httpserver W/System.err﹕ java.net.BindException: bind failed: EADDRINUSE (Address already in use)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.IoBridge.bind(IoBridge.java:99)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:132)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at java.net.ServerSocket.bind(ServerSocket.java:335)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at java.net.ServerSocket.bind(ServerSocket.java:295)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at com.example.httpserver.NanoHTTPD.start(NanoHTTPD.java:142)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at com.example.httpserver.MainActivity.onResume(MainActivity.java:128)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1257)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at android.app.Activity.performResume(Activity.java:6076)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2975)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3017)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.access$800(ActivityThread.java:151)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at android.os.Looper.loop(Looper.java:135)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5254)
08-07 20:30:35.611  14669-14669/com.example.httpserver W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
08-07 20:30:35.612  14669-14669/com.example.httpserver W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:372)
08-07 20:30:35.612  14669-14669/com.example.httpserver W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
08-07 20:30:35.612  14669-14669/com.example.httpserver W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
08-07 20:30:35.612  14669-14669/com.example.httpserver W/System.err﹕ Caused by: android.system.ErrnoException: bind failed: EADDRINUSE (Address already in use)
08-07 20:30:35.612  14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.Posix.bind(Native Method)
08-07 20:30:35.612  14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.ForwardingOs.bind(ForwardingOs.java:56)
08-07 20:30:35.612  14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.IoBridge.bind(IoBridge.java:97)
08-07 20:30:35.612  14669-14669/com.example.httpserver W/System.err﹕ ... 19 more

When I select the image from my web browser all I can see is:

uri: /sdcard/logo_etsiit.gif files {} parameters {} header

EDIT: I solved the problem with the WebServer class, now I can see the image or PDF selected in my web browser

  public class webserver extends NanoHTTPD {
    FileInputStream fileInputStream;

    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 mediasend=getExtension(chosenFile);

        FileInputStream fis = null;
        try {
            fis = new FileInputStream(Environment.getExternalStorageDirectory()
                    + "/" + chosenFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }



        return new NanoHTTPD.Response(etsiit.etsiitcast_def.NanoHTTPD.Response.Status.OK,mediasend,fis);
    }
}

I also added this code to onCreate:

  //Get the ip of the device running NanoHTTPD server
    WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
    WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    int ipAddress = wifiInfo.getIpAddress();
    ipdevice=String.format("http://%d.%d.%d.%d:8080",(ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));

    // start the webserver
    mediaserver = new webserver();
    try {
        mediaserver.start();
    } catch(IOException ioe) {
        Log.d("Httpd", "The server could not start.");
    }
  • If from your, say, laptop you point your browser to http://192.168.1.38:8080/sdcard/logo_etsiit.gif, do you see the image loading from your phone in your browser? Also, you need to provide more information than "nothing happens"; I am pretty sure things are happening but not the way you expect them but it is useful to see logs both from the sender and receiver; e.g. does receiver see your request? Does it see the correct url for your image?.... – Ali Naddaf Aug 07 '15 at 18:19
  • This is what I can see in my browser when I select the image: `uri: /sdcard/logo_etsiit.gif files {} parameters {} header`, so I guess this is one of my mistakes. I added the log results to the question. – Irene Herrera Aug 07 '15 at 18:37
  • So you first need to fix your issue with serving your image correctly; when the same link is accessed in a laptop browser, it should open the image and if it doesn't, your server or its configuration needs to be looked at. From the exception above, it looks like the address you are trying to bind to is already in use, so is there another server running? – Ali Naddaf Aug 07 '15 at 19:22
  • I solved the problem with the WebServer class, now I can see the image or PDF selected in my web browser but still can send it to Chromecast because I don't know if I have to point to `ipdevice` in MediaInfo. – Irene Herrera Aug 08 '15 at 20:03
  • What type of URL are you now getting for the images? Give us an example of it ... – Ali Naddaf Aug 08 '15 at 21:52
  • Thank you for you help Ali Naddaf, the URL I was getting for my image was my phone IP address so I solved the problem. Now I can send any image to Chromecast. – Irene Herrera Aug 09 '15 at 17:46

1 Answers1

0

I found the solution to my problem: I just had to change MediaInfo mediaInfo = new MediaInfo.Builder( getString( R.string.video_url ) )to MediaInfo mediaInfo = new MediaInfo.Builder(ipdevice) where ipdevice is my phone ip address (e.g. http://192.168.1.40:8080).