android开发之用户头像上传

时间:2022-01-08 04:41:16

一,概述

本篇博客总结一下自己在开发过程中应用到的一些知识,在本篇博客中带领大家完成用户头像选择或者拍照上传,并对图片进行大小的压缩,和形状的控制,可以将用户选择到的图片裁剪成圆形上传。

ok,我们开始写一个小的demo,完成用户圆形头像的选取,在写即将实现的效果之前我们看一下即将要实现的效果图

android开发之用户头像上传

二,实现代码

activity_main.xml

<code class="language-xml hljs  has-numbering"><span class="hljs-tag"><<span class="hljs-title">LinearLayout</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span>
    <span class="hljs-attribute">xmlns:tools</span>=<span class="hljs-value">"http://schemas.android.com/tools"</span>
    <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
    <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>
    <span class="hljs-attribute">android:gravity</span>=<span class="hljs-value">"center_horizontal"</span>
    <span class="hljs-attribute">android:orientation</span>=<span class="hljs-value">"vertical"</span> ></span>

    <span class="hljs-tag"><<span class="hljs-title">RelativeLayout
</span>        <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
        <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span>
        <span class="hljs-attribute">android:background</span>=<span class="hljs-value">"#51CA65"</span>
        <span class="hljs-attribute">android:padding</span>=<span class="hljs-value">"30dp"</span> ></span>

        <span class="hljs-tag"><<span class="hljs-title">ImageView
</span>            <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/iv_personal_icon"</span>
            <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span>
            <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span>
            <span class="hljs-attribute">android:layout_centerInParent</span>=<span class="hljs-value">"true"</span>
            <span class="hljs-attribute">android:src</span>=<span class="hljs-value">"@drawable/default_personal_image"</span> /></span>
    <span class="hljs-tag"></<span class="hljs-title">RelativeLayout</span>></span>

    <span class="hljs-tag"><<span class="hljs-title">Button
</span>        <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/btn_change"</span>
        <span class="hljs-attribute">android:layout_marginTop</span>=<span class="hljs-value">"6dp"</span>
        <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span>
        <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span>
        <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"修改头像"</span> ></span>
    <span class="hljs-tag"></<span class="hljs-title">Button</span>></span>

<span class="hljs-tag"></<span class="hljs-title">LinearLayout</span>></span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>

MainActivity.java

<code class="language-java hljs  has-numbering"><span class="hljs-keyword">package</span> com.example.uploadpicdemo;

<span class="hljs-keyword">import</span> java.io.File;

