Android设置拍照或者上传本地图片的示例

前几天,我们客户端这边收到了市场部的一个需求,需要在我们订单成交后,我们的客户端有一个上传交易凭证的功能,那么如何在Android实现上传图片的这个功能呢?在我进行编码之前,我先问自己几个问题。

第一, 图片是直接选择图库里的,还是需要拍照和选择图片两个选项?

因为在选择图片的时候,会有一个拍照的按钮,也可以实现拍照的功能。

第二, 需不需要本地缓存?

本地缓存值得是,在我们的图片上传后,是否在下次直接显示,而不是从服务器读取。

第三,图片是否需要压缩?

众所周知,图片这种资源,因为体积较大,在网络上传输还是很慢的,所以,我们需要在我们的传输时,适当的对文件的大小进行压缩,那么就要根据我们自身的需求,按照一定的比例来进行压缩。

在思考完这几个问题后,根据我们自己的需求,我们在上传时有两个选项的,一个是拍照,一个是选择图片,另外我们需要做本地缓存,还有,图片上传不需要压缩。

那么我们就可以开始实现了,首先在我们的主fragment里,添加如下代码,如果你是activity,当然也可以。

做一个ImageView,作为我们上传的图像。

 mPic1 = (ImageView) view.findViewById(R.id.ImageView01);
nbsp;  mPic1.setOnClickListener(mPhotoListener); 

  private View.OnClickListener mPhotoListener = new View.OnClickListener() { 

  @Override
  public void onClick(View v) {
    int id = v.getId();
    if (id == R.id.ImageView01) {
      Intent popupIntent = new Intent(getActivity(), PopupActivity.class);
      mPhotoId = id;
      startActivityForResult(popupIntent, 1);
    }
  }
};

然后,我们跳转到另外一个PopupActivity,让我们选择,
PopupActivity.Java

package com.chuanlaoda.android.activity; 

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date; 

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast; 

import com.chuanloada.android.R; 

public class PopupActivity extends Activity implements OnClickListener {
  private Button btn_take_photo, btn_pick_photo, btn_cancel;
  private LinearLayout layout;
  private Intent intent; 

  private Button showList;
  private Button uploadNow;
  private String mCurrentPhotoPath;
  private Bitmap sourcePic;
  private File dir = null; 

  private String picName = null;
  private String uploadFile = null; 

  static Uri capturedImageUri=null;
  private Bitmap bitmap = null; 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.popup);
    intent = getIntent();
    btn_take_photo = (Button) this.findViewById(R.id.btn_take_photo);
    btn_pick_photo = (Button) this.findViewById(R.id.btn_pick_photo);
    btn_cancel = (Button) this.findViewById(R.id.btn_cancel); 

    layout = (LinearLayout) findViewById(R.id.pop_layout); 

    layout.setOnClickListener(new OnClickListener() { 

      public void onClick(View v) {
        // TODO Auto-generated method stub
        Toast.makeText(getApplicationContext(), "提示:点击空白地方可以关闭",
            Toast.LENGTH_SHORT).show();
      }
    }); 

    btn_cancel.setOnClickListener(this);
    btn_pick_photo.setOnClickListener(this);
    btn_take_photo.setOnClickListener(this);
  } 

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    finish();
    return true;
  } 

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

    if (resultCode != RESULT_OK) {
      return;
    }
    if (data != null) {
      if (data.getExtras() != null)
      {
        bitmap = (Bitmap) data.getExtras().get("data");
        intent.putExtras(data.getExtras());
        intent.putExtra("uri", capturedImageUri);
        intent.putExtra("requestCode", requestCode);
        intent.putExtra("image", bitmap);
      } 

      if (data.getData() != null)
        intent.setData(data.getData());
    }
    setResult(requestCode, intent);
    finish();
  } 

  @Override
  public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_take_photo:
      dispatchTakePictureIntent();
      break;
    case R.id.btn_pick_photo:
      try { 

        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(intent, 2);
      } catch (ActivityNotFoundException e) { 

      }
      break;
    case R.id.btn_cancel:
      finish();
      break;
    default:
      break;
    }
  } 

  private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
      imageFileName, /* prefix */
      ".jpg",     /* suffix */
      storageDir   /* directory */
    ); 

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = "file:" + image.getAbsolutePath();
    return image;
  } 

  private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
      // Create the File where the photo should go
      File photoFile = null;
      try {
        photoFile = createImageFile();
      } catch (IOException ex) {
        // Error occurred while creating the File
      }
      // Continue only if the File was successfully created
      capturedImageUri = Uri.fromFile(photoFile);
      if (photoFile != null) {
        //takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri);
        startActivityForResult(takePictureIntent, 1);
      }
    }
  }
}

