随机图片到服务器

Random image to server

我是 Android 开发的新手。我创建了我的第一个应用程序,它是一个能够捕捉图像、向用户查询与图像相关的汽车 ID、预览捕捉到的图像并将该图像上传到服务器的相机。

我有兴趣从捕获的图像目录中将随机图像发送到服务器,但不知道目录中的哪个图像被发送出去了。我不希望用户能够选择要发送到服务器的图像,例如通过图库选择。另外,我不想向服务器发送多张图片——只是一张随机的、未知的、非用户选择的图片包含在捕获的图片目录中。

我在这个网站以及许多其他教育网站上做了很多研究。我注意到 Android 的内置随机 class 会有很大用处。

经过更深入的研究,我编写了一些额外的代码来扩展原始相机应用程序代码。但是,位图返回空值。我记录了位图周围的一堆关键部分以试图了解原因,但我没有看到问题。

我很感激任何关于为什么会发生这种情况的见解,以及我是否似乎在正确的轨道上使用我感兴趣的功能。我很乐意听到您认为合适的其他方法来改进我的应用程序。非常感谢!

这是我的代码:

 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 = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                    IMAGE_DIRECTORY_NAME);
            Log.v("Directory", mediaStorageDir.toString());

            mediaStorageDir.listFiles(new FileFilter() {
                public boolean accept(File file) {
                    return !file.isDirectory();
                }
            });
            File[] listFiles = mediaStorageDir.listFiles();
            Log.v("File listFiles", listFiles.toString());

            Random r = new Random ();
            Log.v("Random r", r.toString());

            File randomPicture = listFiles[r.nextInt(listFiles.length)];
            Log.v("Random Picture File", randomPicture.toString());

            Uri fileUri = Uri.fromFile(randomPicture);
            Log.v("fileUri", fileUri.toString());

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

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

            Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(), options);
            Log.v("Bitmap", bitmap.toString());
*/

            inspect(fileUri);
            private void inspect(Uri fileUri)
            {
                InputStream is = null;
                try {
                    is = getContentResolver().openInputStream(fileUri);
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                    //options.inSampleSize = 2;
                    //options.inScreenDensity = DisplayMetrics.DENSITY_LOW;
                    bitmap = BitmapFactory.decodeStream(is, null, options);//member variable bitmap
                } catch (FileNotFoundException e)
                {
                    e.printStackTrace();
                } finally
                {
                    if (is != null)
                    {
                        try
                        {
                            is.close();
                        } catch (IOException e)
                        {
                            //nothing
                        }
                    }
                }
            }//inspect


            ImageView imgView = (ImageView) findViewById(R.id.imgPreview);
            Log.v("ImgView", imgView.toString());

            imgView.setImageBitmap(BitmapFactory.decodeFile(fileUri.getPath()));
        } 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);
        Log.v("Directory Two", mediaStorageDir.toString());

        // 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;
        }
        Log.v("MediaFile", mediaFile.toString());
        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://192.168.80.113/files/justine/image_save.php");

                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();
               Log.v("ByteArray Stream", stream.toString());
               Log.v("byte from stream", byte_arr.toString());
                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();
            }
        }

    }
}

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.justin.myapplication" >
        android:versionCode="1"
        android:versionName="1.0" >

        <uses-sdk
            android:minSdkVersion="11"
            android:targetSdkVersion="22" />

    <supports-screens
        android:largeScreens="true"
        android:normalScreens="true"
        android:smallScreens="true"
        android:anyDensity="true">
    </supports-screens>


    <!-- Accessing camera hardware -->
    <uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.screen.portrait" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

        <application
            android:allowBackup="true"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".MainActivity"
                android:label="@string/app_name"
                android:configChanges="orientation|keyboard|keyboardHidden"
                android:screenOrientation="portrait">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>

    </manifest>

Logcat:

