在好例子网,分享、交流、成长!
您当前所在位置:首页Java 开发实例Android平台开发 → android 按住拍 短视频 例子源码

android 按住拍 短视频 例子源码

Android平台开发

下载此实例
  • 开发语言:Java
  • 实例大小:8.49M
  • 下载次数:44
  • 浏览次数:1480
  • 发布时间:2015-11-03
  • 实例类别:Android平台开发
  • 发 布 人:伊璐
  • 文件格式:.zip
  • 所需积分:2
 相关标签: 视频

实例介绍

【实例简介】 有点仿 微信拍短视频的感觉,按住屏幕任何位置拍摄


【实例截图】




【核心代码】


package com.yixia.camera.demo.ui.record;

import java.io.File;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.BitmapDrawable;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.yixia.camera.FFMpegUtils;
import com.yixia.camera.MediaRecorder;
import com.yixia.camera.MediaRecorder.OnErrorListener;
import com.yixia.camera.MediaRecorder.OnPreparedListener;
import com.yixia.camera.MediaRecorderFilter;
import com.yixia.camera.VCamera;
import com.yixia.camera.demo.R;
import com.yixia.camera.demo.log.Logger;
import com.yixia.camera.demo.ui.BaseActivity;
import com.yixia.camera.demo.ui.record.views.ProgressView;
import com.yixia.camera.demo.ui.record.views.ThemeRadioButton;
import com.yixia.camera.demo.utils.ConvertToUtils;
import com.yixia.camera.demo.utils.NetworkUtils;
import com.yixia.camera.model.MediaObject;
import com.yixia.camera.model.MediaObject.MediaPart;
import com.yixia.camera.util.DeviceUtils;
import com.yixia.camera.util.FileUtils;
import com.yixia.camera.util.StringUtils;
import com.yixia.camera.view.CameraNdkView;

/**
 * 视频录制
 * 
 * @author tangjun@yixia.com
 *
 */
public class MediaRecorderActivity extends BaseActivity implements OnErrorListener, OnClickListener, OnPreparedListener {

	/** 滤镜图标 */
	private final static int[] FILTER_ICONS = new int[] { R.drawable.filter_original, R.drawable.filter_black_white, R.drawable.filter_sharpen, R.drawable.filter_old_film, R.drawable.filter_edge, R.drawable.filter_anti_color, R.drawable.filter_radial, R.drawable.filter_8bit, R.drawable.filter_lomo };
	/** 滤镜枚举值 */
	private final static String[] FILTER_VALUES = new String[] { MediaRecorderFilter.CAMERA_FILTER_NO, MediaRecorderFilter.CAMERA_FILTER_BLACKWHITE, MediaRecorderFilter.CAMERA_FILTER_SHARPEN, MediaRecorderFilter.CAMERA_FILTER_OLD_PHOTOS, MediaRecorderFilter.CAMERA_FILTER_NEON_LIGHT, MediaRecorderFilter.CAMERA_FILTER_ANTICOLOR, MediaRecorderFilter.CAMERA_FILTER_PASS_THROUGH, MediaRecorderFilter.CAMERA_FILTER_MOSAICS, MediaRecorderFilter.CAMERA_FILTER_REMINISCENCE };
	/** 导入图片 */
	public final static int REQUEST_CODE_IMPORT_IMAGE = 999;
	/** 导入视频 */
	public final static int REQUEST_CODE_IMPORT_VIDEO = 998;
	/** 导入视频截取 */
	public final static int REQUEST_CODE_IMPORT_VIDEO_EDIT = 997;
	/** 录制最长时间 */
	public final static int RECORD_TIME_MAX = 10 * 1000;
	/** 录制最小时间 */
	public final static int RECORD_TIME_MIN = 3 * 1000;

	private CheckedTextView mRecordDelete, mRecordDelay, mRecordFilter;
	private ProgressView mProgressView;
	private CameraNdkView mSurfaceView;
	private TextView mTitleText, mTitleNext, mRecordImport;
	private ImageView mPressText;
	/** 滤镜容器 */
	private RadioGroup mRecordFilterContainer;
	private View mRecordFilterLayout;

