Hi everybody !
Following code is a server realized with akka-http on android that serves 
files.
For this to work, just call new ServerForDownloadFile() in an android 
AsyncTask.

class ServerForDownloadTask extends AsyncTask[AnyRef, Void, AnyRef] {
protected def doInBackground(args: AnyRef*): AnyRef = {
try {
new ServerForDownloadFile()
} catch { case e: Exception => println(e) }
}
return null
}

protected def onProgressUpdate(progress: Integer*) {}
protected def onPostExecute(result: Long) {}
}

Take care : this will work only with scala 2.11 (not with scala 2.12) 
because android is java 6 compatible (not java 8).


ServerForDownloadFile.scala
======================
package app

import java.io.File
import java.io.FileInputStream
import java.nio.channels.FileChannel
import java.nio.ByteBuffer
import java.nio.MappedByteBuffer
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util.Try
import scala.util.control.NonFatal
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpEntity.ChunkStreamPart
import akka.http.scaladsl.model._
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink
import akka.stream.scaladsl.Source
import akka.util.ByteString
import akka.util.Timeout

import android.os.Environment

class ByteBufferIterator(buffer:ByteBuffer, chunkSize:Int) extends 
Iterator[ByteString] {
require(buffer.isReadOnly)
require(chunkSize > 0)

override def hasNext = buffer.hasRemaining

override def next(): ByteString = {
val size = chunkSize min buffer.remaining()
val temp = buffer.slice()
temp.limit(size)
buffer.position(buffer.position() + size)
ByteString(temp)
}
}

class ServerForDownloadFile {
def map1(path: String) : MappedByteBuffer = {
val inputStream = new FileInputStream(path)
val channel: FileChannel = inputStream.getChannel();
val result = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size);
channel.close()
result
}

implicit val system = ActorSystem()

implicit val materializer = ActorMaterializer()
implicit val askTimeout: Timeout = 500.millis

import HttpMethods._

val requestHandler: HttpRequest => HttpResponse = {
case HttpRequest(GET, uri, headers, _, _) =>
val dir: File = 
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val path: String = dir.getPath.toString + "/myfile.avi"
println("=========== path=" + path)
val result = Try {
val mappedByteBuffer = map1(path)
val iterator = new ByteBufferIterator(mappedByteBuffer, 4096)
var cnt = 0
val chunks = Source(() => iterator).map { x =>
if ( cnt % 10000 == 0 )
println("Chunk of size " + x.size + "  cnt=" + cnt)
cnt += 1
ChunkStreamPart(x)
}
HttpResponse(entity = 
HttpEntity.Chunked(MediaTypes.`application/octet-stream`, chunks))
} recover {
case NonFatal(cause) =>
HttpResponse(StatusCodes.InternalServerError, entity = cause.getMessage)
}
result.get
case _: HttpRequest => HttpResponse(StatusCodes.NotFound, entity = "Unknown 
resource!")
}

val address = "localhost"
val serverSource: Source[Http.IncomingConnection, 
Future[Http.ServerBinding]] = Http(system).bind(interface = address, port = 
8080)
val bindingFuture: Future[Http.ServerBinding] = 
serverSource.to(Sink.foreach { connection =>
// foreach materializes the source
println("Accepted new connection from " + connection.remoteAddress)
// ... and then actually handle the connection
connection.handleWithSyncHandler(requestHandler)
}).run()

while (true )
Thread.sleep(100)
}

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to