Popup.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:gravity="center_horizontal"
  android:orientation="vertical"
 > 

<LinearLayout
  android:id="@+id/pop_layout"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:gravity="center_horizontal"
  android:orientation="vertical"
  android:layout_alignParentBottom="true"
   android:background="@drawable/btn_style_alert_dialog_background"
   > 

  <Button
    android:id="@+id/btn_take_photo"
    android:layout_marginLeft="20dip"
    android:layout_marginRight="20dip"
    android:layout_marginTop="20dip"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="拍照"
    android:background="@drawable/btn_style_alert_dialog_button"
    android:textStyle="bold"
     /> 

  <Button
    android:id="@+id/btn_pick_photo"
    android:layout_marginLeft="20dip"
    android:layout_marginRight="20dip"
    android:layout_marginTop="5dip"
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="从相册选择"
     android:background="@drawable/btn_style_alert_dialog_button"
     android:textStyle="bold"
     /> 

  <Button
    android:id="@+id/btn_cancel"
    android:layout_marginLeft="20dip"
    android:layout_marginRight="20dip"
    android:layout_marginTop="15dip"
    android:layout_marginBottom="15dip"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="取消"
    android:background="@drawable/btn_style_alert_dialog_cancel"
    android:textColor="#ffffff"
    android:textStyle="bold" 

    />
</LinearLayout>
</RelativeLayout>

