mercredi 15 juillet 2015

Select random image to send to server

I am new to Android development. I created my first app which is a camera with the ability to capture an image, query the user for a Car ID related to the image, preview the captured image, and upload that image to the server.

I am interested in randomly sending out one image from possibly multiple such as from the image directory to the server. I do NOT want to send multiple images to the server--just one random image.

Upon much research on this website as well as on numerous others, I determined the following: I must obtain the image directory to where the captured images are uploaded to, I must randomly select an image from said directory using the random capability in Android, I must set up the image bitmap based on the file uri of the image, and I must convert the bitmap to a blob data type by base64 encoding.

I did the above, but my bitmap returned as null since I receive the message, "Please select image", which was the toast message for that instance.

Here is my code:

public class MainActivity extends Activity {

    // Activity request codes.
    private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
    public static final int MEDIA_TYPE_IMAGE = 1;

    Bitmap bitmap;
    ProgressDialog pd;
    InputStream is;


    //Directory name to store captured images.
    private static final String IMAGE_DIRECTORY_NAME = "Hello Camera";

    private Uri fileUri; //File url to store captured images.

    private ImageView imgPreview;

    private Button btnCapturePicture;

    private Button upload;

    Button mButton;
    EditText mEdit;

    /*  Initializes activity, defines UI layout, and retrieves widgets
      * to interact with.
      * @param savedInstanceState - data is caught here and saved for
      *                           future app use.
      */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

     mButton = (Button)findViewById(R.id.button);
     mEdit = (EditText)findViewById(R.id.edittext);

