android sd卡列目录文件_Android SDCard文件、目录操作【转】

博客围绕Android系统展开,介绍了其基于Linux内核的安全架构,应用程序有受限用户和组,权限分root、system和应用权限。还阐述了对SD卡进行读写需加入许可权限,以及SD卡下的文件操作,如判断是否插入、获取根目录、新建目录等。

一、权限问题

Android框架是基于Linux内核构建,所以Android安全系统也是基于Linux的安全架构建立的。在Linux安全系统中,用户和组起着重要的作用,Linux中所有的资源给不同的用户和用户组设置了不同的访问属性。

在Android系统中,系统为每一个应用程序(apk)创建了一个用户和组。这个用户和组都是受限用户,不能访问系统的数据,只能访问自己的文件和目录,当然它也不能访问其他应用程序的数据。这样设计可以尽可能地保护应用程序的私有数据,增强系统的安全性和健壮性。

通过一些资料,大体可了解,android作为以linux为内核的系统,它的权限也分为root、sysyem、应用权限(受限,只可访问程序本身的目录和文件)。

要对SDCard进行读写操作,需要加入许可权限:

二、SD卡下的文件操作

1、判断SD卡是否插入

boolean sdCardExist = Environment.getExternalStorageState()

.equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在

2、获得sd卡根目录:

if (sdCardExist) {

File dir = Environment.getExternalStorageDirectory();

path = dir.getAbsolutePath();

}

3、新建目录

boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在

if (sdCardExist) {

File dir = Environment.getExternalStorageDirectory();

path=dir.getPath()+"/";

File dir= new File(path+ "123");

dir.mkdir();

}

运行结果:

package cn.zust.takephoto2; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.FileProvider; import android.Manifest; import android.annotation.SuppressLint; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.MediaStore; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; public class MainActivity extends AppCompatActivity { private static String[] items = new String[]{ "拍照", "从相册中选择", }; public static final int TAKE_PHOTO=1;//声明一个请求码,用于识别返回的结果 private static final int SCAN_OPEN_PHONE = 2;// 相册 private Uri imageUri; public String path=null; Bitmap bitmap; public String picpath=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); askPermission(); choosePic(); //aiAlgorithm } private void askPermission(){ ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA },0); } private void choosePic(){ AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this) .setTitle("请选择图片")//设置对话框 标题 .setItems(items, new DialogInterface.OnClickListener() { @RequiresApi(api = Build.VERSION_CODES.N) @Override public void onClick(DialogInterface dialog, int which) { if(which==0){ openCamera(); } else{ openGallery(); } return; } }); builder.create() .show(); } private void openGallery() { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); //intent.setType("image/*"); startActivityForResult(intent, SCAN_OPEN_PHONE); } @RequiresApi(api = Build.VERSION_CODES.N) private void openCamera(){ String imageName = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(new Date()); // File outputImage=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/data/com.example.woundapplication/"+imageName+".jpg"); File outputImage = new File(getExternalCacheDir(), imageName+".jpg"); Objects.requireNonNull(outputImage.getParentFile()).mkdirs(); // Log.e("", outputImage.getAbsolutePath()); /* 创建一个File文件对象,用于存放摄像头拍下的图片, 把它存放在应用关联缓存目录下,调用getExternalCacheDir()可以得到这个目录,为什么要 用关联缓存目录呢?由于android6.0开始,读写sd卡列为了危险权限,使用的时候必须要有权限, 应用关联目录则可以跳过这一步 */ try//判断图片是否存在,存在则删除在创建,不存在则直接创建 { if(outputImage.exists()) { outputImage.delete(); } boolean a = outputImage.createNewFile(); Log.e("createNewFile", String.valueOf(a)); } catch (IOException e) { e.printStackTrace(); } if(Build.VERSION.SDK_INT>=24) //判断安卓的版本是否高于7.0,高于则调用高于的方法,低于则调用低于的方法 //把文件换成Uri对象 /* 因为android7.0以后直接使用本地真实路径是不安全的,会抛出异常。 FileProvider是一种特殊的内容提供器,可以对数据进行保护 */ { imageUri= FileProvider.getUriForFile(MainActivity.this, "com.buildmaterialapplication.fileprovider",outputImage); //对应Mainfest中的provider // imageUri=Uri.fromFile(outputImage); path=imageUri.getPath(); Log.e(">7:",path); } else { imageUri= Uri.fromFile(outputImage); path=imageUri.getPath(); Log.e("<7:",imageUri.getPath()); } //使用隐示的Intent,系统会找到与它对应的活动,即调用摄像头,并把它存储 Intent intent0=new Intent("android.media.action.IMAGE_CAPTURE"); intent0.putExtra(MediaStore.EXTRA_OUTPUT,imageUri); startActivityForResult(intent0,TAKE_PHOTO); } @SuppressLint("SetTextI18n") protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); ImageView img_result=(ImageView) findViewById(R.id.pic); switch (requestCode) { case TAKE_PHOTO: if (resultCode == RESULT_OK) { //将图片解析成Bitmap对象,并把它显现出来 // String filePath = getFilesDir().getAbsolutePath()+"/image.jpeg"; // bitmap = BitmapFactory.decodeFile(filePath); //注意bitmap,后面再decode就会为空 try { bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri)); } catch (FileNotFoundException e) { e.printStackTrace(); } // bitmap = BitmapFactory.decodeFile(picpath); picpath=imageUri.getPath().toString(); Log.e("", imageUri.getAuthority()); Log.e("picpath",picpath); @SuppressLint("SdCardPath") String fileName = picpath; img_result.setImageBitmap(bitmap); img_result.invalidate(); } break; case SCAN_OPEN_PHONE: if (resultCode == RESULT_OK){ Uri selectImage=data.getData(); String[] FilePathColumn={MediaStore.Images.Media.DATA}; Cursor cursor = getContentResolver().query(selectImage, FilePathColumn, null, null, null); cursor.moveToFirst(); //从数据视图中获取已选择图片的路径 int columnIndex = cursor.getColumnIndex(FilePathColumn[0]); picpath = cursor.getString(columnIndex); Log.e("picpath",picpath); cursor.close(); bitmap = BitmapFactory.decodeFile(picpath); img_result.setImageBitmap(bitmap); img_result.invalidate(); } break; default: break; } } } activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <ImageView android:id="@+id/pic" android:layout_width="300dp" android:layout_height="500dp" android:layout_gravity="center"></ImageView> </LinearLayout> 在上书代码中加载照片过程中加入圈等待动画效果 给出完整的修改后的代码,要圈加载不要进度条
05-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值