<span class="hljs-keyword">import</span> android.app.Activity;
<span class="hljs-keyword">import</span> android.app.AlertDialog;
<span class="hljs-keyword">import</span> android.content.DialogInterface;
<span class="hljs-keyword">import</span> android.content.Intent;
<span class="hljs-keyword">import</span> android.graphics.Bitmap;
<span class="hljs-keyword">import</span> android.net.Uri;
<span class="hljs-keyword">import</span> android.os.Bundle;
<span class="hljs-keyword">import</span> android.os.Environment;
<span class="hljs-keyword">import</span> android.provider.MediaStore;
<span class="hljs-keyword">import</span> android.util.Log;
<span class="hljs-keyword">import</span> android.view.View;
<span class="hljs-keyword">import</span> android.view.View.OnClickListener;
<span class="hljs-keyword">import</span> android.widget.Button;
<span class="hljs-keyword">import</span> android.widget.ImageView;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Activity</span> {</span>

    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> CHOOSE_PICTURE = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> TAKE_PICTURE = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> CROP_SMALL_PICTURE = <span class="hljs-number">2</span>;
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">static</span> Uri tempUri;
    <span class="hljs-keyword">private</span> ImageView iv_personal_icon;

    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) {
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_change = (Button) findViewById(R.id.btn_change);
        iv_personal_icon = (ImageView) findViewById(R.id.iv_personal_icon);
        btn_change.setOnClickListener(<span class="hljs-keyword">new</span> OnClickListener() {

            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onClick</span>(View v) {
                showChoosePicDialog();
            }
        });
    }

    <span class="hljs-javadoc">/**
     * 显示修改头像的对话框
     */</span>
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showChoosePicDialog</span>() {
        AlertDialog.Builder builder = <span class="hljs-keyword">new</span> AlertDialog.Builder(<span class="hljs-keyword">this</span>);
        builder.setTitle(<span class="hljs-string">"设置头像"</span>);
        String[] items = { <span class="hljs-string">"选择本地照片"</span>, <span class="hljs-string">"拍照"</span> };
        builder.setNegativeButton(<span class="hljs-string">"取消"</span>, <span class="hljs-keyword">null</span>);
        builder.setItems(items, <span class="hljs-keyword">new</span> DialogInterface.OnClickListener() {

            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onClick</span>(DialogInterface dialog, <span class="hljs-keyword">int</span> which) {
                <span class="hljs-keyword">switch</span> (which) {
                <span class="hljs-keyword">case</span> CHOOSE_PICTURE: <span class="hljs-comment">// 选择本地照片</span>
                    Intent openAlbumIntent = <span class="hljs-keyword">new</span> Intent(
                            Intent.ACTION_GET_CONTENT);
                    openAlbumIntent.setType(<span class="hljs-string">"image/*"</span>);
                    startActivityForResult(openAlbumIntent, CHOOSE_PICTURE);
                    <span class="hljs-keyword">break</span>;
                <span class="hljs-keyword">case</span> TAKE_PICTURE: <span class="hljs-comment">// 拍照</span>
                    Intent openCameraIntent = <span class="hljs-keyword">new</span> Intent(
                            MediaStore.ACTION_IMAGE_CAPTURE);
                    tempUri = Uri.fromFile(<span class="hljs-keyword">new</span> File(Environment
                            .getExternalStorageDirectory(), <span class="hljs-string">"image.jpg"</span>));
                    <span class="hljs-comment">// 指定照片保存路径(SD卡),image.jpg为一个临时文件,每次拍照后这个图片都会被替换</span>
                    openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
                    startActivityForResult(openCameraIntent, TAKE_PICTURE);
                    <span class="hljs-keyword">break</span>;
                }
            }
        });
        builder.create().show();
    }

    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onActivityResult</span>(<span class="hljs-keyword">int</span> requestCode, <span class="hljs-keyword">int</span> resultCode, Intent data) {
        <span class="hljs-keyword">super</span>.onActivityResult(requestCode, resultCode, data);
        <span class="hljs-keyword">if</span> (resultCode == RESULT_OK) { <span class="hljs-comment">// 如果返回码是可以用的</span>
            <span class="hljs-keyword">switch</span> (requestCode) {
            <span class="hljs-keyword">case</span> TAKE_PICTURE:
                startPhotoZoom(tempUri); <span class="hljs-comment">// 开始对图片进行裁剪处理</span>
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> CHOOSE_PICTURE:
                startPhotoZoom(data.getData()); <span class="hljs-comment">// 开始对图片进行裁剪处理</span>
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> CROP_SMALL_PICTURE:
                <span class="hljs-keyword">if</span> (data != <span class="hljs-keyword">null</span>) {
                    setImageToView(data); <span class="hljs-comment">// 让刚才选择裁剪得到的图片显示在界面上</span>
                }
                <span class="hljs-keyword">break</span>;
            }
        }
    }

    <span class="hljs-javadoc">/**
     * 裁剪图片方法实现
     * 
     *<span class="hljs-javadoctag"> @param</span> uri
     */</span>
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startPhotoZoom</span>(Uri uri) {
        <span class="hljs-keyword">if</span> (uri == <span class="hljs-keyword">null</span>) {
            Log.i(<span class="hljs-string">"tag"</span>, <span class="hljs-string">"The uri is not exist."</span>);
        }
        tempUri = uri;
        Intent intent = <span class="hljs-keyword">new</span> Intent(<span class="hljs-string">"com.android.camera.action.CROP"</span>);
        intent.setDataAndType(uri, <span class="hljs-string">"image/*"</span>);
        <span class="hljs-comment">// 设置裁剪</span>
        intent.putExtra(<span class="hljs-string">"crop"</span>, <span class="hljs-string">"true"</span>);
        <span class="hljs-comment">// aspectX aspectY 是宽高的比例</span>
        intent.putExtra(<span class="hljs-string">"aspectX"</span>, <span class="hljs-number">1</span>);
        intent.putExtra(<span class="hljs-string">"aspectY"</span>, <span class="hljs-number">1</span>);
        <span class="hljs-comment">// outputX outputY 是裁剪图片宽高</span>
        intent.putExtra(<span class="hljs-string">"outputX"</span>, <span class="hljs-number">150</span>);
        intent.putExtra(<span class="hljs-string">"outputY"</span>, <span class="hljs-number">150</span>);
        intent.putExtra(<span class="hljs-string">"return-data"</span>, <span class="hljs-keyword">true</span>);
        startActivityForResult(intent, CROP_SMALL_PICTURE);
    }

    <span class="hljs-javadoc">/**
     * 保存裁剪之后的图片数据
     * 
     *<span class="hljs-javadoctag"> @param</span>
     * 
     *<span class="hljs-javadoctag"> @param</span> picdata
     */</span>
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setImageToView</span>(Intent data) {
        Bundle extras = data.getExtras();
        <span class="hljs-keyword">if</span> (extras != <span class="hljs-keyword">null</span>) {
            Bitmap photo = extras.getParcelable(<span class="hljs-string">"data"</span>);
            photo = Utils.toRoundBitmap(photo, tempUri); <span class="hljs-comment">// 这个时候的图片已经被处理成圆形的了</span>
            iv_personal_icon.setImageBitmap(photo);
            uploadPic(photo);
        }
    }

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">uploadPic</span>(Bitmap bitmap) {
        <span class="hljs-comment">// 上传至服务器</span>
        <span class="hljs-comment">// ... 可以在这里把Bitmap转换成file,然后得到file的url,做文件上传操作</span>
        <span class="hljs-comment">// 注意这里得到的图片已经是圆形图片了</span>
        <span class="hljs-comment">// bitmap是没有做个圆形处理的,但已经被裁剪了</span>

        String imagePath = Utils.savePhoto(bitmap, Environment
                .getExternalStorageDirectory().getAbsolutePath(), String
                .valueOf(System.currentTimeMillis()));
        Log.e(<span class="hljs-string">"imagePath"</span>, imagePath+<span class="hljs-string">""</span>);
        <span class="hljs-keyword">if</span>(imagePath != <span class="hljs-keyword">null</span>){
            <span class="hljs-comment">// 拿着imagePath上传了</span>
            <span class="hljs-comment">// ...</span>
        }
    }
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li><li>102</li><li>103</li><li>104</li><li>105</li><li>106</li><li>107</li><li>108</li><li>109</li><li>110</li><li>111</li><li>112</li><li>113</li><li>114</li><li>115</li><li>116</li><li>117</li><li>118</li><li>119</li><li>120</li><li>121</li><li>122</li><li>123</li><li>124</li><li>125</li><li>126</li><li>127</li><li>128</li><li>129</li><li>130</li><li>131</li><li>132</li><li>133</li><li>134</li><li>135</li><li>136</li><li>137</li><li>138</li><li>139</li><li>140</li><li>141</li><li>142</li><li>143</li><li>144</li><li>145</li><li>146</li><li>147</li><li>148</li><li>149</li><li>150</li><li>151</li><li>152</li><li>153</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>