        mButton.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View view) {
                        Log.v("EditText", mEdit.getText().toString());
                    }
                });

        imgPreview = (ImageView) findViewById(R.id.imgPreview);

        btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);

        upload = (Button) findViewById(R.id.upload);

        upload.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (bitmap == null) {
                    Toast.makeText(getApplicationContext(), "Please Select Image", Toast.LENGTH_LONG).show();

                } else {
                    new ImageUpload().execute();
                }

            }
        });

        /**
         * Captures image button click event in order to capture a photo.
         * @param new View.OnClickListener- call to constructor
         */
        btnCapturePicture.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                //Captures an image.
                captureImage();
            }
        });


        //Checks for camera availability.
        if (!isDeviceSupportCamera()) {
            Toast.makeText(getApplicationContext(),
                    "Sorry! Your device doesn't support camera", Toast.LENGTH_LONG).show();
            //Closes if a camera is not available on the device.
            finish();
        }
    }

    /**
     * Checks if device has camera hardware.
     *
     * @return - true or false.
     */
    private boolean isDeviceSupportCamera() {
        if (getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            //Device has a camera.
            return true;
        } else {
            // Device does not have a camera.
            return false;
        }
    }

    /*
     * Launches camera app request image capture.
     */
    private void captureImage() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

        //Starts the image capture Intent.
        startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
    }

    /**
     * Gets and stores the file url. Will be null after returning from camera
     * app.
     *
     * @param outState - Holds per-instance state from activity.
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        // Saves the file url in bundle. It will be null on screen orientation changes.
        outState.putParcelable("file_uri", fileUri);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        //Gets the file url.
        fileUri = savedInstanceState.getParcelable("file_uri");
    }


    /**
     * Receives activity result method. Will be called after closing the camera.
     *
     * @param requestCode - Requests to capture an image.
     * @param resultCode  - Based on success or failure of image capturing, shows
     *                    an image preview or one of two error messages.
     * @param data        - Carries the result data(successfully captured image).
     * @return - An image preview, or one of two error messages.
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //If the result is the image capturing event,
        if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                //the image was successfully captured
                // and will be displayed in the preview.
                previewCapturedImage();
            } else if (resultCode == RESULT_CANCELED) {
                //The user cancelled the image capturing.
                Toast.makeText(getApplicationContext(),
                        "User cancelled image capture", Toast.LENGTH_SHORT).show();
            } else {
                //Image capturing failed, but the user did not actually cancel it.
                Toast.makeText(getApplicationContext(),
                        "Sorry! Failed to capture image", Toast.LENGTH_SHORT).show();
            }
        }
    }


    /**
     * Displays the image from a path to ImageView.
     * Downsizes an image if necessary and throws exception
     * if the image is too large.
     */
    private void previewCapturedImage() {
        try {

            imgPreview.setVisibility(View.VISIBLE);
            upload.setVisibility(View.VISIBLE);

            File mediaStorageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
            File[] listFiles = mediaStorageDir.listFiles();
            Random r = new Random ();
            File randomPicture = listFiles[r.nextInt(listFiles.length)];
            Uri pictureUri = Uri.fromFile(randomPicture);

            BitmapFactory.Options options = new BitmapFactory.Options();

            // Downsizes images. Will throw OutOfMemory Exception for larger images.
            options.inSampleSize = 8;

            bitmap = BitmapFactory.decodeFile(pictureUri.getPath(), options);
            ImageView imgView = (ImageView) findViewById(R.id.imgPreview);

          imgView.setImageBitmap(bitmap);
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }

    /**
     * Creates the file uri to store an image.
     *
     * @param type - Refers to the captured image.
     * @return Uri.fromFile - The file uri to store an image.
     */
    public Uri getOutputMediaFileUri(int type) {
        return Uri.fromFile(getOutputMediaFile(type));
    }


    /**
     * Returns the captured image.
     *
     * @param type - Refers to the captured image.
     * @return null or mediaFile - mediaFile: Captured
     * image inside of timestamped file.
     */
    private static File getOutputMediaFile(int type) {

        // External sdcard location.
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                IMAGE_DIRECTORY_NAME);

        // Create the storage directory if it does not exists
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create " + IMAGE_DIRECTORY_NAME + " directory");
                return null;
            }
        }

        // Creates a media file name corresponding to a timestamp.
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
        } else {
            return null;
        }

        return mediaFile;
    }
   /*
     * Uploads the saved and captured image to the server.
     */

    public class ImageUpload extends AsyncTask<String, String,String> {
        String postUrl = "";

        public void postURL(String url) {

            postUrl = url;
        }

        /**
         * Compresses the selected gallery image and encodes
         * compressed image to a base64 string.
         *
         * @param params
         */
        @Override
        protected String doInBackground(String... params) {
          String result = null;
           try {
                HttpClient client = new DefaultHttpClient();
                String postURL = "";
                HttpPost post = new HttpPost("http://ift.tt/1J0913I");

                ArrayList<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();

               String msg = mEdit.getText().toString();
               nameValuePair.add(new BasicNameValuePair("carid",msg));

                //Converts image file uri to blob base64
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
                byte[] byte_arr = stream.toByteArray();
                String image_str = new String(Base64.encode(byte_arr, Base64.DEFAULT));

                nameValuePair.add(new BasicNameValuePair("carimage", image_str));

                UrlEncodedFormEntity ent = new UrlEncodedFormEntity(nameValuePair, HTTP.UTF_8);
                post.setEntity(ent);
                HttpResponse responsePOST = client.execute(post);
                HttpEntity resEntity = responsePOST.getEntity();
               result = EntityUtils.toString(resEntity);

                if (resEntity != null) {
                    Log.i("RESPONSE", EntityUtils.toString(resEntity));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }

        @Override
        protected void onPostExecute(String result) {
            if (result != null) {
                Toast.makeText(getApplicationContext(),
                        "Successfully uploaded", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getApplicationContext(),
                        "Sorry! Failed to upload", Toast.LENGTH_SHORT).show();
            }
        }

    }
}

I am confused as to why the bitmap is returning null. I appreciate any insight as to why as well as any suggestions of how to improve my current code for my interested goal. Thank you greatly.




Aucun commentaire:

Enregistrer un commentaire