大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
打开相册选择图片裁剪:https://blog.csdn.net/Code_legend/article/details/77620359
https://blog.csdn.net/zz110753/article/details/60877594
图片选择框架:星级最多https://github.com/LuckSiege/PictureSelector
https://github.com/wildma/PictureSelector
https://github.com/HuanTanSheng/EasyPhotos
自定义的一些请求码:
private static final int CODE_GALLERY_REQUEST = 0xa0; private static final int CODE_CAMERA_REQUEST = 0xa1; private static final int CODE_RESULT_REQUEST = 0xa2; private static final int CAMERA_PERMISSIONS_REQUEST_CODE = 0x03; private static final int STORAGE_PERMISSIONS_REQUEST_CODE = 0x04; private static final int CHOOSE_PHOTO = 0x05;
检查权限、动态请求权限、权限回调
/**
* 动态申请sdcard读写权限
*/
private void autoObtainStoragePermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSIONS_REQUEST_CODE);
} else {
}
} else {
}
}
/**自Android 6.0以后对某些涉及用户隐私权限的获取需要动态获取,所以首先是检查权限,如没有权限则动态申请权限,这里我们需要用到的权限是WRITE_EXTERNAL_STORAGE和CAMERA。
* FileProvider是ContentProvider的一个子类,用于应用程序之间私有文件的传递。自Android 7.0后系统禁止应用向外部公开file://URI ,
* 因此需要FileProvider来向外界传递URI,传递的形式是content : //Uri,使用时需要在清单文件中注册。
*
*
* 申请访问相机权限
*/
private void autoObtainCameraPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkPermission()) {//检查权限
//没有权限,发送权限请求
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CAMERA)) {
Toast.makeText(getActivity(), "您已经拒绝过一次了", Toast.LENGTH_SHORT).show();
}
//请求相机权限
requestPermissions();
} else {//有权限直接调用系统相机拍照
if (hasSdcard()) {//sd卡挂载上了,可读可写
//打开相机
} else {
Toast.makeText(getActivity(), "没有SD卡", Toast.LENGTH_SHORT).show();
}
}
}
}
//检查权限
private boolean checkPermission() {
//是否有权限
boolean haveCameraPermission = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
boolean haveWritePermission = ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
return haveCameraPermission && haveWritePermission;
}
// 请求相机权限和sd卡权限
@RequiresApi(api = Build.VERSION_CODES.M)
private void requestPermissions() {
requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, CAMERA_PERMISSIONS_REQUEST_CODE);
}
//请求权限的回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult: ");
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
//调用系统相机申请拍照权限回调
case CAMERA_PERMISSIONS_REQUEST_CODE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//允许授权
if (hasSdcard()) {
//拍照
} else {
Toast.makeText(getActivity(), "没有SD卡", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getActivity(), "请允许打开相机", Toast.LENGTH_SHORT).show();
}
break;
}
//调用系统相册申请Sdcard权限回调
case STORAGE_PERMISSIONS_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//打开相册
} else {
Toast.makeText(getActivity(), "请允许操作SD卡", Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
/**
* 检查设备是否存在SDCard的工具方法
*/
public static boolean hasSdcard() {
String state = Environment.getExternalStorageState();
return state.equals(Environment.MEDIA_MOUNTED);
}
拍照
系统相机拍照:
1.//定义一个保存图片的File变量 private File currentImageFile = null; private Uri currentImageUri=null;
/** * * 自己定义一个保存路径,(拍完的图片是不会保存到本地的, 我们可以自己写代码把图片保存到我们的SD卡里,然后再显示,这样的图片会清晰很多.) * */ public void createSavepath(){ File dir = new File(Environment.getExternalStorageDirectory(),"pictures"); if(!dir.exists()){ dir.mkdirs(); } currentImageFile = new File(dir,System.currentTimeMillis() + ".jpg"); if(!currentImageFile.exists()){ try { currentImageFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } Log.d("extra",""+dir.toString()); }
2.在res下面创建一个xml文件夹,xml下面建立file_paths.xml文件,这个文件的主要作用是向外提供content://uri路径。
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <!--files-path 相当于 getFilesDir()--> <files-path name="my_images" path="images"/> <!--cache-path 相当于 getCacheDir()--> <cache-path name="lalala" path="cache_image"/> <!--external-path 相当于 Environment.getExternalStorageDirectory()--> <external-path name="hahaha" path="."/> <!--external-files-path 相当于 getExternalFilesDir("") --> <external-files-path name="paly" path="freeSoft"/> <!--external-cache-path 相当于 getExternalCacheDir() --> <external-cache-path name="lei" path="."/> </paths>
3.manifest配置:application下面添加provide配置
<application> <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.wofu.aichi010.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
权限:
<uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4.打开相机,需要动态添加权限
方法一:这种方法是自定义路径存储图片 createSavepath();//上面自定义保存路径 currentImageUri = FileProvider.getUriForFile(getActivity(), "com.example.wofu.aichi010.fileprovider" ,currentImageFile); //打开相机 Intent it = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); it.putExtra(MediaStore.EXTRA_OUTPUT,currentImageUri);//输出到指定路径 it.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);//授予临时权限 startActivityForResult(it, Activity.DEFAULT_KEYS_DIALER);
方法二:这种方法不存储图片,
Intent it = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(it,Activity.DEFAULT_KEYS_DIALER);
5.回调获取图片
//重写onActivityResult方法,相机拍照后会返回一个intent给onActivityResult。 intent的extra部分包含一个编码过的Bitmap, // 拍完的图片是不会保存到本地的, 我们可以自己写代码把图片保存到我们的SD卡里,然后再显示,这样的图片会清晰很多. @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d("回调图片","照片"+resultCode+data+requestCode); if (resultCode == Activity.RESULT_OK) { 方式一:自定义路径中获取图片 img_show.setImageURI(currentImageUri); 方式二:直接使用图片,不存储,img_show是Imageview Bundle bundle = data.getExtras(); Bitmap bitmap = (Bitmap) bundle.get("data"); img_show.setImageBitmap(bitmap); } }
自定义相机拍照:
保存图片
—————保存图片到指定位置———
将Bitmap保存图片到指定的路径/sdcard/Boohee/下,文件名以当前系统时间命名,但是这种方法保存的图片没有加入到系统图库中
public static File saveImage(Bitmap bmp) {
File appDir = new File(Environment.getExternalStorageDirectory(), "Boohee");
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
bmp.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
———————保存图片到系统相册——-
调用以上系统自带的方法会把bitmap对象保存到系统图库中, 但是这种方法无法指定保存的路径和名称, 上述方法的title、description参数只是插入数据库中的字段, 真实的图片名称系统会自动分配。插入图库的方法图片并没有立刻显示在图库中,而我们需要立刻更新系统图库以便让用户可以立刻查看到这张图片。
MediaStore.Images.Media.insertImage(getActivity().getContentResolver(), bitmap, “title”, “description”);
录像
1.创建路线个保存路径:
//定义一个保存视频的File变量
private File currentImageFile = null;
private Uri currentImageUri=null;
public void createvideoSavepath(){ File dir = new File(Environment.getExternalStorageDirectory(),"videos"); if(!dir.exists()){ dir.mkdirs(); } currentImageFile = new File(dir,System.currentTimeMillis() + ".mp4"); if(!currentImageFile.exists()){ try { currentImageFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } Log.d("extra",""+dir.toString()); }
2.打开相机录像,fileprovide的配置参考相机拍照
createvideoSavepath(); currentImageUri = FileProvider.getUriForFile(getActivity(), "com.example.wofu.aichi010.fileprovider" ,currentImageFile); Intent intents = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); intents.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); intents.putExtra(MediaStore.EXTRA_OUTPUT, currentImageUri); startActivityForResult(intents, 10);
3.录像后回调
public void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d("回调图片","照片"+resultCode+data+requestCode); if (resultCode == Activity.RESULT_OK) { }
打开相册
***从相册选择video
/**
* 从相册中选择视频
*/
private void choiceVideo() {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 66);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 66 && resultCode == RESULT_OK && null != data) {
Uri selectedVideo = data.getData();
String[] filePathColumn = {MediaStore.Video.Media.DATA};
Cursor cursor = getContentResolver().query(selectedVideo,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
VIDEOPATH = cursor.getString(columnIndex);
cursor.close();
//根据时间路径播放视频
}
if (resultCode != Activity.RESULT_OK) {
return;
}
}
*****打开相册
方式一:这种方式会打开,页面显示错误报告、图库、文件管理,近期的图片页面,图片、视频、文件都可以选择
Intent intent = new Intent("android.intent.action.GET_CONTENT"); intent.setType("image/*"); startActivityForResult(intent, CHOOSE_PHOTO); // 打开相册
方式二:打开选择图片,显示的是一个个图片文件夹
Intent intentFromGallery = new Intent(); // 设置文件类型 intentFromGallery.setType("image/*"); intentFromGallery.setAction(Intent.ACTION_PICK); startActivityForResult(intentFromGallery, CODE_GALLERY_REQUEST);
打开相册的回调:
public void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d("回调图片","照片"+resultCode+data+requestCode); if (resultCode == Activity.RESULT_OK) {
//获取Bitmap,然后加载图片
Uri uri = data.getData(); ContentResolver resolver = getActivity().getContentResolver(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(resolver, uri); img_show.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); } //获取一些图片信 //Uri uri = data.getData(); //Cursor cursor =getActivity().getContentResolver().query(uri, null, null, null,null); //if (cursor != null && cursor.moveToFirst()) { //这里开始查询每一列的信息,有6列 // String path = cursor.getString(1);//0是内存地址,1是图片格式,如image/jpeg // Log.d("相册选择",path); // cursor.close(); //}
}
压缩图片
调用:
try {
Bitmap bitmap = getBitmapFormUri(currentImageUri);
img_show.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
//缩放图片
public Bitmap getBitmapFormUri(Uri uri) throws FileNotFoundException, IOException {
InputStream input = getContext().getContentResolver().openInputStream(uri);
//这一段代码是不加载文件到内存中也得到bitmap的真是宽高,主要是设置inJustDecodeBounds为true
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;//不加载到内存
onlyBoundsOptions.inDither = true;//optional
onlyBoundsOptions.inPreferredConfig = Bitmap.Config.RGB_565;//optional
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
input.close();
int originalWidth = onlyBoundsOptions.outWidth;
int originalHeight = onlyBoundsOptions.outHeight;
if ((originalWidth == -1) || (originalHeight == -1))
return null;
//图片分辨率以480x800为标准
float hh = 800f;//这里设置高度为800f
float ww = 480f;//这里设置宽度为480f
//缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;//be=1表示不缩放
if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大的话根据宽度固定大小缩放
be = (int) (originalWidth / ww);
} else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高的话根据宽度固定大小缩放
be = (int) (originalHeight / hh);
}
if (be <= 0)
be = 1;
//比例压缩
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = be;//设置缩放比例
bitmapOptions.inDither = true;
bitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
input = getActivity().getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
return compressImage(bitmap);//再进行质量压缩
}
//压缩图片质量
public Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();//重置baos即清空baos
//第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差 ,第三个参数:保存压缩后的数据的流
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options,把压缩后的数据存放到baos中
options -= 10;//每次都减少10
if (options<=0)
break;
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
return bitmap;
}
—————播放视频—————–
public class MainActivity extends AppCompatActivity {
private MediaPlayer mediaPlayer;
private SurfaceView sfv;
private VideoView vv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
sfv = findViewById(R.id.sfv);//可以在子线程直接更新UI
//播放视频
public void play(){
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource("http://badu.com/ddd");//要播放的数据
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.prepareAsync();//准备播放
//设置显示
final SurfaceHolder holder=sfv.getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
private int cur;
//sfv准备好了
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
mediaPlayer.setDisplay(holder);
//准备完成再开始播放
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
mediaPlayer.seekTo(cur);//上次的位置
}
});
}
//变化的时候
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
//sfv销毁的时候
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
if(mediaPlayer!=null && mediaPlayer.isPlaying()) {
//获取视频当前位置
cur = mediaPlayer.getCurrentPosition();
mediaPlayer.stop();//停止
}
}
});
}
//方法二:videoview实现视频播放
public void videoViewPlay(){
//videoView控件就是对surfaceView的封装,实现mediaplayer接口
vv = findViewById(R.id.videoV);
vv.setVideoPath("http://bas.com/ee.mp4");//播放的资源
vv.start();//开始播放
}
//方法三:vitamio框架实现视频播放
public void vitamioMobviePlay(){
}
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/192730.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...