	private PopupWindow mPopupWindow;

	private MediaRecorderFilter mMediaRecorder;
	private MediaObject mMediaObject;
	private int mWindowWidth;
	/** 是否是点击状态 */
	private volatile boolean mPressedStatus, mReleased, mStartEncoding;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);// 防止锁屏
		mWindowWidth = DeviceUtils.getScreenWidth(this);
		setContentView(R.layout.activity_media_recorder);

		// ~~~ 绑定控件
		mSurfaceView = (CameraNdkView) findViewById(R.id.record_preview);
		mProgressView = (ProgressView) findViewById(R.id.record_progress);
		mTitleText = (TextView) findViewById(R.id.title_text);
		mTitleNext = (TextView) findViewById(R.id.title_right);
		mRecordDelay = (CheckedTextView) findViewById(R.id.record_delay);
		mRecordDelete = (CheckedTextView) findViewById(R.id.record_delete);
		mRecordFilter = (CheckedTextView) findViewById(R.id.record_filter);
		mPressText = (ImageView) findViewById(R.id.record_tips_text);
		mRecordFilterContainer = (RadioGroup) findViewById(R.id.record_filter_container);
		mRecordFilterLayout = findViewById(R.id.record_filter_layout);
		mRecordImport = (TextView) findViewById(R.id.record_import);

		// ~~~ 绑定事件
		findViewById(R.id.record_layout).setOnTouchListener(mOnSurfaceViewTouchListener);
		mTitleNext.setOnClickListener(this);
		mRecordDelete.setOnClickListener(this);
		mRecordFilter.setOnClickListener(this);
		mRecordDelay.setOnClickListener(this);
		mRecordImport.setOnClickListener(this);

		// ~~~ 初始数据
		mSurfaceView.getLayoutParams().height = mWindowWidth;//(int) (mWindowWidth * 3F / 2);//视频为640x480,后期裁剪成1:1的视频
		findViewById(R.id.record_layout).getLayoutParams().height = mWindowWidth;//设置1:1预览范围
		mProgressView.invalidate();
		//		mDelayAnimation = AnimationUtils.loadAnimation(this, R.anim.record_delay_anim);
	}

	@Override
	protected void onStart() {
		super.onStart();

		if (mMediaRecorder == null)
			initMediaRecorder();
		else {
			mMediaRecorder.setSurfaceHolder(mSurfaceView.getHolder());
			mMediaRecorder.prepare();
		}
		checkStatus();
	}

	@Override
	protected void onStop() {
		super.onStop();
		if (mMediaRecorder != null && !mReleased) {
			mMediaRecorder.release();
		}
	}

	@Override
	public void onBackPressed() {
		if (mRecordDelete.isChecked()) {
			cancelDelete();
			return;
		}

		if (mMediaObject != null && mMediaObject.getDuration() > 1) {
			//未转码
			new AlertDialog.Builder(this).setTitle(R.string.hint).setMessage(R.string.record_camera_exit_dialog_message).setNegativeButton(R.string.dialog_yes, new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					mMediaObject.delete();
					finish();
				}

			}).setPositiveButton(R.string.dialog_no, null).setCancelable(false).show();
			return;
		}

		if (mMediaObject != null)
			mMediaObject.delete();
		super.onBackPressed();
	}

	private void initMediaRecorder() {
		mMediaRecorder = new MediaRecorderFilter();
		mMediaRecorder.setOnErrorListener(this);
		mMediaRecorder.setOnPreparedListener(this);
		//WIFI下800k码率,其他情况(4G/3G/2G)600K码率
		mMediaRecorder.setVideoBitRate(NetworkUtils.isWifiAvailable(this) ? MediaRecorder.VIDEO_BITRATE_MEDIUM : MediaRecorder.VIDEO_BITRATE_NORMAL);
		//		mMediaRecorder.setSurfaceHolder(mSurfaceView.getHolder());
		mMediaRecorder.setSurfaceView(mSurfaceView);
		String key = String.valueOf(System.currentTimeMillis());
		mMediaObject = mMediaRecorder.setOutputDirectory(key, VCamera.getVideoCachePath()   key);
		if (mMediaObject != null) {
			mMediaRecorder.prepare();
			mMediaRecorder.setCameraFilter(MediaRecorderFilter.CAMERA_FILTER_NO);
			mProgressView.setData(mMediaObject);
		} else {
			Toast.makeText(this, R.string.record_camera_init_faild, Toast.LENGTH_SHORT).show();
			finish();
		}
	}

	private View.OnTouchListener mOnSurfaceViewTouchListener = new View.OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			if (mMediaRecorder == null || mMediaObject == null) {
				return false;
			}

			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:

				//检测是否手动对焦
				//				if (checkCameraFocus(event))
				//					return true;

				//取消回删
				if (cancelDelete())
					return true;

				//取消延时拍摄
				//				if (mRecordDelay.isChecked()) {
				//					stopRecord();
				//					return true;
				//				}

				//判断是否已经超时
				if (mMediaObject.getDuration() >= RECORD_TIME_MAX) {
					return true;
				}

				//显示当前时间
				mTitleText.setText(String.format("%.1f", mMediaObject.getDuration() / 1000F));

				startRecord();

				break;
			case MotionEvent.ACTION_MOVE:
				break;
			case MotionEvent.ACTION_UP:
				// 暂停
				if (mPressedStatus) {
					stopRecord();

					//检测是否已经完成
					if (mMediaObject.getDuration() >= RECORD_TIME_MAX) {
						mTitleNext.performClick();
					}
				}

				mTitleText.setText(R.string.record_camera_title);
				break;
			}
			return true;
		}

	};

	/** 开始拍摄 */
	private void startRecord() {
		mPressedStatus = true;

		if (mMediaRecorder != null) {
			mMediaRecorder.startRecord();
		}

		if (mHandler != null) {
			mHandler.sendEmptyMessage(HANDLE_INVALIDATE_PROGRESS);
			mHandler.sendEmptyMessageDelayed(HANDLE_STOP_RECORD, RECORD_TIME_MAX - mMediaObject.getDuration());
		}

		mHandler.removeMessages(HANDLE_SHOW_TIPS);
		mHandler.sendEmptyMessage(HANDLE_SHOW_TIPS);
		mRecordDelete.setEnabled(false);
		if (!mRecordDelay.isChecked())
			mRecordDelay.setEnabled(false);

		mPressText.setImageResource(R.drawable.record_tips_pause);
	}

	private void stopRecord() {
		mPressedStatus = false;
		//提示完成
		mPressText.setImageResource(R.drawable.record_tips_press);

		if (mMediaRecorder != null)
			mMediaRecorder.stopRecord();

		//取消倒计时
		mHandler.removeMessages(HANDLE_STOP_RECORD);

		mRecordDelay.setChecked(false);
		mRecordDelay.setEnabled(true);
		mRecordDelete.setEnabled(true);
	}

	/** 是否可回删 */
	private boolean cancelDelete() {
		if (mMediaObject != null) {
			MediaPart part = mMediaObject.getCurrentPart();
			if (part != null && part.remove) {
				part.remove = false;
				mRecordDelete.setChecked(false);

				if (mProgressView != null)
					mProgressView.invalidate();

				return true;
			}
		}
		return false;
	}

	/** 刷新进度条 */
	private static final int HANDLE_INVALIDATE_PROGRESS = 0;
	/** 延迟拍摄停止 */
	private static final int HANDLE_STOP_RECORD = 1;
	/** 显示下一步 */
	private static final int HANDLE_SHOW_TIPS = 2;

	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case HANDLE_INVALIDATE_PROGRESS:
				if (mMediaObject != null && !isFinishing()) {
					if (mProgressView != null)
						mProgressView.invalidate();
					if (mPressedStatus)
						mTitleText.setText(String.format("%.1f", mMediaObject.getDuration() / 1000F));
					if (mPressedStatus)
						sendEmptyMessageDelayed(0, 30);
				}
				break;
			case HANDLE_SHOW_TIPS:
				if (mMediaRecorder != null && !isFinishing()) {
					int duration = checkStatus();

					if (mPressedStatus) {
						if (duration < RECORD_TIME_MAX) {
							sendEmptyMessageDelayed(HANDLE_SHOW_TIPS, 200);
						} else {
							sendEmptyMessageDelayed(HANDLE_SHOW_TIPS, 500);
						}
					}
				}
				break;
			case HANDLE_STOP_RECORD:
				stopRecord();
				startEncoding();
				break;
			}
		}
	};

	/** 导入图片或视频 */
	private void importImageOrVideo(final String path) {
		if (!isFinishing() && mMediaObject != null && StringUtils.isNotEmpty(path) && new File(path).exists()) {
			new AsyncTask<Void, Void, Boolean>() {

				@Override
				protected void onPreExecute() {
					super.onPreExecute();
					showProgress("", getString(R.string.record_camera_progress_message));
				}

				@Override
				protected Boolean doInBackground(Void... params) {
					MediaPart part = mMediaObject.buildMediaPart(path, 1000, MediaObject.MEDIA_PART_TYPE_IMPORT_IMAGE);
					if (part != null) {
						return FFMpegUtils.convertImage2Video(part);
					}
					return false;
				}

				@Override
				protected void onPostExecute(Boolean result) {
					super.onPostExecute(result);
					hideProgress();
					if (result) {
						mProgressView.setData(mMediaObject);
					} else {
						Toast.makeText(MediaRecorderActivity.this, R.string.record_video_transcoding_faild, Toast.LENGTH_SHORT).show();
					}
				}

			}.execute();
		}
	}

	private void startEncoding() {
		//检测磁盘空间
		if (FileUtils.showFileAvailable() < 200) {
			Toast.makeText(this, R.string.record_camera_check_available_faild, Toast.LENGTH_SHORT).show();
			return;
		}

		if (!isFinishing() && mMediaRecorder != null && mMediaObject != null && !mStartEncoding) {
			mStartEncoding = true;

			new AsyncTask<Void, Void, Boolean>() {

				@Override
				protected void onPreExecute() {
					super.onPreExecute();
					showProgress("", getString(R.string.record_camera_progress_message));
				}

				@Override
				protected Boolean doInBackground(Void... params) {
					boolean result = FFMpegUtils.videoTranscoding(mMediaObject, mMediaObject.getOutputTempVideoPath(), mWindowWidth, false);
					if (result && mMediaRecorder != null) {
						mMediaRecorder.release();
						mReleased = true;
					}
					return result;
				}

				@Override
				protected void onCancelled() {
					super.onCancelled();
					mStartEncoding = false;
				}

				@Override
				protected void onPostExecute(Boolean result) {
					super.onPostExecute(result);
					hideProgress();
					if (result) {
						/** 序列化保存数据 */
						if (saveMediaObject(mMediaObject)) {
							Intent intent = new Intent(MediaRecorderActivity.this, MediaPreviewActivity.class);
							intent.putExtra("obj", mMediaObject.getObjectFilePath());
							startActivity(intent);
						} else {
							Toast.makeText(MediaRecorderActivity.this, R.string.record_camera_save_faild, Toast.LENGTH_SHORT).show();
						}
					} else {
						Toast.makeText(MediaRecorderActivity.this, R.string.record_video_transcoding_faild, Toast.LENGTH_SHORT).show();
					}
					mStartEncoding = false;
				}
			}.execute();
		}
	}

	/** 检测是否超过三秒 */
	private int checkStatus() {
		int duration = 0;
		if (!isFinishing() && mMediaObject != null) {
			duration = mMediaObject.getDuration();
			if (duration < RECORD_TIME_MIN) {
				//视频必须大于3秒
				if (mTitleNext.getVisibility() != View.INVISIBLE)
					mTitleNext.setVisibility(View.INVISIBLE);
			} else {
				//下一步
				if (mTitleNext.getVisibility() != View.VISIBLE) {
					mTitleNext.setVisibility(View.VISIBLE);
					mTitleNext.setText(R.string.record_camera_next);
				}
			}
		}
		return duration;
	}

	@Override
	public void onVideoError(int what, int extra) {
		Logger.e("[MediaRecorderActvity]onVideoError: what"   what   " extra:"   extra);
	}

	@Override
	public void onAudioError(int what, String message) {
		Logger.e("[MediaRecorderActvity]onAudioError: what"   what   " message:"   message);
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				Toast.makeText(MediaRecorderActivity.this, R.string.record_camera_open_audio_faild, Toast.LENGTH_SHORT).show();
			}
		});
	}

	@Override
	public void onClick(View v) {
		final int id = v.getId();

		//处理开启回删后其他点击操作
		if (id != R.id.record_delete) {
			if (mMediaObject != null) {
				MediaPart part = mMediaObject.getCurrentPart();
				if (part != null) {
					if (part.remove) {
						part.remove = false;
						mRecordDelete.setChecked(false);
						if (mProgressView != null)
							mProgressView.invalidate();
					}
				}
			}
		}

		if (id != R.id.record_filter) {
			if (mRecordFilter.isChecked()) {
				mRecordFilterLayout.setVisibility(View.GONE);
				mRecordFilter.setChecked(false);
			}
		}

		switch (v.getId()) {
		case R.id.record_import://导入
			showImportMenu();
			break;
		case R.id.title_right:
			startEncoding();
			break;
		case R.id.record_delete:
			if (mMediaObject != null) {
				MediaPart part = mMediaObject.getCurrentPart();
				if (part != null) {
					if (part.remove) {
						//确认删除分块
						part.remove = false;
						mMediaObject.removePart(part, true);
						mRecordDelete.setChecked(false);
					} else {
						part.remove = true;
						mRecordDelete.setChecked(true);
					}
				}
				if (mProgressView != null)
					mProgressView.invalidate();

				//检测按钮状态
				checkStatus();
			}
			break;
		case R.id.record_filter:
			if (mRecordFilter.isChecked()) {
				mRecordFilterLayout.setVisibility(View.GONE);
				mRecordFilter.setChecked(false);
			} else {
				loadFilter();
				mRecordFilterLayout.setVisibility(View.VISIBLE);
				mRecordFilter.setChecked(true);
			}
			break;
		case R.id.import_image: {
			if (mPopupWindow != null) {
				mPopupWindow.dismiss();
				mPopupWindow = null;
			}
			Intent intent = new Intent();
			intent.setAction(Intent.ACTION_GET_CONTENT);
			intent.setType("image/*");
			startActivityForResult(Intent.createChooser(intent, getString(R.string.record_camera_import_image_choose)), REQUEST_CODE_IMPORT_IMAGE);
		}
			break;
		case R.id.import_video: {
			if (mPopupWindow != null) {
				mPopupWindow.dismiss();
				mPopupWindow = null;
			}
			Intent intent = new Intent();
			intent.setAction(Intent.ACTION_GET_CONTENT);
			intent.addCategory(Intent.CATEGORY_OPENABLE);
			intent.setType("video/*");
			startActivityForResult(Intent.createChooser(intent, getString(R.string.record_camera_import_video_choose)), REQUEST_CODE_IMPORT_VIDEO);
		}
			break;
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == Activity.RESULT_OK) {
			if (requestCode == REQUEST_CODE_IMPORT_VIDEO_EDIT) {
				mMediaObject = restoneMediaObject(mMediaObject.getObjectFilePath());
				mProgressView.setData(mMediaObject);
			} else {
				//处理导入图片和视频
				if (data != null) {
					Uri uri = data.getData();
					if (uri != null) {
						String columnName;
						switch (requestCode) {
						case REQUEST_CODE_IMPORT_IMAGE://导入图片
							columnName = MediaStore.Images.Media.DATA;
							break;
						case REQUEST_CODE_IMPORT_VIDEO:
							columnName = MediaStore.Video.Media.DATA;
							break;
						default:
							return;
						}
						if (StringUtils.isNotEmpty(columnName)) {
							Cursor cursor = getContentResolver().query(uri, new String[] { columnName }, null, null, null);
							if (cursor != null) {
								String path = "";
								if (cursor.moveToNext()) {
									path = cursor.getString(0);
								}
								cursor.close();

								switch (requestCode) {
								case REQUEST_CODE_IMPORT_IMAGE://导入图片
									importImageOrVideo(path);
									break;
								case REQUEST_CODE_IMPORT_VIDEO:
									if (saveMediaObject(mMediaObject)) {
										startActivityForResult(new Intent(this, ImportVideoActivity.class).putExtra("obj", mMediaObject.getObjectFilePath()).putExtra("path", path), REQUEST_CODE_IMPORT_VIDEO_EDIT);
									}
									break;
								}
							}
						}
					}
				}
			}
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

	@SuppressWarnings("deprecation")
	private void showImportMenu() {
		View view = LayoutInflater.from(this).inflate(R.layout.menu_record_import, null);
		mPopupWindow = new PopupWindow(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);
		view.findViewById(R.id.import_image).setOnClickListener(this);
		view.findViewById(R.id.import_video).setOnClickListener(this);
		mPopupWindow.setFocusable(true);
		mPopupWindow.setOutsideTouchable(true);
		mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
		view.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		mPopupWindow.showAsDropDown(mRecordImport, 0, -view.getMeasuredHeight() - mRecordImport.getHeight());
	}

	/** 加载滤镜 */
	private void loadFilter() {
		if (!isFinishing() && mRecordFilterContainer.getChildCount() == 0) {
			final String[] filterNames = getResources().getStringArray(R.array.record_filter);
			int leftMargin = ConvertToUtils.dipToPX(this, 10);
			LayoutInflater mInflater = LayoutInflater.from(this);
			for (int i = 0; i < FILTER_ICONS.length; i  ) {
				ThemeRadioButton filterView = (ThemeRadioButton) mInflater.inflate(R.layout.view_radio_item, null);
				filterView.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						int index = ConvertToUtils.toInt(v.getTag().toString());
						if (mMediaRecorder != null)
							mMediaRecorder.setCameraFilter(FILTER_VALUES[index]);
					}
				});
				filterView.setCompoundDrawablesWithIntrinsicBounds(0, FILTER_ICONS[i], 0, 0);
				filterView.setText(filterNames[i]);
				filterView.setTag(i);
				RadioGroup.LayoutParams lp = new RadioGroup.LayoutParams(RadioGroup.LayoutParams.WRAP_CONTENT, RadioGroup.LayoutParams.WRAP_CONTENT);
				lp.leftMargin = leftMargin;
				mRecordFilterContainer.addView(filterView, lp);
			}

			mRecordFilterContainer.getChildAt(0).performClick();
		}
	}

	@Override
	public void onPrepared() {
		if (mMediaRecorder != null) {
			//自动对焦
			mMediaRecorder.autoFocus(new AutoFocusCallback() {

				@Override
				public void onAutoFocus(boolean success, Camera camera) {
					if (success) {

					}
				}
			});
		}
	}
}


标签: 视频

实例下载地址

android 按住拍 短视频 例子源码

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 柯柯柯柯柯柯。 发表于: 2016-10-20 11:17 00
赞助了10快下载下来结果用的是别人的SDK,醉了也是

支持(0) 盖楼(回复)

第 2 楼 Connor 发表于: 2017-03-15 10:52 24
66666666666666666666666666666666666666666666

支持(0) 盖楼(回复)

第 3 楼 aa2380691247 发表于: 2017-03-21 09:49 15
贡献了10块钱~结果是VCamera的sdk

支持(0) 盖楼(回复)

第 4 楼 aa2380691247 发表于: 2017-03-21 09:49 22
贡献了10块钱~结果是VCamera的sdk

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有11条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警