VolleyMultipartRequest

wer112

Top Contributor
Lasse das doch mal mit den Session . Mache ein einfaches PHP und eine einfache APP die nur den Request schickt und Teste es aus bis du es verstanden hast . So wird das nichts werden.
DAs mit den Session ist kein Problem dient als Sicherheit. Mit Postmann hat es doch super geklappt. der Java Teil ist das Problem.

Und möchte eine Datei versenden und kein Bild. Bilder gibt es viele Anleitungen, aber nicht für eine Datei.
 

KonradN

Super-Moderator
Mitarbeiter
Das Problem hier ist doch erst einmal, dass man genau verstehen muss, wie hier die Daten transferiert werden. Wenn der Request per postman funktioniert, dann musst Du "nur" noch einen solchen Request in Java bauen und versenden.

Daher ist die erste Frage: Was macht Postman denn da genau? (Die Frage wäre eigentlich unnötig, da ja ein PHP Server diesbezüglich gebaut wurde, daher müsste diese Information schon vorliegen. Aber da wurde vermutlich nur kopiert ohne die Details zu verstehen.)

Dazu schauen wir dann einfach einmal etwas bei Postman und dann finden wir zu dieser Art des Requests:
Upload a file via POST request | Postman Answers | Postman API Network

Das ist also ein Multipart form-data Request ... was bedeutet das genau?
Understanding multipart/form-data in HTTP protocol - SoByte

Und nun könnt ihr schauen, wie ihr sowas in Java aufbauen könnt :)
 

Jw456

Top Contributor
Hast du überhaupt Zugriff auf die Datei in Android. Kannst du die Datei Überhaupt öffnen?
Wie groß ist das ByteArray was du von der Methode zurück bekommst? Stimmt das mit der Datei etwa überein?
Von wo welchen Android Speicherbereich willst du die Datei lesen?
 

wer112

Top Contributor
Hast du überhaupt Zugriff auf die Datei in Android. Kannst du die Datei Überhaupt öffnen?
Wie groß ist das ByteArray was du von der Methode zurück bekommst? Stimmt das mit der Datei etwa überein?
Von wo welchen Android Speicherbereich willst du die Datei lesen?
Ich kann die Methode nicht aufrufen um die Zahlen zu bekommen:

Ergebniss:
Code:
java.lang.NullPointerException: uriString
                                                                                                        at android.net.Uri$StringUri.<init>(Uri.java:507)
                                                                                                        at android.net.Uri$StringUri.<init>(Uri.java:497)
                                                                                                        at android.net.Uri.parse(Uri.java:469)
                                                                                                        at (freeentwickler_registrieren.java:893)
                                                                                                        at freeentwickler_registrieren.java:833)
                                                                                                        at (freeentwickler_registrieren.java:78)
                                                                                                        at .onClick(freeentwickler_registrieren.java:183)
                                                                                                        at android.view.View.performClick(View.java:7792)
                                                                                                        at android.widget.TextView.performClick(TextView.java:16112)
                                                                                                        at android.view.View.performClickInternal(View.java:7769)
                                                                                                        at android.view.View.access$3800(View.java:910)
                                                                                                        at android.view.View$PerformClick.run(View.java:30218)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:938)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                        at android.os.Looper.loopOnce(Looper.java:226)
                                                                                                        at android.os.Looper.loop(Looper.java:313)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:8751)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

Habe es so probiert um das Ergebniss zu bekommen:

Java:
 try {
            byte[] ini = uriToByteArray(getActivity(), Uri.parse(zipUri));
            Log.e("Free Entwickler", "Bytes: " + ini);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

Die URI:
zipUri = Environment.getExternalStorageDirectory() + "/Download/" + "E" + kundennummer + ".zip";
 

Jw456

Top Contributor
Basierend auf dem Code Post #1
Hatte ich so eine Datei gesendet. Ohne da irgendwelche Änderungen an der Klasse VolleyMultipartRequest zu machen.

Java:
        public byte[] getArrayFromZip( String  zipPath) {
        File myFile = new File(zipPath);
        ByteArrayOutputStream byteBuffer = null;

        try (InputStream inputStream = new FileInputStream(myFile)) {
            byteBuffer = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];
            int len;

            while ((len = inputStream.read(buffer)) != -1) {
                byteBuffer.write(buffer, 0, len);
            }

        }catch (IOException e){
            Log.e("Free Entwickler", "IOException: " + e);
        }
        return byteBuffer.toByteArray();
    }


    private void uploadZip() {

        VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, ROOT_URL,
                new Response.Listener<NetworkResponse>() {
                    @Override
                    public void onResponse(NetworkResponse response) {
                        try {
                            JSONObject obj = new JSONObject(new String(response.data));
                            Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
                        Log.e("GotError",""+error.getMessage());
                    }
                }) {

            @Override
            protected Map<String, DataPart> getByteData() {
                Map<String, DataPart> params = new HashMap<>();
                long imagename = System.currentTimeMillis();
                byte[] zipArray = getArrayFromZip(Environment.getExternalStorageDirectory() + "/Download/" + "Ezip" + ".zip");
                params.put("zip", new DataPart(imagename + ".zip", zipArray ));
                return params;
            }
        };

        //adding the request to volley
        Volley.newRequestQueue(this).add(volleyMultipartRequest);
    }
 

