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.