ok,大功告成,最后别忘了在清单文件中添加读写sd可权限,不然得不到imagePath

<code class="language-xml hljs  has-numbering"><span class="hljs-tag"><<span class="hljs-title">uses-permission</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"android.permission.WRITE_EXTERNAL_STORAGE"</span> /></span></code><ul class="pre-numbering"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>

关于上面的隐示intent如果有什么不懂的可以参考

http://blog.csdn.net/ydxlt/article/details/47983661

关于startActivityForResult启动activity返回结果,在一个activity需要启动另外一个Activity得到数据的时候,我们可以通过意图启动那个Activity返回数据,然后重写Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法,在里面根据我们启动的时候传入的请求码(requestCode)判断是启动的哪个Activity返回了,然后在从data参数中取得返回的数据信息,在此之前我们得判断一下启动作为结果返回的Activity的状态,也就是判断一下resultCode是运行的时候被取消了还是运行正常,还是其他情况(RESULT_FIRST_USER),如果resultCode返回RESULT_OK表示用户在启动的Activity中选择了数据,这个时候我们可以从data中去掉相应的信息了,如果resultCode返回RESULT_CANCELED者没必要处理数据了因为用户没在启动的activity中做任何操作就返回了

在一个activity中可以多次通过startActivityForResult启动其他Activity得到数据。

demo下载地址:http://download.csdn.net/detail/ydxlt/9053973