Ansatz zur Verarbeitung eines online generierten CSV Files

  • 7 Antworten
  • Neuester Beitrag
Diskutiere Ansatz zur Verarbeitung eines online generierten CSV Files im Android App Entwicklung im Bereich Betriebssysteme & Apps.
Tiefkuehlpizza

Tiefkuehlpizza

Neues Mitglied
Habt ihr ein Tipp?

Die Url beispiel.de/kalender.php?a=export&export=csv&year=2022 generiert ein CSV zum Download.
Ich würde den Inhalt des Files gerne in meiner App verwerten (Abspeichern muss nicht sein).

Momentaner Ansatz in Kotlin:
Code:
...
val CSV_File_Path = "https://www.beispiel.de/kalender.php?a=export&export=csv&year=2022
val myUri: Uri = Uri.parse(CSV_File_Path)
val inputStream: InputStream? = ...appContext()...contentResolver.openInputStream(myUri)
...
Ich werde rausgeworfen mit:
...FileNotFoundException...

Passt der Ansatz um ein generiertes File downzuloaden?
In welche Richtung muss ich meinen Ansatz anpassen?

Viele Grüße
Pizza
 
swa00

swa00

Moderator
Teammitglied
Zuletzt bearbeitet:
Tiefkuehlpizza

Tiefkuehlpizza

Neues Mitglied
Danke für das Feedback.

Ich habe es mit OkHTTP3 wie folgt probiert:
Code:
...

val client = OkHttpClient()

val request = Request.Builder()
    .url("https://publicobject.com/helloworld.txt")
    .build()

client.newCall(request).execute().use { response ->
    if (!response.isSuccessful) throw IOException("Unexpected code $response")
    var strng = response.toString()
}
...
Absturz beim erstellen vom Request.
Code:
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: playground, PID: 14707
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1605)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:115)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
        at java.net.InetAddress.getAllByName(InetAddress.java:1152)
        at okhttp3.Dns$1.lookup(Dns.java:40)
        at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:185)
        at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:149)
        at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:84)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:214)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
        at okhttp3.RealCall.execute(RealCall.java:92)
        at playground.networking.NetworkManager$getSiteAuthed$1.invoke(NetworkManager.kt:263)
        at playground.networking.NetworkManager$getSiteAuthed$1.invoke(NetworkManager.kt:49)
        at playground.networking.TokenManager$authenticate$1.invoke(TokenManager.kt:47)
        at playground.networking.TokenManager$authenticate$1.invoke(TokenManager.kt:36)
        at playground.networking.TokenManager.getToken(TokenManager.kt:82)
        at playground.networking.TokenManager.authenticate(TokenManager.kt:46)
        at playground.networking.NetworkManager.getSiteAuthed(NetworkManager.kt:190)
        at playground.networking.NetworkManager.getSiteAuthed$default(NetworkManager.kt:186)
        at playground.networking.Clndr.fetch(Calendar.kt:24)
        at playground.networking.NetworkManager$indexAll$1.invoke(NetworkManager.kt:643)
        at playground.networking.NetworkManager$indexAll$1.invoke(NetworkManager.kt:49)
        at playground.networking.NetworkManager$indexAll$onDone$1.invoke(NetworkManager.kt:576)
        at playground.networking.NetworkManager$indexAll$onDone$1.invoke(NetworkManager.kt:49)
        at playground.networking.Courses$createIndex$onDone$1.invoke(Courses.kt:55)
        at playground.networking.Courses$createIndex$onDone$1.invoke(Courses.kt:16)
        at playground.networking.Courses$createIndex$2$3.invoke(Courses.kt:118)
        at playground.networking.Courses$createIndex$2$3.invoke(Courses.kt:16)
        at playground.networking.NetworkManager$getSiteAuthed$1$2.onResponse(NetworkManager.kt:308)
        at com.androidnetworking.common.ANRequest.deliverSuccessResponse(ANRequest.java:731)
        at com.androidnetworking.common.ANRequest.access$6500(ANRequest.java:80)
        at com.androidnetworking.common.ANRequest$6.run(ANRequest.java:709)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Gleiches Verhalten bei Nutzung von InputStream, OpenCsv und ApacheCsv.