接下来就是我们需要在我们的主fragment (或者activity)中添加onActivityResult.

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    photo = (ImageView) mView.findViewById(mPhotoId);
    String pfid=String.valueOf(BusinessDetailsFragment.getPosition(mPhotoId) + 1);
    String gsid=String.valueOf(mBusinessId);
    String cur_date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
    switch (resultCode) {
    case 1:
      if (data != null) {
        Uri mImageCaptureUri = (Uri) data.getExtras().get("uri");
        if (mImageCaptureUri != null) {
          Bitmap image;
          try {
            //image = MediaStore.Images.Media.getBitmap(this.getActivity().getContentResolver(), mImageCaptureUri);
            image = (Bitmap) data.getExtras().get("image");
            String fileFullPath = PhotoAPI.savePicsToSdcard(image, mFileLoc);
            PromptUtils.showProgressDialog(getActivity(), "正在上传照片");
            mResult = PhotoAPI.uploadFile(gsid, pfid, fileFullPath);
            Cache.addLastPhotoPath(pfid, fileFullPath);
            Cache.addLastPhotoDate(gsid, cur_date);
            PromptUtils.dismissProgressDialog(); 

            showDialog(mResult);
            if (image != null) {
              photo.setImageBitmap(image);
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        } else {
          Bundle extras = data.getExtras();
          if (extras != null) {
            Bitmap image = extras.getParcelable("data");
            String fileFullPath = PhotoAPI.savePicsToSdcard(image, mFileLoc); 

            PromptUtils.showProgressDialog(getActivity(), "正在上传照片");
            mResult = PhotoAPI.uploadFile(gsid, pfid, fileFullPath);
            PromptUtils.dismissProgressDialog();
            Cache.addLastPhotoPath(pfid, fileFullPath);
            Cache.addLastPhotoDate(gsid, cur_date);
            showDialog(mResult);
            if (image != null) {
              photo.setImageBitmap(image);
            }
          }
        }
      }
      break;
    case 2:
      if (data != null) {
        Uri mImageCaptureUri = data.getData();
        if (mImageCaptureUri != null) {
          Bitmap image;
          try {
            image = MediaStore.Images.Media.getBitmap(this.getActivity().getContentResolver(), mImageCaptureUri);
            String fileFullPath = getRealPathFromURI(this.getActivity(),mImageCaptureUri);
            PromptUtils.showProgressDialog(getActivity(), "正在上传照片");
            mResult = PhotoAPI.uploadFile(gsid, pfid, fileFullPath);
            PromptUtils.dismissProgressDialog();
            Cache.addLastPhotoPath(pfid, fileFullPath);
            Cache.addLastPhotoDate(gsid, cur_date);
            showDialog(mResult);
            if (image != null) {
              photo.setImageBitmap(image);
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        } else {
          Bundle extras = data.getExtras();
          if (extras != null) {
            String fileFullPath = getRealPathFromURI(this.getActivity(),mImageCaptureUri);
            PromptUtils.showProgressDialog(getActivity(), "正在上传照片");
            mResult = PhotoAPI.uploadFile(gsid, pfid, fileFullPath);
            PromptUtils.dismissProgressDialog();
            Cache.addLastPhotoPath(pfid, fileFullPath);
            Cache.addLastPhotoDate(gsid, cur_date);
            Bitmap image = extras.getParcelable("data");
            if (image != null) {
              photo.setImageBitmap(image);
            }
          }
        }
      }
      break;
    default:
      break; 

    }
  }

另外,我们处理图片上传的代码在这里。

class UploadThread extends Thread {
  private String result = "";
  private String actionUrl;
  private String uploadFile; 

  public UploadThread(String gsid, String pfid, String uploadFile) {
    String baseUrl = APIConfig.getAPIHost() + "uploadProof";
    this.actionUrl=baseUrl+"&gsid=" + gsid + "&pfid="+pfid;
    this.uploadFile = uploadFile;
  } 

  @Override
  public void run() {
    String end = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    try { 

      URL url = new URL(actionUrl);
      HttpURLConnection con = (HttpURLConnection) url.openConnection();
      /* 允许Input、Output,不使用Cache */
      con.setDoInput(true);
      con.setDoOutput(true);
      con.setUseCaches(false);
      /* 设置传送的method=POST */
      con.setRequestMethod("POST");
      /* setRequestProperty */
      con.setRequestProperty("Connection", "Keep-Alive");
      con.setRequestProperty("Charset", "UTF-8");
      con.setRequestProperty("Content-Type",
          "multipart/form-data;boundary=" + boundary); 

      /* 设置DataOutputStream */
      DataOutputStream ds = new DataOutputStream(con.getOutputStream());
      ds.writeBytes(twoHyphens + boundary + end);
      ds.writeBytes("Content-Disposition: form-data; "
          + "name=\"GooddShip\";filename=\"" + uploadFile + "\"" + end);
      ds.writeBytes(end); 

      /* 取得文件的FileInputStream */
      FileInputStream fStream = new FileInputStream(uploadFile); 

      /* 设置每次写入1024bytes */
      int bufferSize = 1024;
      byte[] buffer = new byte[bufferSize]; 

      int length = -1;
      /* 从文件读取数据至缓冲区 */
      while ((length = fStream.read(buffer)) != -1) {
        /* 将资料写入DataOutputStream中 */
        ds.write(buffer, 0, length);
      } 

      ds.writeBytes(end);
      ds.writeBytes(twoHyphens + boundary + twoHyphens + end); 

      /* close streams */
      fStream.close();
      ds.flush(); 

      /* 取得Response内容 */
      InputStream is = con.getInputStream();
      int ch;
      StringBuffer b = new StringBuffer();
      while ((ch = is.read()) != -1) {
        b.append((char) ch);
      } 

      /* Parse JSON */
      JSONObject jObject = new JSONObject(b.toString());
      int code = jObject.getInt("Code");
      String error = jObject.getString("Error");
      String msg = jObject.getString("msg"); 

      if (code == 1) {
      /* 将Response显示于Dialog */
        result = "上传成功";
      } else result = "上传失败" + error;
      /* 关闭DataOutputStream */
      ds.close();
    } catch (Exception e) {
      result = "上传失败" + e;
    }
  }

然后就可以了,我们最终的效果如下。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2016-10-31

Android 7.0中拍照和图片裁剪适配的问题详解

前言 Android 7.0系统发布后,拿到能升级的nexus 6P,就开始了7.0的适配.发现在Android 7.0以上,在相机拍照和图片裁剪上,可能会碰到以下一些错误: Process: com.yuyh.imgsel, PID: 22995 // 错误1 android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.yuyh.imgsel/cache/1486438962645.jpg ex

Android中使用Camera类编写手机拍照App的实例教程

Camera是Android摄像头硬件的相机类,位于硬件包"android.hardware.Camera"下.它主要用于摄像头捕获图片.启动/停止预览图片.拍照.获取视频帧等,它是设备本地的服务,负责管理设备上的摄像头硬件. Camera既然用于管理设备上的摄像头硬件,那么它也为开发人员提供了相应的方法,并且这些方法大部分都是native的,用C++在底层实现,下面简单介绍一下Camera的一些方法: static Camera open():打开Camera,返回一个Camera实

Android调用手机拍照功能的方法

本文实例讲述了Android调用手机拍照功能的方法.分享给大家供大家参考.具体如下: 一.main.xml布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" andr

Android开发实现拍照功能的方法实例解析

本文实例讲述了Android开发实现拍照功能的方法.分享给大家供大家参考,具体如下: 解析: 1)判断是否有摄像头checkCameraHardware(this) 2)获得相机camera = Camera.open(0); 3)把相机添加到mPreView = new SurfacePreView(this, mCamera); 4)实现拍照 mCamera.autoFocus 5)在拍照后使用mCamera.takePicture(null, null, mPicture);方法把图片保存