Jw456

Top Contributor
PS: Wenn du endlich anfangen würdest auch stimmige Bezeichner zu verwenden würden solche Fehler sicher weniger passieren.
 

KonradN

Super-Moderator
Mitarbeiter
Hatten wir nicht schon eine neue Version der Methode, die keine Uri sondern einen String mit Pfad nimmt? Weil getContentProvider nicht ging? Da hatte ich doch dann eine Alternative genannt, wie Du die Datei einlesen konntest. Aber das muss dann ein anderer Thread gewesen sein, denn das habe ich jetzt hier im Thread auf den ersten Blick nicht gefunden.

Ursache war da doch, dass es für ZIP Dateien kein Content Provider gab oder so und Du da dann eine Exception hattest ...
 

Jw456

Top Contributor
dann zeige dein PHP lase dir im php doch den typ ausgeben.

echo "Datei Type : ". $_FILES['zip']['type']. "\n";

Frage hast du die Orginal volleyMultipartRequest Klasse?
 

wer112

Top Contributor
dann zeige dein PHP lase dir im php doch den typ ausgeben.

echo "Datei Type : ". $_FILES['zip']['type']. "\n";
Würd nicht funktionieren, da ich seitdem dein Code genommen habe, bekomme ich kein Response mehr und auch kein Type.

In Postman bekomme ich ein Type, aber nicht wenn ich es per App mache.
Frage hast du die Orginal volleyMultipartRequest Klasse?
Ne, musste DartPart public machen. Sonst bleibt er.
 

Jw456

Top Contributor
Ich hoffe du hast DataPart auch als innere Klasse gelassen so wie im Tutorial.

zeige es komplett.
Oder lade dir das Projekt von der Tut. Seite Link ist am Ende.
 

wer112

Top Contributor
Ich hoffe du hast DataPart auch als innere Klasse gelassen so wie im Tutorial.

zeige es komplett.
Oder lade dir das Projekt von der Tut. Seite Link ist am Ende.
Wenn ich das !:! mache wie im Download Ordner bzw. auf der Webseite bekomme ich diese Fehlermeldung was ich dir auf dem Foto gezeigt hatte, wo DartaPart fehlerhaft makiert wurden ist.

Es ging zum Teil wenns public ist, aber du meinst, kann man Orginal lassen.
 

KonradN

Super-Moderator
Mitarbeiter
Ist genauso ohne public. Kp wieso das nicht klappt ohne public.
Java Grundlagen! Ohne "public" ist es "package private" und damit ist es nur innerhalb des gleichen packages sichtbar.

In dem original Projekt werden die Klassen im gleichen Package sein und du wirst es in unterschiedlichen Packages haben.
 

wer112

Top Contributor
Dazu hatte ich doch auch einen Post gemacht - war in einem anderen Thread, oder? Natürlich ist das mit dem public ok und sollte auch public sein. Die class sollte sogar "public static" sein um sauber zu sein.
JW456 hat gesagt ich kann das Orginal nehmen und das Orginale ist kein Public. Wenn es nicht Public ist, wird es mir Rot angezeigt.
Du hast die Klasse ja auch in einem andren package als
die Activity. Dann entweder einen Import oder FQN
Import geht nicht, da DartaPart nicht public ist.

Was ist FQN bei dir?
 

KonradN

Super-Moderator
Mitarbeiter
Ich kann nur etwas zu Java Grundlagen schreiben. Und die Java Syntax muss stimmen. Und ich hatte Dir zu den Anpassungen etwas geschrieben und es liess sich übersetzen. Es haben auch erste Dinge funktioniert. Das dann gegen eine Version auszutauschen, die nicht übersetzt, macht wenig Sinn und solltest Du auch nicht erst machen.

