Android——從本地相簿上傳圖片至伺服器
android實現本地圖片上傳至服務端,只需幾步操作即可實現,下面一起看看。
首先看下效果:
主要程式碼:
package com.kevin.imageuploadclient.fragment;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.kevin.imageuploadclient.R;
import com.kevin.imageuploadclient.fragment.basic.PictureSelectFragment;
import com.kevin.imageuploadclient.util.Constant;
import java.io.File;
import butterknife.Bind;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* 圖片上傳
*/
public class MainFragment extends PictureSelectFragment {
/** Toolbar */
@Bind(R.id.toolbar)
Toolbar toolbar;
@Bind(R.id.main_frag_picture_iv)
ImageView mPictureIv;
public static MainFragment newInstance() {
return new MainFragment();
}
@Override
protected int getContentViewId() {
return R.layout.fragment_main;
}
@Override
public void initViews(View view) {
initToolbar(toolbar);
}
@Override
public void initEvents() {
// 設定圖片點選監聽
mPictureIv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectPicture();
}
});
// 設定裁剪圖片結果監聽
setOnPictureSelectedListener(new OnPictureSelectedListener() {
@Override
public void onPictureSelected(Uri fileUri, Bitmap bitmap) {
// mPictureIv.setImageBitmap(bitmap);
String filePath = fileUri.getEncodedPath();
final String imagePath = Uri.decode(filePath);
uploadImage(imagePath);
}
});
}
/**
* 上傳圖片
* @param imagePath
*/
private void uploadImage(String imagePath) {
new NetworkTask().execute(imagePath);
}
/**
* 訪問網路AsyncTask,訪問網路在子執行緒進行並返回主執行緒通知訪問的結果
*/
class NetworkTask extends AsyncTask<String, Integer, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
return doPost(params[0]);
}
@Override
protected void onPostExecute(String result) {
if(!"error".equals(result)) {
Log.i(TAG, "圖片地址 " + Constant.BASE_URL + result);
Glide.with(mContext)
.load(Constant.BASE_URL + result)
.into(mPictureIv);
}
}
}
private String doPost(String imagePath) {
OkHttpClient mOkHttpClient = new OkHttpClient();
String result = "error";
MultipartBody.Builder builder = new MultipartBody.Builder();
// 這裡演示新增使用者ID
// builder.addFormDataPart("userId", "20160519142605");
builder.addFormDataPart("image", imagePath,
RequestBody.create(MediaType.parse("image/jpeg"), new File(imagePath)));
RequestBody requestBody = builder.build();
Request.Builder reqBuilder = new Request.Builder();
Request request = reqBuilder
.url(Constant.BASE_URL + "/uploadimage")
.post(requestBody)
.build();
Log.d(TAG, "請求地址 " + Constant.BASE_URL + "/uploadimage");
try{
Response response = mOkHttpClient.newCall(request).execute();
Log.d(TAG, "響應碼 " + response.code());
if (response.isSuccessful()) {
String resultValue = response.body().string();
Log.d(TAG, "響應體 " + resultValue);
return resultValue;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
MainFragment繼承的PictureSelectFragment是一個帶有圖片的按鈕選擇器,該類如下:
PictureSelectFragment類:
package com.kevin.imageuploadclient.fragment.basic;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.kevin.crop.UCrop;
import com.kevin.imageuploadclient.R;
import com.kevin.imageuploadclient.activity.CropActivity;
import com.kevin.imageuploadclient.view.SelectPicturePopupWindow;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 帶有圖片的選擇器按鈕
*/
public abstract class PictureSelectFragment extends BaseFragment implements SelectPicturePopupWindow.OnSelectedListener {
private static final int GALLERY_REQUEST_CODE = 0; // 相簿選圖示記
private static final int CAMERA_REQUEST_CODE = 1; // 相機拍照標記
// 拍照臨時圖片
private String mTempPhotoPath;
// 剪下後圖像檔案
private Uri mDestinationUri;
/**
* 選擇提示 PopupWindow
*/
private SelectPicturePopupWindow mSelectPicturePopupWindow;
/**
* 圖片選擇的監聽回撥
*/
private OnPictureSelectedListener mOnPictureSelectedListener;
/**
* 剪下圖片
*/
protected void selectPicture() {
mSelectPicturePopupWindow.showPopupWindow(mActivity);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mDestinationUri = Uri.fromFile(new File(activity.getCacheDir(), "cropImage.jpeg"));
mTempPhotoPath = Environment.getExternalStorageDirectory() + File.separator + "photo.jpeg";//臨時相片
mSelectPicturePopupWindow = new SelectPicturePopupWindow(mContext);
mSelectPicturePopupWindow.setOnSelectedListener(this);
}
@Override
public void OnSelected(View v, int position) {
switch (position) {
case 0:
// "拍照"按鈕被點選了
takePhoto();
break;
case 1:
// "從相簿選擇"按鈕被點選了
pickFromGallery();
break;
case 2:
// "取消"按鈕被點選了
mSelectPicturePopupWindow.dismissPopupWindow();
break;
}
}
/**
* 已完成許可權請求時收到的回撥。
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_STORAGE_READ_ACCESS_PERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
pickFromGallery();//從相簿選擇
}
break;
case REQUEST_STORAGE_WRITE_ACCESS_PERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
takePhoto();//拍照
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
/**
* 調起手機拍照功能
*/
private void takePhoto() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN // api16開始新增的許可權
&& ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {//許可權不夠,提示
requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
getString(R.string.permission_write_storage_rationale),
REQUEST_STORAGE_WRITE_ACCESS_PERMISSION);
} else {//有許可權則調拍照功能
mSelectPicturePopupWindow.dismissPopupWindow();
Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//下面這句指定呼叫相機拍照後的照片儲存的路徑
takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mTempPhotoPath)));
startActivityForResult(takeIntent, CAMERA_REQUEST_CODE);
}
}
/**
* 選擇手機相簿的照片
*/
private void pickFromGallery() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN // api16之後需要許可權
&& ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {//許可權不夠時,提示
requestPermission(Manifest.permission.READ_EXTERNAL_STORAGE,
getString(R.string.permission_read_storage_rationale),
REQUEST_STORAGE_READ_ACCESS_PERMISSION);
} else {//許可權足夠,開啟手機相簿
mSelectPicturePopupWindow.dismissPopupWindow();
Intent pickIntent = new Intent(Intent.ACTION_PICK, null);
// 如果限制上傳到伺服器的圖片型別時可以直接寫如:"image/jpeg 、 image/png等的型別"
pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(pickIntent, GALLERY_REQUEST_CODE);
}
}
/**
* 回撥
* @param requestCode
* @param resultCode
* @param data
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == mActivity.RESULT_OK) {
switch (requestCode) {
case CAMERA_REQUEST_CODE: // 呼叫相機拍照
File temp = new File(mTempPhotoPath);
startCropActivity(Uri.fromFile(temp));//傳入臨時相片進行剪下
break;
case GALLERY_REQUEST_CODE: // 直接從相簿獲取
startCropActivity(data.getData());
break;
case UCrop.REQUEST_CROP: // 裁剪圖片結果
handleCropResult(data);
break;
case UCrop.RESULT_ERROR: // 裁剪圖片錯誤
handleCropError(data);
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
/**
* 裁剪圖片方法實現
*
* @param uri
*/
public void startCropActivity(Uri uri) {
UCrop.of(uri, mDestinationUri)
.withAspectRatio(1, 1)
.withMaxResultSize(512, 512)//剪下尺寸
.withTargetActivity(CropActivity.class)
.start(mActivity, this);
}
/**
* 處理剪下成功的返回值
*
* @param result
*/
private void handleCropResult(Intent result) {
deleteTempPhotoFile();
final Uri resultUri = UCrop.getOutput(result);
if (null != resultUri && null != mOnPictureSelectedListener) {
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(mActivity.getContentResolver(), resultUri);//獲取剪下後的圖片
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mOnPictureSelectedListener.onPictureSelected(resultUri, bitmap);
} else {
Toast.makeText(mContext, "無法剪下選擇圖片", Toast.LENGTH_SHORT).show();
}
}
/**
* 處理剪下失敗的返回值
*
* @param result
*/
private void handleCropError(Intent result) {
deleteTempPhotoFile();
final Throwable cropError = UCrop.getError(result);
if (cropError != null) {
Log.e(TAG, "handleCropError: ", cropError);
Toast.makeText(mContext, cropError.getMessage(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(mContext, "無法剪下選擇圖片", Toast.LENGTH_SHORT).show();
}
}
/**
* 刪除拍照臨時檔案
*/
private void deleteTempPhotoFile() {
File tempFile = new File(mTempPhotoPath);
if (tempFile.exists() && tempFile.isFile()) {
tempFile.delete();
}
}
/**
* 設定圖片選擇的回撥監聽
*
* @param l
*/
public void setOnPictureSelectedListener(OnPictureSelectedListener l) {
this.mOnPictureSelectedListener = l;
}
/**
* 圖片選擇的回撥介面
*/
public interface OnPictureSelectedListener {
/**
* 圖片選擇的監聽回撥
*
* @param fileUri
* @param bitmap
*/
void onPictureSelected(Uri fileUri, Bitmap bitmap);
}
}
BaseFragment是繼承Fragment類,在BaseFragment中做了請求許可權,還有幾個抽象方法:
BaseFragment類:
package com.kevin.imageuploadclient.fragment.basic;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.kevin.imageuploadclient.R;
import butterknife.ButterKnife;
public abstract class BaseFragment extends Fragment {
/** 類標籤 */
protected static String TAG = "";
/** 上下文 */
protected Context mContext = null;
/** 依附的Activity */
protected Activity mActivity= null;
private AlertDialog mAlertDialog;
protected static final int REQUEST_STORAGE_READ_ACCESS_PERMISSION = 101;
protected static final int REQUEST_STORAGE_WRITE_ACCESS_PERMISSION = 102;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
TAG = this.getClass().getSimpleName();
mContext = activity;
mActivity = activity;
// LogUtils.i(getFragmentName() + " onAttach()");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// LogUtils.i(getFragmentName() + " onCreate()");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// LogUtils.i(getFragmentName() + " onCreateView()");
if (getContentViewId() != 0) {
return inflater.inflate(getContentViewId(), null);
} else {
return super.onCreateView(inflater, container, savedInstanceState);
}
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// LogUtils.i(getFragmentName() + " onViewCreated()");
ButterKnife.bind(this, view);
init();
initViews(view);
initData();
initEvents();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// LogUtils.i(getFragmentName() + " onActivityCreated()");
}
@Override
public void onStart() {
super.onStart();
// LogUtils.i(getFragmentName() + " onStart()");
}
@Override
public void onResume() {
super.onResume();
// LogUtils.i(getFragmentName() + " onResume()");
}
@Override
public void onPause() {
super.onPause();
// LogUtils.i(getFragmentName() + " onPause()");
}
@Override
public void onStop() {
super.onStop();
// LogUtils.i(getFragmentName() + " onStop()");
}
@Override
public void onDestroyView() {
super.onDestroyView();
// LogUtils.i(getFragmentName() + " onDestroyView()");
ButterKnife.unbind(this);
}
@Override
public void onDestroy() {
super.onDestroy();
// LogUtils.i(getFragmentName() + " onDestroy()");
}
@Override
public void onDetach() {
super.onDetach();
// LogUtils.i(getFragmentName() + " onDetach()");
}
/**
* 使用Toolbar代替ActionBar
*
* @return void
*/
protected void initToolbar(Toolbar toolbar) {
((AppCompatActivity)mActivity).setSupportActionBar(toolbar);
}
/**
* 使用Toolbar代替ActionBar
*
* @return void
*/
protected void initToolbar(Toolbar toolbar, String title) {
toolbar.setTitle(title);
initToolbar(toolbar);
}
/**
* 請求許可權
*
* 如果許可權被拒絕過,則提示使用者需要許可權
*/
protected void requestPermission(final String permission, String rationale, final int requestCode) {
if (shouldShowRequestPermissionRationale(permission)) {
showAlertDialog(getString(R.string.permission_title_rationale), rationale,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{permission}, requestCode);
}
}, getString(R.string.label_ok), null, getString(R.string.label_cancel));
} else {
requestPermissions(new String[]{permission}, requestCode);
}
}
/**
* 顯示指定標題和資訊的對話方塊
*
* @param title - 標題
* @param message - 資訊
* @param onPositiveButtonClickListener - 肯定按鈕監聽
* @param positiveText - 肯定按鈕資訊
* @param onNegativeButtonClickListener - 否定按鈕監聽
* @param negativeText - 否定按鈕資訊
*/
protected void showAlertDialog(@Nullable String title, @Nullable String message,
@Nullable DialogInterface.OnClickListener onPositiveButtonClickListener,
@NonNull String positiveText,
@Nullable DialogInterface.OnClickListener onNegativeButtonClickListener,
@NonNull String negativeText) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(title);
builder.setMessage(message);
builder.setPositiveButton(positiveText, onPositiveButtonClickListener);
builder.setNegativeButton(negativeText, onNegativeButtonClickListener);
mAlertDialog = builder.show();
}
/**
* 獲取當前Fragment的名稱
* @return
*/
public String getFragmentName(){
return TAG;
}
/** 初始化方法 */
public void init() {}
/** 設定佈局 */
protected abstract int getContentViewId();
/** 初始化View的抽象方法 */
public abstract void initViews(View view);
/** 初始化資料 */
protected void initData() {}
/** 初始化事件的抽象方法 */
public abstract void initEvents();
}
同樣,圖片剪下一樣是繼承了自己寫的,前面圖片剪下的方法中的CropActivity類:
package com.kevin.imageuploadclient.activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import com.kevin.crop.UCrop;
import com.kevin.crop.util.BitmapLoadUtils;
import com.kevin.crop.view.CropImageView;
import com.kevin.crop.view.GestureCropImageView;
import com.kevin.crop.view.OverlayView;
import com.kevin.crop.view.TransformImageView;
import com.kevin.crop.view.UCropView;
import com.kevin.imageuploadclient.R;
import com.kevin.imageuploadclient.activity.basic.BaseActivity;
import java.io.OutputStream;
import butterknife.Bind;
public class CropActivity extends BaseActivity {
private static final String TAG = "CropActivity";
@Bind(R.id.toolbar)
Toolbar mToolBar;
@Bind(R.id.weixin_act_ucrop)
UCropView mUCropView;
GestureCropImageView mGestureCropImageView;
OverlayView mOverlayView;
@Bind(R.id.crop_act_save_fab)
FloatingActionButton mSaveFab;
private Uri mOutputUri;
@Override
protected void initContentView() {
setContentView(R.layout.activity_crop);
}
@Override
protected void initViews() {
initToolBar();
mGestureCropImageView = mUCropView.getCropImageView();
mOverlayView = mUCropView.getOverlayView();
// 設定允許縮放
mGestureCropImageView.setScaleEnabled(true);
// 設定禁止旋轉
mGestureCropImageView.setRotateEnabled(false);
// 設定剪下後的最大寬度
// mGestureCropImageView.setMaxResultImageSizeX(300);
// 設定剪下後的最大高度
// mGestureCropImageView.setMaxResultImageSizeY(300);
// 設定外部陰影顏色
mOverlayView.setDimmedColor(Color.parseColor("#AA000000"));
// 設定周圍陰影是否為橢圓(如果false則為矩形)
mOverlayView.setOvalDimmedLayer(false);
// 設定顯示裁剪邊框
mOverlayView.setShowCropFrame(true);
// 設定不顯示裁剪網格
mOverlayView.setShowCropGrid(false);
final Intent intent = getIntent();
setImageData(intent);
}
/**
* 初始化ToolBar
*/
private void initToolBar() {
mToolBar.setTitle("裁剪圖片");
setSupportActionBar(mToolBar);
mToolBar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
}
@Override
protected void initEvents() {
mGestureCropImageView.setTransformImageListener(mImageListener);
mSaveFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cropAndSaveImage();
}
});
}
private void setImageData(Intent intent) {
Uri inputUri = intent.getParcelableExtra(UCrop.EXTRA_INPUT_URI);
mOutputUri = intent.getParcelableExtra(UCrop.EXTRA_OUTPUT_URI);
if (inputUri != null && mOutputUri != null) {
try {
mGestureCropImageView.setImageUri(inputUri);
} catch (Exception e) {
setResultException(e);
finish();
}
} else {
setResultException(new NullPointerException("Both input and output Uri must be specified"));
finish();
}
// 設定裁剪寬高比
if (intent.getBooleanExtra(UCrop.EXTRA_ASPECT_RATIO_SET, false)) {
float aspectRatioX = intent.getFloatExtra(UCrop.EXTRA_ASPECT_RATIO_X, 0);
float aspectRatioY = intent.getFloatExtra(UCrop.EXTRA_ASPECT_RATIO_Y, 0);
if (aspectRatioX > 0 && aspectRatioY > 0) {
mGestureCropImageView.setTargetAspectRatio(aspectRatioX / aspectRatioY);
} else {
mGestureCropImageView.setTargetAspectRatio(CropImageView.SOURCE_IMAGE_ASPECT_RATIO);
}
}
// 設定裁剪的最大寬高
if (intent.getBooleanExtra(UCrop.EXTRA_MAX_SIZE_SET, false)) {
int maxSizeX = intent.getIntExtra(UCrop.EXTRA_MAX_SIZE_X, 0);
int maxSizeY = intent.getIntExtra(UCrop.EXTRA_MAX_SIZE_Y, 0);
if (maxSizeX > 0 && maxSizeY > 0) {
mGestureCropImageView.setMaxResultImageSizeX(maxSizeX);
mGestureCropImageView.setMaxResultImageSizeY(maxSizeY);
} else {
Log.w(TAG, "EXTRA_MAX_SIZE_X and EXTRA_MAX_SIZE_Y must be greater than 0");
}
}
}
private void cropAndSaveImage() {
OutputStream outputStream = null;
try {
final Bitmap croppedBitmap = mGestureCropImageView.cropImage();
if (croppedBitmap != null) {
outputStream = getContentResolver().openOutputStream(mOutputUri);
croppedBitmap.compress(Bitmap.CompressFormat.JPEG, 85, outputStream);
croppedBitmap.recycle();
setResultUri(mOutputUri, mGestureCropImageView.getTargetAspectRatio());
finish();
} else {
setResultException(new NullPointerException("CropImageView.cropImage() returned null."));
}
} catch (Exception e) {
setResultException(e);
finish();
} finally {
BitmapLoadUtils.close(outputStream);
}
}
private TransformImageView.TransformImageListener mImageListener = new TransformImageView.TransformImageListener() {
@Override
public void onRotate(float currentAngle) {
// setAngleText(currentAngle);
}
@Override
public void onScale(float currentScale) {
// setScaleText(currentScale);
}
@Override
public void onLoadComplete() {
Animation fadeInAnimation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.crop_fade_in);
fadeInAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mUCropView.setVisibility(View.VISIBLE);
mGestureCropImageView.setImageToWrapCropBounds();
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
mUCropView.startAnimation(fadeInAnimation);
}
@Override
public void onLoadFailure(Exception e) {
setResultException(e);
finish();
}
};
private void setResultUri(Uri uri, float resultAspectRatio) {
setResult(RESULT_OK, new Intent()
.putExtra(UCrop.EXTRA_OUTPUT_URI, uri)
.putExtra(UCrop.EXTRA_OUTPUT_CROP_ASPECT_RATIO, resultAspectRatio));
}
private void setResultException(Throwable throwable) {
setResult(UCrop.RESULT_ERROR, new Intent().putExtra(UCrop.EXTRA_ERROR, throwable));
}
}
BaseActivity類:
package com.kevin.imageuploadclient.activity.basic;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.ViewConfiguration;
import com.kevin.imageuploadclient.KevinApplication;
import java.lang.reflect.Field;
import butterknife.ButterKnife;
public abstract class BaseActivity extends ActionBarActivity {
protected Context mContext = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
mContext = this;
KevinApplication.getInstance().mActivityStack.addActivity(this);
setOverflowShowingAlways();
super.onCreate(savedInstanceState);
initContentView();
ButterKnife.bind(this);
init();
initViews();
initEvents();
}
/**
* 設定總是顯示溢位選單
*/
private void setOverflowShowingAlways() {
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void onStart() {
super.onStart();
}
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);
}
public void finish() {
super.finish();
KevinApplication.getInstance().mActivityStack.removeActivity(this);
}
/**
* 初始化佈局
*/
protected abstract void initContentView();
/**
* 初始化
*/
protected void init() {
}
/**
* 初始化View
*/
protected abstract void initViews();
/**
* 初始化事件
*/
protected abstract void initEvents();
}
大家需要的話下面是下載地址,提醒一點,如果你想在客戶端跑起來上傳圖片,必須要啟動服務端,服務端的文章在這裡,在上一篇的最下面一樣附上了下載地址,只需要在客戶端修改伺服器地址就可以了。
相關推薦
Android——從本地相簿上傳圖片至伺服器
android實現本地圖片上傳至服務端,只需幾步操作即可實現,下面一起看看。 首先看下效果: 主要程式碼: package com.kevin.imageuploadclient.fragment; import android.graphics
微信小程式如何上傳圖片至伺服器(node.js例項分享)
一、前臺處理 (1)首先在wxml中為按鈕繫結上傳圖片事件 <button bindtap="upImgClick">上傳圖片</button> <image src='{{imgUrl}}'></image>
用postman 上傳圖片至伺服器
from flask import Flask,request app = Flask(__name__) @app.route('/',methods=['POST','GET']) def index(): name = request.form.get("name") age =
呼叫系統相簿上傳圖片到伺服器--OPPO等部分手機上出現短暫的顯示桌面問題
主要原因是主體樣式設定的問題:這裡把appTheme設定一個style即可: <item name="android:windowBackground">@color/white</item> <!--下面這個屬
記錄:php上傳圖片至伺服器 並返回顯示圖片地址
前端上傳圖片主要程式碼:upload_test.html<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&g
在fragment中實現Android上傳圖片至本地JavaWeb服務器
prop prefix adt ilo err 1.10 response try 轉換成 服務器端: 需要一個接受文件的servlet,以及導入兩個包:commons-fileupload-1.3.1.jar 和 commons-io-2.4.jar import ja
[Android] WebView中拍照或從相簿上傳圖片
WebView 上傳圖片, 想必很多人都碰到過這樣的場景. 而且 WebView 在4.4前後的區別非常大, 比如對URL跳轉的格式, 對JS的注入宣告等等, 4.4以後的WebView 已經是chromium核心, 有多強大就無需我贅述. 說這些, 其實也
上傳圖片至數據庫及從數據庫中讀取圖片顯示至頁面
for循環 common 基於 serial 文件創建 每一個 super lis size 1.基於最簡單的servlet+jsp+jdbc實現 2.實驗環境:myeclipse以及tomcat 8.5 3.所需jar包: 4.數據庫: 數據庫用的是mysql
使用“rz -be”命令上傳檔案至伺服器;使用“sz 檔名”從伺服器下載檔案到本地
我們知道在與linux 做檔案交換的時候,經常會使用到windows 檔案上傳到linux 或者linux 檔案下載到windows之類的情況,其中大家使用比較常用的就是 Xftp,sftp,FileZilla等,那麼今天就介紹另外一種方式上傳與下載檔案rz/sz 測試環境: CentOs
java 上傳圖片至本地 並讀取圖片在網頁中顯示
java 上傳圖片至本地 並讀取圖片在網頁中顯示 程式碼+圖片如下所示 一、程式碼 @Controller public class ImageController { private static Logger logger = LoggerFactory.getLogge
WebView中拍照或從相簿上傳圖片
WebView 上傳圖片, 想必很多人都碰到過這樣的場景. 而且 WebView 在4.4前後的區別非常大, 比如對URL跳轉的格式, 對JS的注入宣告等等, 4.4以後的WebView 已經是chromium核心, 有多強大就無需我贅述. 說這些, 其實也是
Android H5和App互動以及開啟相簿上傳圖片並顯示
一、H5連結開啟App 點選瀏覽器中的URL,如何啟動App呢? 1、HTML連結處理 首先做成HTML的內容,url格式如下: <a href="[scheme]://[host]/[path]?[query]">啟動應用程式</a> 說明:
Android上傳圖片至java伺服器
這幾天有做到一個小的案例,手機拍照、相簿照片上傳到伺服器。客戶端和伺服器的程式碼都貼出來: 客戶端 AndroidManifest.xml新增以下許可權 <uses-permission android:name="android.permiss
微信小程式 上傳圖片至阿里雲OSS(支援多圖片上傳)
我們先講下為什麼要把圖片檔案上傳到雲伺服器呢, 有什麼好處呢? 1、能減輕我們自己伺服器的頻寬 如果一個程式裡有多處地方用到使用者上傳圖片等功能的話,建議還是放到阿里雲或者千牛雲等其他平臺上來儲存我們的圖片,可以給公司的伺服器減少很多壓力,磁碟儲存也就不會太大 2、提升使用者體驗感
winform端上傳圖片至flask伺服器
winform端程式碼: public static string PostImageData(string url, IDictionary<string, string> parameters, int timeout, string userAgent, CookieColle
使用jsJdk非同步上傳圖片至OSS伺服器
阿里雲官方文件中給的基本都是同步上傳檔案的DEMO,可能是非同步的比較簡單,但是由於自己JS基礎還不夠牢固,在學習使用的時候也很鬧心,因為老是看著看著就看到非同步的那邊去了。將自己寫好的的一個DEMO放於部落格中,萬一能夠幫助到任何一個和我一樣的朋友也是好的。 <!DOCTYPE html&
本地初次上傳程式碼至gitlab
以前做過的專案中用過Git和GitHub,這次用的是GitLab,以下是網路上對三者區別的描述,我覺得很形象: Git是一種版本控制系統(Version Control System,VCS),是一種工具。 &nbs
上傳圖片至fastdfs分散式檔案系統並回顯
事件,當我們瀏覽完圖片選中一張時,觸發onchange事件將圖片上傳到伺服器並回顯、 1 <img width="100" height="100" id="allUrl" src="${brand.imgUrl }"/> 2 <input type="hidden" name
Android上傳圖片到伺服器並顯示(後臺用Java處理)
Android上傳圖片(Android Studio) Fragment介面: private String img_src; /** * 從相簿選取圖片 */ public void selectImg() { Intent intent = new
JAVA 上傳圖片至阿里OSS儲存庫
1.建立一個工具類OSSUtil.java,程式碼如下: package com.qyrj.util; import com.aliyun.oss.OSSClient; import com.aliyun.oss.model.PutObjectRequest; import java.io.By