Android手机拍照或选取图库图片作为头像

package zhangpgil.photo; import java.io.File; import android.support.v7.app.ActionBarActivity; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import android.content.Intent; import

Android实现拍照、选择图片并裁剪图片功能

一. 实现拍照.选择图片并裁剪图片效果 按照之前博客的风格,首先看下实现效果. 二. uCrop项目应用 想起之前看到的Yalantis/uCrop效果比较绚,但是研究源码之后发现在定制界面方面还是有一点的限制,于是在它的基础上做了修改Android-Crop,把定制界面独立出来,让用户去自由设置.下图为使用Android-Crop实现的模仿微信选择图片并裁剪Demo. 三. 实现思路 比较简单的选择设备图片裁剪,并将裁剪后的图片保存到指定路径: 调用系统拍照,将拍照图片保存在SD卡,然后裁剪图

Android实现调用系统相册和拍照的Demo示例

本文讲述了Android实现调用系统相册和拍照的Demo示例.分享给大家供大家参考,具体如下: 最近我在群里看到有好几个人在交流说现在网上的一些Android调用系统相册和拍照的demo都有bug,有问题,没有一个完整的.确实是,我记得一个月前,我一同学也遇到了这样的问题,在低版本的系统中没问题,用高于4.4版本的系统就崩溃.所以,我还是想提取出来,给大家整理一下,一个比较完整无bug的demo,让大家收藏,留着以后用. 其实对于调用手机图库,高版本的系统会崩溃,是因为获取方法变了,所以我们应该

android 拍照和上传的实现代码

复制代码 代码如下: import java.io.ByteArrayOutputStream;   import java.io.File;   import android.app.Activity;   import android.content.Intent;   import android.graphics.Bitmap;   import android.net.Uri;   import android.os.Bundle;   import android.os.Enviro

android系统在静音模式下关闭camera拍照声音的方法

话说为了防止偷拍,业内有不成文规定,手机公司在做camera时,点击拍照和录像键的时候,必须要有提示音.因此,google也就非常人性化的将播放拍照声音的函数,放到了cameraService中,防止开发者能开发出不响的camera,从而只要调用拍照函数,一定会响,这是写死在framework中的. 话说这个规定在当今有点不合时宜,这不,今天我收到测试提的一个BUG,说是公司的新需求,要求在静音模式下拍照声音也得取消.这么无耻的需求,也许就在我们中国最大的山寨手机公司才会提到.废话不多说,看看是

Android启动相机拍照并返回图片

具体实现过程请看下面代码: 简单的调用了一下系统的拍照功能 代码如下所示: //拍照的方法 private void openTakePhoto(){ /** * 在启动拍照之前最好先判断一下sdcard是否可用 */ String state = Environment.getExternalStorageState(); //拿到sdcard是否可用的状态码 if (state.equals(Environment.MEDIA_MOUNTED)){ //如果可用 Intent intent

Android拍照得到全尺寸图片并进行压缩