Es ist super, dass Du Vorschläge versuchst und entsprechend Rückmeldung gibst. Das ist super! Aber ich denke, bezüglich der Anpassung kannst Du diese Vorschläge an dieser Stelle nicht weiter verfolgen. Wenn Du rein "public" hinzugefügt hast bei der inneren Klasse, dann hast Du an der Funktionalität nichts geändert - außer, dass Du eben auch aus anderen Packages darauf zugreifen kannst. Das brauchst Du und das ist für die Funktionalität ok.

Und Deine Unterteilung in mehrere Packages macht auch (prinzipiell) Sinn. Daher sehe ich keinen Grund, die Struktur anzupassen nur um das "public" nicht mehr haben zu müssen.
 

wer112

Top Contributor
Ich kann nur etwas zu Java Grundlagen schreiben. Und die Java Syntax muss stimmen. Und ich hatte Dir zu den Anpassungen etwas geschrieben und es liess sich übersetzen. Es haben auch erste Dinge funktioniert. Das dann gegen eine Version auszutauschen, die nicht übersetzt, macht wenig Sinn und solltest Du auch nicht erst machen.

Es ist super, dass Du Vorschläge versuchst und entsprechend Rückmeldung gibst. Das ist super! Aber ich denke, bezüglich der Anpassung kannst Du diese Vorschläge an dieser Stelle nicht weiter verfolgen. Wenn Du rein "public" hinzugefügt hast bei der inneren Klasse, dann hast Du an der Funktionalität nichts geändert - außer, dass Du eben auch aus anderen Packages darauf zugreifen kannst. Das brauchst Du und das ist für die Funktionalität ok.

Und Deine Unterteilung in mehrere Packages macht auch (prinzipiell) Sinn. Daher sehe ich keinen Grund, die Struktur anzupassen nur um das "public" nicht mehr haben zu müssen.
Habe es wieder auf Public gestellt. Leider bekomme ich keine Response mehr nur ein Yolly Error und auch kein Type rein.
 

Jw456

Top Contributor
Java:
    dataOutputStream.writeBytes(lineEnd);
    }

    public  class DataPart {
        private String fileName;
        private byte[] content;
        private String type;

        public DataPart() {
        }

        public DataPart(String name, byte[] data) {  //hier anpassen
            fileName = name;
            content = data;
        }

        String getFileName() {
            return fileName;
        }

        byte[] getContent() {
            return content;
        }

        String getType() {
            return type;
        }

    }
}
 

wer112

Top Contributor
Bei unterschiedlichen package public aber der der Konstruktor ist im Original leider auch nicht public
Was bedeudet bei dir FQN?
Ich musste DartPart wieder public machen, sowie KonradN gesagt hat, da ich sonst nur die Fehlermeldung bekomme. Und import geht niccht, wenn das nicht public ist.

Type bekomme ich immer noch nicht und immer noch keine Resonse nur den Volly Erro.
 

wer112

Top Contributor
Java:
    dataOutputStream.writeBytes(lineEnd);
    }

    public  class DataPart {
        private String fileName;
        private byte[] content;
        private String type;

        public DataPart() {
        }

        public DataPart(String name, byte[] data) {  //hier anpassen
            fileName = name;
            content = data;
        }

        String getFileName() {
            return fileName;
        }

        byte[] getContent() {
            return content;
        }

        String getType() {
            return type;
        }

    }
}
Das ist nicht dasOrginale, habe das wie bereits geschrieben genauso public gemacht. Die Probleme habe ich immer noch.
 

Jw456

Top Contributor
Wir haben ja nun fest gestellt das unterschiedliche package hast und da ist public auch richtig ok.

Auch ich musste es ändern habe die Klasse vorher nicht bearbeitet als ich alles noch im selben Package hatte.
 

Jw456

Top Contributor
Kompilieren übersetzen tut er aber?

Warum steht throws IOException bei dir ? Bild Post #65
Java:
   protected Map<String, DataPart> getByteData() throws IOException{
 

Marinek

Bekanntes Mitglied
Das Problem ist via Forum nicht zu lösen. Man dreht sich im Kreis und bis da eine Info public, private oder nix kommt, dauert 3 Stunden.

Es werden auch immer nur Bruchstücke der Informationen mitgeteilt. Ich kann nur dazu raten sich ein einfacheres Projekt zu suchen, mit denen man die Grundlagen versteht. Das hier hat 0 Sinnn.

Ich habe das mal 10 Minuten gegoogelt.


Hier ist ein Beispiel, das genau deine Anforderungen entspricht.
 

wer112

Top Contributor
Kompilieren übersetzen tut er aber?

Warum steht throws IOException bei dir ? Bild Post #65
Java:
   protected Map<String, DataPart> getByteData() throws IOException{
Habe ich wieder weggemacht, lag an eine andere Methode die ich probiert hatte von KonradN oder so.
Vermutlich, weil getArrayFromZip eine IOException werfen kann.
andere Rest von andere Methode
Hier wäre die IOException, die beim Lesen der Datei auftreten kann, irgendwo zu behandeln.
Dann muss man die behandeln.

Hat allerdings nicht mit den Problemen zu tun
 

Jw456

Top Contributor
Nochmal die Frage hast du wirklich den Zugriff auf die Zip Datei?
denn Environment.getExternalStorageDirectory() ist seit api 29 deprecated


zipUri = Environment.getExternalStorageDirectory() + "/Download/" + "E" + kundennummer + ".zip";
Du könnest die Datei in den Appspeicher erstellen lassen. Nicht den öffentlichen
 

wer112

Top Contributor
Nochmal die Frage hast du wirklich den Zugriff auf die Zip Datei?
denn Environment.getExternalStorageDirectory() ist seit api 29 deprecated



Du könnest die Datei in den Appspeicher erstellen lassen. Nicht den öffentlichen
ohne Filter konnte ich das hochladen und es funktioniert. Wenn es ab 29 nicht mehr geht, wie komme ich dann in den normalen Interner Speicher?
 

wer112

Top Contributor
was ist bei dir der Filter?
Der filter geht mit Postman, aber nicht für die App. Ohne Filter kann ich die Datei hochladen, aber ich erhalte keine Response mehr und ein Error Fehler:

Java:
if($_FILES['zip']['type'] == "application/zip"){

}else{
                $array['response'] = "falsches Format";
                $array['format'] = $_FILES['zip']['type'];
                echo json_encode($array);
            }
 

wer112

Top Contributor
zeige dein PHP ohne deinen "Filter"
Ohne Filter:

PHP:
<?php
session_start();

include_once("includes/utf-8.php");
require "connections/db.php";

$array = array();

$angemeldet = 1;//trim($_SESSION['angemeldet']);
$kundennummer = "855";//trim($_SESSION['kn']);

if(empty($angemeldet) or empty($kundennummer)){
    
    
    $array['response'] = "Session fehler";
    echo json_encode($array);


}else{
    
    
 

    if($angemeldet == 1){

        
        $zip = $_FILES['zip']['tmp_name'];

        $dir = $_SERVER['DOCUMENT_ROOT'] . "/projekte/klugstore/doc/entdata/";

        

        if(empty($zip)){

            $array['response'] = "Datei ist leer.";
            echo json_encode($array);

        }else{

            
                $check = move_uploaded_file($zip,$dir.$_FILES["zip"]["name"]);
                
                if($check){
                    $array['format'] = $_FILES['zip']['type'];
                $array['response'] = "erfolgreich hochgeladen";
                echo json_encode($array);

                }else{
                    $array['format'] = $_FILES['zip']['type'];
                    $array['response'] = "nicht erfolgreich hochladen";
                    echo json_encode($array);
                }

            
            
            


        }

      

    }else{
        $array['response'] = "nicht angemeldet.";
        echo json_encode($array);
    }

}

?>

Mit Postman geht der Filter einwandfrei...
 

Marinek

Bekanntes Mitglied
Wir sind wieder bei Post 1.

Deine url scheint falsch zu sein. Oder deine App kann nicht nach draußen kommunizieren. Das steht ja in der letzten Exception.

Du musst vor dem hochladen die Session authentifizieren. Beim hochladen musst du sessioninformationen mitsenden. Sonst geht das nicht.

Unsere Hinweise hast du bisher erfolgreich ignoriert.

Ich bin hier raus.
 

wer112

Top Contributor
Wir sind wieder bei Post 1.

Deine url scheint falsch zu sein. Oder deine App kann nicht nach draußen kommunizieren. Das steht ja in der letzten Exception.
Die URL funktioniert, da die Zip Datei ohne den Filter gesendet wird.
Du musst vor dem hochladen die Session authentifizieren. Beim hochladen musst du sessioninformationen mitsenden. Sonst geht das nicht.
Das macht mein Cookie Manager, da liegt nicht das Problem.
Unsere Hinweise hast du bisher erfolgreich ignoriert.
Ich ignoriere keine Informationen. Das Problem ist weder PHP, da Postman problem klappt und es sind auch keine Session Probleme. Da ich Session ausgeschalten habe und mit festen Variablen gearbeitet haben.
 

Oben