07-15 16:07:36.531  22150-22150/com.example.justin.myapplication D/dalvikvm﹕ Late-enabling CheckJNI
07-15 16:07:36.664  22150-22150/com.example.justin.myapplication D/libEGL﹕ loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
07-15 16:07:36.664  22150-22150/com.example.justin.myapplication D/libEGL﹕ loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
07-15 16:07:36.672  22150-22150/com.example.justin.myapplication D/libEGL﹕ loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
07-15 16:07:36.742  22150-22150/com.example.justin.myapplication D/OpenGLRenderer﹕ Enabling debug mode 0
07-15 16:07:43.961  22150-22150/com.example.justin.myapplication V/EditText﹕ 5
07-15 16:07:45.781  22150-22150/com.example.justin.myapplication V/Directory Two﹕ /storage/emulated/0/Pictures/Hello Camera
07-15 16:07:45.789  22150-22150/com.example.justin.myapplication V/MediaFile﹕ /storage/emulated/0/Pictures/Hello Camera/IMG_20150715_160745.jpg
07-15 16:07:46.484  22150-22150/com.example.justin.myapplication W/IInputConnectionWrapper﹕ showStatusIcon on inactive InputConnection
07-15 16:07:52.859  22150-22150/com.example.justin.myapplication V/Directory﹕ /storage/emulated/0/Pictures/Hello Camera
07-15 16:07:52.906  22150-22150/com.example.justin.myapplication V/File listFiles﹕ [Ljava.io.File;@4276b448
07-15 16:07:52.906  22150-22150/com.example.justin.myapplication V/Random r﹕ java.util.Random@42777f30
07-15 16:07:52.906  22150-22150/com.example.justin.myapplication V/Random Picture File﹕ /storage/emulated/0/Pictures/Hello Camera/IMG_20150710_160840.jpg
07-15 16:07:52.906  22150-22150/com.example.justin.myapplication V/fileUri﹕ file:///storage/emulated/0/Pictures/Hello%20Camera/IMG_20150710_160840.jpg
07-15 16:07:52.937  22150-22150/com.example.justin.myapplication D/dalvikvm﹕ GC_FOR_ALLOC freed 187K, 3% free 8776K/9000K, paused 14ms, total 15ms
07-15 16:07:53.242  22150-22150/com.example.justin.myapplication V/Bitmap﹕ android.graphics.Bitmap@42754638
07-15 16:07:53.242  22150-22150/com.example.justin.myapplication V/ImgView﹕ android.widget.ImageView{42747f90 V.ED.... ......I. 0,0-0,0 #7f0c0051 app:id/imgPreview}
07-15 16:07:53.265  22150-22150/com.example.justin.myapplication D/dalvikvm﹕ GC_FOR_ALLOC freed 38K, 3% free 9080K/9308K, paused 14ms, total 14ms
07-15 16:07:53.359  22150-22150/com.example.justin.myapplication I/dalvikvm-heap﹕ Grow heap (frag case) to 28.113MB for 20155408-byte allocation
07-15 16:07:53.383  22150-22159/com.example.justin.myapplication D/dalvikvm﹕ GC_FOR_ALLOC freed <1K, 1% free 28763K/28992K, paused 19ms, total 19ms
07-15 16:07:53.398  22150-22153/com.example.justin.myapplication D/dalvikvm﹕ GC_CONCURRENT freed <1K, 1% free 28763K/28992K, paused 3ms+2ms, total 20ms

替换此代码:

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

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

        Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(), options);

用这个:

检查(fileUri);

并添加此方法:

  /** 
        private void inspect(Uri uri) 
   */
  private void inspect(Uri uri) 
  {
    InputStream is = null;
    try {
      is = getContentResolver().openInputStream(uri);
      Options options = new BitmapFactory.Options();
      options.inPreferredConfig = Bitmap.Config.ARGB_8888;
//      options.inSampleSize = 2;
//      options.inScreenDensity = DisplayMetrics.DENSITY_LOW;
     bitmap = BitmapFactory.decodeStream(is, null, options);//member variable bitmap
    } catch (FileNotFoundException e) 
    {
      e.printStackTrace();
    } finally 
    {
      if (is != null) 
      {
        try 
        {
          is.close();
        } catch (IOException e)
        {
            //nowt ?
        }
      }
    }
  }//inspect

你原来的技术是这样完成的

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

// Downsizes images. Will throw OutOfMemory Exception for larger images.
                            options.inSampleSize = 8;
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;//you missed this
    Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(), options);