Internet Permission ist beachtet.
Das einlesen lokaler Files (Im App Verzeichnis auf dem Emulator) funktioniert.

Ich versuche morgen noch ein neues Projekt zu erstellen und nur das dort reinzuklöppeln.
Bei dem Versuch beachte ich dann alle Details aus @swa00 Beispiel.
Hätte trotzdem gedacht, dass es "schnell" funktioniert.

Über Tipps würde ich mich freuen.

Gruß
Pizza
 
J

jogimuc

Stammgast
Hast du auch die Internet pemission im manifest gesetz?

<uses-permission android:name="android.permission.INTERNET" /> <application ...
 
Tiefkuehlpizza

Tiefkuehlpizza

Neues Mitglied
Ja, die Internet Permission ist gesetzt 👍
 
swa00

swa00

Moderator
Teammitglied
Also irgendwas stimmt mit deinen Policies nicht

at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1605)
setze mal zur Probe das im Application-Block der manifest ein
android:usesCleartextTraffic="true"
P.S Requests müssen wie deinem ersten Beispiel im Thread laufen
 
Tiefkuehlpizza

Tiefkuehlpizza

Neues Mitglied
Hallo Zusammen,

also auf den Tipp von @swa00 hin habe ich mal nach der zitierten Fehlermeldung gegoogelt.
Soweit ich das verstanden habe, sind aufwandsintensive Funktionen nicht im Main Thread erlaubt.

Dann habe ich die Funktion in eine eigene Klasse verlegt und dort run() überschrieben.
Immer noch der Fehler.

Dann habe ich mich in async eingelesen und das darüber gemacht und nun funktioniert es.

Code:
class RqstRun(private val scope: CoroutineScope, private val url: String = ""): Runnable {

    // Create OkHttp Client
    val client = OkHttpClient.Builder()
            .addNetworkInterceptor { chain ->
                chain.proceed(
                    chain.request()
                        .newBuilder()
                        .header("User-Agent", "milkalilalaunebaer")
                        .build()
                )
            }
            .build()

    override fun run() {
        fetch()
    }

    private fun fetch() = scope.async {
        try {
            // Create URL
            val myUrl = URL(url)
            // Build request
            val request = Request.Builder().url(myUrl).build()
            // Execute request
            val response = client.newCall(request).execute()

            val str = response.body!!.string()
            //Juhuu - Inhalt ist drin
        }
        catch(err:Error) {
            print("Error when executing get request: "+err.localizedMessage)
        }
    }
}
In main:
Code:
val myRqstRun = RqstRun(GlobalScope, sUrl)
            myRqstRun.run()
Danke für die Hilfe.

Gruß
Pizza
Beitrag automatisch zusammengefügt:

Wie ist das eigentlich, wenn ich mich vorher erst anmelden muss?

Die App an der ich ein bissel bastele macht das schon, ich habe dann ein valides Token und andere "normale" Seiten, die hinter der Anmeldeschranke sind, bekomme ich damit.

Das Token ist an der Stelle mit dem OkHTTP3 Request auch gültig
Bei der Seite bekomme ich allerdings nur das Fehlerfeedback statt den CSV Export.

Pseudocode
Code:
...

Token Check

if (success) {
   if(meine spezielle Seite)
    OkHTTP3  Zeugs ////Fehler - Du bist nicht angemeldet Seite

   else
     Parsing normal sites //OK
}

...
Muss man beim OkHTTP3 Request was Spezielles beachten?
Stichwort zum weiterlesen?

Gruß
Pizza
Beitrag automatisch zusammengefügt:

Update RequestBuilder - Hilft aber auch nicht weiter.
Code:
var tkn = prefs.getString("token", "")!!

val request = Request.Builder()
     .url(myUrl)
     .header("Authorization", tkn)
     .build()
Gruß
Pizza
 
Zuletzt bearbeitet: