Отправьте изображение и другие строковые параметры на сервер, используя HttpURLConnection и Base64 - PullRequest
0 голосов
/ 23 мая 2018

Я пытаюсь отправить изображение и некоторые строковые значения из Android в php-скрипт, используя HttpURLConnection.Я успешно сделал это со строками, но не могу понять это правильно с изображением.Я использую Base64 (android.util.Base64), чтобы преобразовать мое изображение в строку, чтобы отправить его.Теперь у меня есть отдельный файл HttpParse.java, который я использую для отправки всей своей информации на сервер, и я думаю, что именно здесь необходимо внести изменения, чтобы разрешить изображение, но я не уверен (я новееРазработка Java / Android).Я исследовал несколько схожих вопросов, но они не до меня дошли, чтобы понять, что я делаю неправильно.Кроме того, я проверил, что я успешно конвертирую изображение в строку.Вот мой код:

РЕДАКТИРОВАТЬ Я получил немного дальше ... После тестирования, я получаю проблему, потому что три переменные, которые я пытаюсь получить с getArguments (), возвращаются какnull ... Но я не могу понять, как заставить их пройти успешно ... Я добавил код для того, как я запускаю свой фрагмент и как я пытаюсь получить свой пакет

Начало моего фрагмента:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_units);

    Intent intent = getIntent();

    LexaUser = intent.getStringExtra("UserName");
    ReadOnly = intent.getStringExtra("ReadOnly");
    Password = intent.getStringExtra("Password");
    QA = intent.getStringExtra("QA");
    SearchValue = intent.getStringExtra("SearchInput");

    bottomNavigation = (BottomNavigationView)findViewById(R.id.bottom_navigation);
    bottomNavigation.inflateMenu(R.menu.bottom_menu);
    fragmentManager = getSupportFragmentManager();

    bottomNavigation.getMenu().getItem(0).setChecked(true);

    UnitDetailsHeader = findViewById(R.id.UnitDetailsViewTitle);
    UnitDetailsHeader.setText(SearchValue);

    UnitSizeText = findViewById(R.id.UnitSize);
    UnitStatusText = findViewById(R.id.UnitStatus);

    if (SearchValue.contains("-")) {
        getUnitDetails(SearchValue, LexaUser);
    } else {
        getSiblings();
    }

    bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            int id = item.getItemId();

            switch (id){
                case R.id.action_search:
                    fragment = new NewUnitStatusFragment();
                    break;
                case R.id.action_cart:
                    fragment = new PendingUnitStatusFragment();
                    break;
                case R.id.action_hot_deals:
                    fragment = new FinalUnitStatusFragment();
                    break;
                case R.id.action_siblings:
                    fragment = new SiblingUnitFragment();
                    break;
            }

            Bundle connBundle = new Bundle();
            connBundle.putString("SearchValue", SearchValue);
            connBundle.putString("LexaUser", LexaUser);
            connBundle.putString("Password", Password);
            connBundle.putString("QA", QA);

            fragment.setArguments(connBundle);

            final FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.replace(R.id.main_container, fragment).commit();

            return true;
        }
    });


}

И где я пытаюсь получить свои аргументы: (У меня изначально был onCreateView, но затем я пытался переместить его в onCreate. Но поведение было таким же)

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getArguments() != null) {
        SearchValue = getArguments().getString("SearchValue");
        LexaUser = getArguments().getString("LexaUser");
        Password = getArguments().getString("Password");
    }
}

Мой фрагмент, где я получаю изображение и отправляю мои данные:

package [my_package];

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import android.util.Base64;
import java.util.HashMap;

import static android.app.Activity.RESULT_OK;

public class NewUnitStatusFragment extends Fragment {

    Context newUnitStatusContext;
    Activity newUnitStatusActivity;

    Intent cameraIntent;

    ProgressDialog progressDialog;

    String ReadOnly;
    String LexaUser;
    String Password;
    String SearchValue;

    String finalResultNewUnitStatus;
    String HttpURLNewUnitStatus = "https://[path/to/file]/insertNewUnitStatus.php";
    HashMap<String, String> hashMapNewUnitStatus = new HashMap<>();
    HttpParse httpParse = new HttpParse();

    Spinner statusSpinner;
    Spinner generalCauseSpinner;
    EditText newUSComment;
    Button addPhotoBtn;
    ImageView newUnitStatusImage;

    Button addNewUnitStatus;

    String newUnitStatus;
    String generalCause;
    String newUnitStatusComment;
    String newUnitStatusPhoto;

    String message;

    private static final int PICK_FROM_GALLERY = 1;


    public NewUnitStatusFragment() {
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_newunitstatus, container, false);

        newUnitStatusContext = getContext();
        newUnitStatusActivity = getActivity();

        statusSpinner = view.findViewById(R.id.Status);
        generalCauseSpinner = view.findViewById(R.id.GeneralCause);
        newUSComment = view.findViewById(R.id.NewComment);
        newUnitStatusImage = view.findViewById(R.id.AddPhoto);
        addPhotoBtn = view.findViewById(R.id.AddPhotosLabel);
        addNewUnitStatus = view.findViewById(R.id.addBtnNewUnitStatus);

        ArrayAdapter<CharSequence> statusSpinnerAdapter = ArrayAdapter.createFromResource(newUnitStatusContext,
            R.array.new_unit_status_array, android.R.layout.simple_spinner_item);

        statusSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        statusSpinner.setAdapter(statusSpinnerAdapter);

        newUnitStatus = statusSpinner.getSelectedItem().toString();

        ArrayAdapter<CharSequence> generalCauseSpinnerAdapter = ArrayAdapter.createFromResource(newUnitStatusContext,
            R.array.status_general_cause_array, android.R.layout.simple_spinner_item);

        generalCauseSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        generalCauseSpinner.setAdapter(generalCauseSpinnerAdapter);

        generalCause = generalCauseSpinner.getSelectedItem().toString();

        addPhotoBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                startGallery();
            }
        });

        // Set a click listener for the text view
        addNewUnitStatus.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                newUnitStatus = statusSpinner.toString();
                generalCause = generalCauseSpinner.toString();
                newUnitStatusComment = newUSComment.toString();

                if (getArguments() != null) {
                    SearchValue = getArguments().getString("SearchValue");
                    LexaUser = getArguments().getString("LexaUser");
                    Password = getArguments().getString("Password");
                }

                addNewUnitStatus(SearchValue, newUnitStatus, generalCause, newUnitStatusComment, newUnitStatusPhoto, LexaUser, Password);

            }
        });

        return view;
    }

    private void startGallery() {
    cameraIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        cameraIntent.setType("image/*");
        cameraIntent.setAction(Intent.ACTION_GET_CONTENT);
        if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
            startActivityForResult(cameraIntent, 1000);
        } else {
            Toast.makeText(newUnitStatusContext, "Error: " + cameraIntent + " - cameraIntent.resolveActivity(getActivity().getPackageManager()) = null", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        //super method removed
        if (resultCode == RESULT_OK) {
            if (requestCode == 1000) {
                Uri returnUri = data.getData();
                try {
                    Bitmap bitmapImage = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), returnUri);
                    newUnitStatusImage.setImageBitmap(bitmapImage);

                    newUnitStatusImage.buildDrawingCache();
                    Bitmap bm = newUnitStatusImage.getDrawingCache();
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                    byte[] b = baos.toByteArray();

                    newUnitStatusPhoto = Base64.encodeToString(b, Base64.DEFAULT);

                } catch (IOException ioEx) {
                    ioEx.printStackTrace(); 
                    Toast.makeText(newUnitStatusContext, "ioEx Error: " + ioEx, Toast.LENGTH_LONG).show();
                }
            } else {
                Toast.makeText(newUnitStatusContext, "Error: " + requestCode, Toast.LENGTH_LONG).show();
            }
        } else {
            Toast.makeText(newUnitStatusContext, "Error: " + resultCode, Toast.LENGTH_LONG).show();
        }
    }

    public void addNewUnitStatus(String searchInput, String newUnitStatus, String generalCause, String newUnitStatusComment, String newUnitStatusPhoto, String lexaUser, String password) {

        class NewUnitStatusClass extends AsyncTask<String,Void,String> {

            @Override
            protected void onPreExecute() {
                super.onPreExecute();

                progressDialog = ProgressDialog.show(newUnitStatusContext, "Loading Data", null, true, true);
            }

            @Override
            protected void onPostExecute(String httpResponseMsg) {

                super.onPostExecute(httpResponseMsg);

                if (httpResponseMsg != null) {

                    try {

                        JSONObject object = new JSONObject(httpResponseMsg);

                        message = object.getString("message");

                        Toast.makeText(newUnitStatusContext, httpResponseMsg, Toast.LENGTH_LONG).show();


                    } catch (JSONException e) {
                        Log.e("JSONException", "Error: " + e.toString());
                        Toast.makeText(newUnitStatusContext, "Error: " + e.toString(), Toast.LENGTH_LONG).show();
                    } // catch (JSONException e)

                    progressDialog.dismiss();

                } else {

                    progressDialog.dismiss();
                    Toast.makeText(newUnitStatusContext, "HttpResponseMsg is null.", Toast.LENGTH_LONG).show();
                }
            }

            @Override
            protected String doInBackground(String... params) {

                hashMapNewUnitStatus.put("searchinput", params[0]);
                hashMapNewUnitStatus.put("newUnitStatus", params[1]);
                hashMapNewUnitStatus.put("generalCause", params[2]);
                hashMapNewUnitStatus.put("newUnitStatusComment", params[3]);
                hashMapNewUnitStatus.put("newUnitStatusPhoto", params[4]);
                hashMapNewUnitStatus.put("lexauser", params[5]);
                hashMapNewUnitStatus.put("password", params[6]);

                finalResultNewUnitStatus = httpParse.postRequest(hashMapNewUnitStatus, HttpURLNewUnitStatus);

                return finalResultNewUnitStatus;
            }
        }
        NewUnitStatusClass newUnitStatusClass = new NewUnitStatusClass();
        newUnitStatusClass.execute(searchInput, newUnitStatus, generalCause, newUnitStatusComment, newUnitStatusPhoto, lexaUser, password);
    }
}

И мой код для этого на самом деле HttpURLConnection: HttpParse.java

package [my_package];

import android.app.ListActivity;
import android.widget.ArrayAdapter;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

public class HttpParse extends ListActivity {

    String FinalHttpData = "";
    String Result;
    BufferedWriter bufferedWriter;
    OutputStream outputStream;
    BufferedReader bufferedReader;
    StringBuilder stringBuilder = new StringBuilder();
    URL url;

    public String postRequest(HashMap<String, String> Data, String HttpUrlHolder) {

        try {
            url = new URL(HttpUrlHolder);

            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

            httpURLConnection.setReadTimeout(14000);

            httpURLConnection.setConnectTimeout(14000);

            httpURLConnection.setRequestMethod("POST");

            httpURLConnection.setDoInput(true);

            httpURLConnection.setDoOutput(true);

            outputStream = httpURLConnection.getOutputStream();

            bufferedWriter = new BufferedWriter(

                new OutputStreamWriter(outputStream, "UTF-8"));

            bufferedWriter.write(FinalDataParse(Data));

            bufferedWriter.flush();

            bufferedWriter.close();

            outputStream.close();

            if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {

                bufferedReader = new BufferedReader(
                    new InputStreamReader(
                            httpURLConnection.getInputStream()
                    )
                );
                FinalHttpData = bufferedReader.readLine();
            }
            else {
                FinalHttpData = "Something Went Wrong";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return FinalHttpData;
    }

    public String FinalDataParse(HashMap<String,String> hashMap2) throws UnsupportedEncodingException {

        for(Map.Entry<String,String> map_entry : hashMap2.entrySet()){

            stringBuilder.append("&");

            stringBuilder.append(URLEncoder.encode(map_entry.getKey(), "UTF-8"));

            stringBuilder.append("=");

            stringBuilder.append(URLEncoder.encode(map_entry.getValue(), "UTF-8"));

        }

       Result = stringBuilder.toString();

        return Result ;
    }
}

Любая помощь приветствуется!Спасибо!

PS В моем приложении отображается следующая ошибка:

W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference

Это приводит к этому:

E/JSONException: Error: org.json.JSONException: End of input at character 0 of
...