废话不多说了,直接给大家贴代码了,具体代码如下所示: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <

Android 拍照并对照片进行裁剪和压缩实例详解

Android 拍照并对照片进行裁剪和压缩实例详解 本文主要介绍 Android 调用摄像头拍照并对照片进行裁剪和压缩,文中给出了主要步骤和关键代码. 调用摄像头拍照,对拍摄照片进行裁剪,代码如下. /** * 调用摄像头拍照,对拍摄照片进行裁剪 */ private void showCameraAction() { // 跳转到系统照相机 Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (camera

Android拍照和获取相册图片

之前遇到各种拍照啊,获取相册图片之类,都是直接去度娘,要么之前的代码复制下,没好好总结过. 再也不要问度娘了,再也不用一堆博客里找啊找了... ----------------------------------------------我是正文的分割线----------------------------------------------------------- 一个一个来,先说调用手机相机拍照(最简单版): cameraButton.setOnClickListener(new View

Android拍照裁剪图片

下面是效果图,看看是不是亲想要的效果图,如果是,这段代码你就可以参考下了,但是要灵活运用,根据需求做相应的改动. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation

Android实现拍照、选择相册图片并裁剪功能

通过拍照或相册中获取图片,并进行裁剪操作,然后把图片显示到ImageView上.  当然也可以上传到服务器(项目中绝大部分情况是上传到服务器),参考网上资料及结合项目实际情况,  测试了多款手机暂时没有发现严重问题.代码有注释,直接贴代码: public class UploadPicActivity extends Activity implements View.OnClickListener { private Button take_photo_btn; private Button s

Android自定义组件获取本地图片和相机拍照图片

iOS中有封装好的选择图片后长按出现动画删除效果,效果如下 而Android找了很久都没有找到有这样效果的第三方组件,最后懒得找了还是自己实现这效果吧 选择图片后还可对图片进行剪裁 当然,代码中还有很多不完善的地方,我接下来会继续完善这个组件的 已经上传到开源社区,欢迎大家来Star啊~ Demo源码:传送门 设计中的碰到的一些问题和解决思路 1.如何让加号图片显示在GridView最后面 首先在调用GridAdapter构造方法时就加载加号图片 /** * 图片适配器 * @param con

Android 欢迎全屏图片详解及实例代码

Android 欢迎全屏图片详解 其实欢迎界面就是在主Activity之前再添加一个欢迎的Activity.在这个Activity中实现欢迎界面,和其他的Activity用法 是基本一样,只有细微的差别.     1.在Activity的onCreate方法中实现: @Override ic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /**全屏设置,隐藏窗口所有装饰**/ getW

Android 拍照选择图片并上传功能的实现思路(包含权限动态获取)

作为一个Android新手,想实现手机拍照并上传的功能,经过查找资料,已实现此功能.在此记录备忘.老鸟请忽略. 一.实现思路: 1.Android手机客户端,拍照(或选择图片),然后上传到服务器. 2.服务器端接收手机端上传上来的图片. 二.实现步骤: 1.按惯例,先放效果图: 项目结构: 2.activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a

Android中Glide加载图片并实现图片缓存

今天工作中遇到Glide的缓存问题,之前在项目中一直用Glide加载本地及网络图片,但是没有考虑过缓存的问题,但是需求中需要提到了,所以在网上查了一下,再这里和大家简单的分享一下Glide的使用方法以及缓存 首先,Glide是Github上开源的一个图片库,作者是bumptech,所以要使用的话,必须添加依赖: compile 'com.github.bumptech.glide:glide:3.6.1' 加载方式: Glide.with(context) .load("https://ss0.

Android通过ExifInterface判断Camera图片方向的方法

Android的Camera相关应用开发中,有一个必须搞清楚的知识点,就是Camera的预览方向和拍照方向 图像的Sensor方向:手机Camera的图像数据都是来自于摄像头硬件的图像传感器(Image Sensor),这个Sensor被固定到手机之后是有一个默认的取景方向的,这个方向如下图所示,坐标原点位于手机横放时的左上角: android应用里使用相机图片时必须要考虑的一个问题就是图片朝向,只有判断对朝向才能调整图片从而更好的展现.本文将介绍一种通过ExifInterface判断图片朝向的