Webserver部分
|
用phpMyAdmin创建数据中的表photos。用于存放image的路径
|
|
CREATETABLE`a2393827_db`.`photos`(
`id`INTNOTNULLAUTO_INCREMENT,
`image`VARCHAR(300)CHARACTERSETutf8COLLATEutf8_unicode_ciNOTNULL,
PRIMARYKEY(`id`)
)ENGINE= MYISAM
|
Now,inyourservercreateanewdirectory.IcreatedPhotoUpload
Insidethedirectoryyouneedascripttoconnecttoyourdatabase.SocreateascriptnamedbConnect.phpandwritethefollowingcode
现在members.000webhost.com/login的FileManger(web文件管理器)创建用于存放上传图片的目录。PhotoUpload,当然你也可以用其他方法创建,比如ftp工具。
在这个目录里你需要一个脚本去连接数据库。在此创建dbConnect.php脚本。
现在你需要再一个脚本用于处理image的upload。这个文件命名为upload.php
|
完成3个php脚本
|
脚本1:dbConnect.php数据库连接
|
<?php
define('HOST','mysql.hostinger.in');
define('USER','u502452270_andro');
define('PASS','belal_123');
define('DB','u502452270_andro');
$con=mysqli_connect(HOST,USER,PASS,DB)or die('Unable toConnect');
|
脚本2:upload.php
现在你需要再一个脚本用于处理image的upload。这个文件命名为
|
<?php
if($_SERVER['REQUEST_METHOD']=='POST'){
$image=$_POST['image'];
require_once('dbConnect.php');
$sql="SELECTidFROMphotosORDERBYidASC";
$res=mysqli_query($con,$sql);
$id=0;
while($row =mysqli_fetch_array($res)){
$id=$row['id'];
}
$path="uploads/$id.png";
$actualpath="http://zhiguicai.comli.com/PhotoUpload//$path";
$sql="INSERTINTOphotos(image)VALUES('$actualpath')";
if(mysqli_query($con,$sql)){
file_put_contents($path,base64_decode($image));
echo"Successfully Uploaded";
}
mysqli_close($con);
}else{
echo"Error";
}
|
脚本3:getAllImages.php
上面的脚本处理上传。它将存image文件到指定的uploads路径,所有你也需要创建一个目录名为uploads
上面的脚本存储image的文件的路径到mysql数据库
所有我们需要image文件的urls。为了得到这个urls我们采用JSON数据格式。
我们创建第3个脚本getAllImages.php
|
<?php
require_once('dbConnect.php');
$sql="selectimagefromphotos";
$res=mysqli_query($con,$sql);
$result=array();
while($row =mysqli_fetch_array($res)){
array_push($result,array('url'=>$row['image']));
}
echojson_encode(array("result"=>$result));
mysqli_close($con);
|
Nowourserverpartisover.Youcanseebelowthesnapshotofmyserver’sdirectory.
现在我们服务器部分的程序已经完成。如下面的截图
|
测试方法:https://www.youtube.com/watch?v=3tEiiUOLemA&feature=youtu.be
|
用谷歌查询“byte64encoder”
选择如图:
http://www.motobit.com/util/base64-decoder-encoder.asp
可以上传图片,并转化为base64格式数据包
并用网上测试post的工具测试是否可以用(奇怪的是在此生成的图片是空的)http://tool.sufeinet.com/httphelper.aspx?url=http://www.cnblogs.com/hongfei/p/3705089.html&type=url
|
国内在线模拟post:http://www.bejson.com/httputil/httppost2/
http://tool.sufeinet.com/httphelper.aspx?url=http://www.cnblogs.com/hongfei/p/3705089.html&type=url
地址填上:http://zhiguicai.comli.com/PhotoUpload/upload.php
国外在线模拟post:http://www.atool.org/httptest.php
下载chrome浏览器,并为其下载Chrome Poster插件
|
Androidapp客户端
|
创建Androidstuido工程:UploadImageUsingPHPMySQL
|
|
MainActivity布局如上图
|
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"tools:context=".MainActivity">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="选择图片文件"
android:id="@+id/buttonChoose"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/imageView"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="上传图片"
android:id="@+id/buttonUpload"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="查看上传的图片"
android:id="@+id/buttonViewImage"/>
</LinearLayout>
|
创建一个新类RequestHandler处理我们的http请求RequestHandler.java
|
packagecom.czg.com.uploadimageusingphpmysql;
importjava.io.BufferedReader;
importjava.io.BufferedWriter;
importjava.io.InputStreamReader;
importjava.io.OutputStream;
importjava.io.OutputStreamWriter;
importjava.io.UnsupportedEncodingException;
importjava.net.HttpURLConnection;
importjava.net.URL;
importjava.net.URLEncoder;
importjava.util.HashMap;
importjava.util.Map;
importjavax.net.ssl.HttpsURLConnection;
/**
*Createdbyczgon2016/1/12.
*/
publicclassRequestHandler{
publicStringsendPostRequest(StringrequestURL,
HashMap<String,String>postDataParams){
URLurl;
StringBuildersb=newStringBuilder();
try{
url=newURL(requestURL);
HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStreamos=conn.getOutputStream();
BufferedWriterwriter=newBufferedWriter(
newOutputStreamWriter(os,"UTF-8"));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
intresponseCode=conn.getResponseCode();
if(responseCode==HttpsURLConnection.HTTP_OK){
BufferedReaderbr=newBufferedReader(newInputStreamReader(conn.getInputStream()));
sb=newStringBuilder();
Stringresponse;
while((response=br.readLine())!=null){
sb.append(response);
}
}
}catch(Exceptione){
e.printStackTrace();
}
returnsb.toString();
}
privateStringgetPostDataString(HashMap<String,String>params)throwsUnsupportedEncodingException{
StringBuilderresult=newStringBuilder();
booleanfirst=true;
for(Map.Entry<String,String>entry:params.entrySet()){
if(first)
first=false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(),"UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(),"UTF-8"));
}
returnresult.toString();
}
}
|
现在在MainActivity.java写下如下代码,是其完成上传功能
|
packagecom.czg.com.uploadimageusingphpmysql;
importandroid.app.ProgressDialog;
importandroid.content.Intent;
importandroid.graphics.Bitmap;
importandroid.net.Uri;
importandroid.os.AsyncTask;
importandroid.provider.MediaStore;
importandroid.support.v7.app.AppCompatActivity;
importandroid.os.Bundle;
importandroid.util.Base64;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.ImageView;
importandroid.widget.Toast;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.util.HashMap;
publicclassMainActivityextendsAppCompatActivityimplementsView.OnClickListener{
publicstaticfinalStringUPLOAD_URL="http://zhiguicai.comli.com/PhotoUpload/upload.php";
publicstaticfinalStringUPLOAD_KEY="image";
privateintPICK_IMAGE_REQUEST=1;
privateButtonbuttonChoose;
privateButtonbuttonUpload;
privateButtonbuttonView;
privateImageViewimageView;
privateBitmapbitmap;
privateUrifilePath;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonChoose=(Button)findViewById(R.id.buttonChoose);
buttonUpload=(Button)findViewById(R.id.buttonUpload);
buttonView=(Button)findViewById(R.id.buttonViewImage);
imageView=(ImageView)findViewById(R.id.imageView);
buttonChoose.setOnClickListener(this);
buttonUpload.setOnClickListener(this);
buttonView.setOnClickListener(this);
}
//在相册中选择图片
privatevoidshowFileChooser(){
Intentintent=newIntent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"SelectPicture"),PICK_IMAGE_REQUEST);
}
//图片选择后响应(根据选择的路径)
@Override
protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
super.onActivityResult(requestCode,resultCode,data);
if(requestCode==PICK_IMAGE_REQUEST&&resultCode==RESULT_OK&&data!=null&&data.getData()!=null){
filePath=data.getData();
try{
bitmap=MediaStore.Images.Media.getBitmap(getContentResolver(),filePath);
imageView.setImageBitmap(bitmap);
}catch(IOExceptione){
e.printStackTrace();
}
}
}
//图片转化为Base64格式的字符串
publicStringgetStringImage(Bitmapbmp){
ByteArrayOutputStreambaos=newByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG,100,baos);
byte[]imageBytes=baos.toByteArray();
StringencodedImage=Base64.encodeToString(imageBytes,Base64.DEFAULT);
returnencodedImage;
}
//上传图片
privatevoiduploadImage(){
classUploadImageextendsAsyncTask<Bitmap,Void,String>{
ProgressDialogloading;
RequestHandlerrh=newRequestHandler();
@Override
protectedvoidonPreExecute(){
super.onPreExecute();
loading=ProgressDialog.show(MainActivity.this,"请耐心等候,图片Uploading...",null,true,true);
}
@Override
protectedvoidonPostExecute(Strings){
super.onPostExecute(s);
loading.dismiss();
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
}
@Override
protectedStringdoInBackground(Bitmap...params){
Bitmapbitmap=params[0];
StringuploadImage=getStringImage(bitmap);//图片转化为byte64格式字符串
HashMap<String,String>data=newHashMap<>();
data.put(UPLOAD_KEY,uploadImage);//填入postkey,及数据(即图片信息)
Stringresult=rh.sendPostRequest(UPLOAD_URL,data);
returnresult;
}
}
UploadImageui=newUploadImage();
ui.execute(bitmap);
}
@Override
publicvoidonClick(Viewv){
if(v==buttonChoose){
showFileChooser();
}
if(v==buttonUpload){
uploadImage();
}
if(v==buttonView){
viewImage();
}
}
privatevoidviewImage(){
//startActivity(newIntent(this,ImageListView.class));
}
}
|
到这里你程序基本上实现了上传的功能,不过不要忘记在androidManifest.xml中添加app的上网权限。
<uses-permissionandroid:name="android.permission.INTERNET"/>
加完权限代码,你可以测试运行app是否可以上传文件
我亲测上传成功(问题小的图片可以上传,大的图片无法上传。不知是什么问题。具体原因是文件大小受到byte64的影响。只能等下次再找找问题。或转变一中图片上传方式。)
|
|
Nowtheletsmovetothenextpartwhichisdownloadinguploadedimages.
下面将进入下一个阶段---下载已经上传的图片
|
在一个ListView控件中显示已经上传的图片在此你必须通过前一阶段的app上传一些图片到web服务器上。因为我们马上要去下载这些已经上传上去的图片。如果你有100s or1000simages打算显示在ListView中。你不要继续后面的代码。而应该用list的效果。应该看点击查看其它教程。
Android AddingItemstoListonScroll
|
n把// startActivity(newIntent(this,ImageListView.class));的注释取消,这是会产生一个错误。我们需要创建一个新的Activity
n创建一个blank activity(ImageListView)
n现在我们将点击“查看上传图片”按钮,这个Activity将被打开
n这这个activity我们放置一个ListView。(我们进入activity_image_list_view.xml)代码如下
|
|
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="net.simplifiedcoding.imageuploadsample.ImageListView">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/listView"/>
</LinearLayout>
|
n我们必须创建一个自定义ListView。我们新建一个xml资源文件给自定义ListView。
n在此新建xml资源文件image_list_view.xml
|
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageViewandroid:id="@+id/imageDownloaded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/abc_ic_menu_copy_mtrl_am_alpha"/>
<TextViewandroid:id="@+id/textViewURL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
|
NowcreateanewclassnamedCustomListforourCustom ListView.
下面为显示自定义List创建一个新类。CustomListextendsArrayAdapter
|
packagecom.czg.com.uploadimageusingphpmysql;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.graphics.Bitmap;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.ArrayAdapter;
importandroid.widget.ImageView;
importandroid.widget.TextView;
/**
*Createdbyczgon2016/1/13.
*/
publicclassCustomListextendsArrayAdapter<String>{
privateString[]urls;
privateBitmap[]bitmaps;
privateActivitycontext;
publicCustomList(Activitycontext,String[]urls,Bitmap[]bitmaps){
super(context,R.layout.image_list_view,urls);
this.context=context;
this.urls=urls;
this.bitmaps=bitmaps;
}
@Override
publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
LayoutInflaterinflater=context.getLayoutInflater();
ViewlistViewItem=inflater.inflate(R.layout.image_list_view,null,true);
TextViewtextViewURL=(TextView)listViewItem.findViewById(R.id.textViewURL);
ImageViewimage=(ImageView)listViewItem.findViewById(R.id.imageDownloaded);
textViewURL.setText(urls[position]);
image.setImageBitmap(Bitmap.createScaledBitmap(bitmaps[position],100,50,false));
returnlistViewItem;
}
}
|
NowweneedtofetchalltheBitmapsfromserver.Soforthiswewillcreateanewclass.IcreatedGetAlImages.java
下面我们需要从webserver上获取所有已经上传的Bitmaps图片。所有我们需要创建一个新类用于获取图片GetAlImages.java
|
packagecom.czg.com.uploadimageusingphpmysql;
importandroid.app.ProgressDialog;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.os.AsyncTask;
importorg.json.JSONArray;
importorg.json.JSONException;
importorg.json.JSONObject;
importjava.io.IOException;
importjava.net.MalformedURLException;
importjava.net.URL;
/**
*Createdbyczgon2016/1/13.
*/
publicclassGetAlImages{
publicstaticString[]imageURLs;
publicstaticBitmap[]bitmaps;
publicstaticfinalStringJSON_ARRAY="result";
publicstaticfinalStringIMAGE_URL="url";
privateStringjson;
privateJSONArrayurls;
publicGetAlImages(Stringjson){
this.json=json;
try{
JSONObjectjsonObject=newJSONObject(json);
urls=jsonObject.getJSONArray(JSON_ARRAY);
}catch(JSONExceptione){
e.printStackTrace();
}
}
privateBitmapgetImage(JSONObjectjo){
URLurl=null;
Bitmapimage=null;
try{
url=newURL(jo.getString(IMAGE_URL));
image=BitmapFactory.decodeStream(url.openConnection().getInputStream());
}catch(MalformedURLExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(JSONExceptione){
e.printStackTrace();
}
returnimage;
}
publicvoidgetAllImages()throwsJSONException{
bitmaps=newBitmap[urls.length()];
imageURLs=newString[urls.length()];
for(inti=0;i<urls.length();i++){
imageURLs[i]=urls.getJSONObject(i).getString(IMAGE_URL);
JSONObjectjsonObject=urls.getJSONObject(i);
bitmaps[i]=getImage(jsonObject);
}
}
}
|
Wewillpassthejsonstringhavingalltheurlsofourimagestotheconstructorofthisclass.
WewillgetthejsonstringhavingalltheurlsfromourgetAllImages.phpscript.
NowcometoImageListView.javaclassandwritethefollowingcode
n我们将在这构造函数传入json字符串。
n并解析这个Json数据是由getAllImages.php脚本返回。可以用浏览器测试如下
n现在我们进入ImageListView.java代码并写下如下代码。
|
packagecom.czg.com.uploadimageusingphpmysql;
importandroid.app.ProgressDialog;
importandroid.content.Intent;
importandroid.os.AsyncTask;
importandroid.support.v7.app.AppCompatActivity;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.widget.AdapterView;
importandroid.widget.ListView;
importorg.json.JSONException;
importjava.io.BufferedReader;
importjava.io.InputStreamReader;
importjava.net.HttpURLConnection;
importjava.net.URL;
publicclassImageListViewextendsAppCompatActivityimplementsAdapterView.OnItemClickListener{
privateListViewlistView;
publicstaticfinalStringGET_IMAGE_URL="http://zhiguicai.comli.com/PhotoUpload/getAllImages.php";
publicGetAlImagesgetAlImages;
publicstaticfinalStringBITMAP_ID="BITMAP_ID";
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_list_view);
listView=(ListView)findViewById(R.id.listView);
listView.setOnItemClickListener(this);
getURLs();
}
privatevoidgetImages(){
classGetImagesextendsAsyncTask<Void,Void,Void>{
ProgressDialogloading;
@Override
protectedvoidonPreExecute(){
super.onPreExecute();
loading=ProgressDialog.show(ImageListView.this,"正在下载图片。。。","请稍等片刻...",false,false);
}
@Override
protectedvoidonPostExecute(Voidv){
super.onPostExecute(v);
loading.dismiss();
//Toast.makeText(ImageListView.this,"Success",Toast.LENGTH_LONG).show();
CustomListcustomList=newCustomList(ImageListView.this,GetAlImages.imageURLs,GetAlImages.bitmaps);
listView.setAdapter(customList);
}
@Override
protectedVoiddoInBackground(Void...voids){
try{
getAlImages.getAllImages();
}catch(JSONExceptione){
e.printStackTrace();
}
returnnull;
}
}
GetImagesgetImages=newGetImages();
getImages.execute();
}
privatevoidgetURLs(){
classGetURLsextendsAsyncTask<String,Void,String>{
ProgressDialogloading;
@Override
protectedvoidonPreExecute(){
super.onPreExecute();
loading=ProgressDialog.show(ImageListView.this,"下载中...","请等待...",true,true);
}
@Override
protectedvoidonPostExecute(Strings){
super.onPostExecute(s);
loading.dismiss();
getAlImages=newGetAlImages(s);
getImages();
}
@Override
protectedStringdoInBackground(String...strings){
BufferedReaderbufferedReader=null;
try{
URLurl=newURL(strings[0]);
HttpURLConnectioncon=(HttpURLConnection)url.openConnection();
StringBuildersb=newStringBuilder();
bufferedReader=newBufferedReader(newInputStreamReader(con.getInputStream()));
Stringjson;
while((json=bufferedReader.readLine())!=null){
sb.append(json+"\n");
}
returnsb.toString().trim();
}catch(Exceptione){
returnnull;
}
}
}
GetURLsgu=newGetURLs();
gu.execute(GET_IMAGE_URL);
}
@Override
publicvoidonItemClick(AdapterView<?>parent,Viewview,intposition,longid){
Intentintent=newIntent(this,ViewFullImage.class);
intent.putExtra(BITMAP_ID,position);
startActivity(intent);
}
}
|
到这一步代码会报错,(因为我们还没有创建ViewFullImage类)
|
现在我们创建一个新的activity用于全屏显示图片。新建ViewFullImage。我们在这个视图上添加一个ImageView用于显示图片。
|
|
Xml布局文件如下(activity_view_full_image.xml)
|
<?xmlversion="1.0"encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"
android:layout_height="match_parent"android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="net.simplifiedcoding.imageuploadsample.ViewFullImage">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/imageViewFull"
/>
</RelativeLayout>
|
ViewFullImage类代码如下:ViewFullImage.java
|
packagecom.czg.com.uploadimageusingphpmysql;
importandroid.content.Intent;
importandroid.support.v7.app.AppCompatActivity;
importandroid.os.Bundle;
importandroid.widget.ImageView;
publicclassViewFullImageextendsAppCompatActivity{
privateImageViewimageView;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_full_image);
Intentintent=getIntent();
inti=intent.getIntExtra(ImageListView.BITMAP_ID,0);
imageView=(ImageView)findViewById(R.id.imageViewFull);
imageView.setImageBitmap(GetAlImages.bitmaps[i]);
}
}
|
现在所有工作已经完成,你运行测试你的代码
|
|
源码下载:https://yunpan.cn/crxSdtRknEtFt访问密码0ef7
|