Android获取联系人列表,本地图片路径以及拍照显示(杂记)

1.获取联系人列表,代码如下:

    private String[] getContacts() {
        Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        String[] projects = new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};

        Cursor cursor = getContentResolver().query(uri,projects,null,null,null);
        String[] contacts = null;
        int index=0;
        try{
            Log.i("Contact-C","count : "+cursor.getCount());
            contacts = new String[cursor.getCount()];
            cursor.moveToFirst();
            while (!cursor.isAfterLast()){
                String name = cursor.getString(0);
                String number = cursor.getString(1);
                Log.i("Contact-C",name+" : "+number+" ---------------  index = "+index);
                contacts[index] = name+" : "+number;
                index++;
                cursor.moveToNext();
            }
        }finally {
            index = 0;
            cursor.close();
        }

        return contacts;
    }

Demo下载链接:github demo,在NormalDemo/app/build/outputs/apk/debug下有Demo apk可直接安装运行查看效果


2. 获取本地图片路径:

    public void getLocalImagePath(){
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, REQ_SELECT_IMAGE);
    }
上述代码是选择图片,在onActivityResult获取路径:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQ_SELECT_IMAGE){
            Uri imageUri = data.getData();
            String imagePath = getRealPathFromURI(data.getData());
        }
    }

    private String getRealPathFromURI(Uri contentURI) {
        String result;
        Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
        if (cursor == null) { // Source is Dropbox or other similar local file path
            result = contentURI.getPath();
        } else {
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            result = cursor.getString(idx);
            cursor.close();
        }
        return result;
    }


3. Camera拍照并重定向照片存储位置以及显示

相机拍摄的照片较大,需要在设备的文件系统中存储。Context提供的基本目录和目录处理系统如下:

(1)File getFilesDir()

获取/data/data/<包名>/files目录。

(2)FileInputStream openFileInput(String name)

打开现有文件进行读取。

(3)FileOutputStream openFileOutput(String name, int mode)

打开文件进行写入,如果不存在就创建它。

(4)File getDir(String name, int mode)

获取/data/data/<包名>/目录的子目录(如果不存在就先创建它)。

(5)String[] fileList()

获取主文件目录下的文件列表。可与其他方法配合使用,如openFileInput(String)。

(6)File getCacheDir()

获取/data/data/<包名>/cache目录。应注意及时清理该目录,并节约使用。


我们打算用getFilesDir()来存储拍摄的照片,这时候有一个问题,系统Camera拍摄的照片都会存储在系统指定的目录下,我们可以使用Gallery浏览,那如何将拍摄的照片重定向存储到应有的所在的目录呢。

如果想共享文件给其他应用,或是接收其他应用的文件(如相机应用拍摄的照片),可以通 过ContentProvider把要共享的文件暴露出来。ContentProvider允许你暴露内容URI给其他应 用。在Android中,如果只是从其他应用接收一个文件,我们可以使用FileProvider,唯一需要做的就是做一些简单的配置,接下来介绍。


1. 配置AndroidManifest.xml:

        <provider
            android:authorities="org.doit.canvas.demo.fileprovider"
            android:name="android.support.v4.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">

            <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file">
            </meta-data>
        </provider>
由于FileProvider是ContentProvider的子类,我们需要在AndroidManifest中进行声明。上述配置中,authorities是授权的权限,name则是FileProvider完整的包路径,exported表示除了授权的人和自己以外,其他人禁止使用FileProvider,grantUriPermissions用来给其他应用授权,允许其他人向你指定的Uri写入数据。meta-data告诉FileProvider该暴露那些文件。

file.xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="take_photo"
        path="."></files-path>
</paths>

这是个描述性XML文件,其表达的意思是,把私有存储空间的根路径映射为take_photo。 这个名字仅供FileProvider内部使用,你不应去用它。


以上就是Manifest中的配置,以下是代码部分:

    private void capturePhoto(){

        Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        boolean canTake = captureIntent.resolveActivity(getPackageManager()) != null;
        Log.i("TakePhoto","canTake : "+canTake);
        if (canTake){
            Uri fileUri = FileProvider.getUriForFile(this,"org.doit.canvas.demo.fileprovider",getPhotoFile());
            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT,fileUri);
            List<ResolveInfo> resolveInfoList = getPackageManager().queryIntentActivities(captureIntent,PackageManager.MATCH_DEFAULT_ONLY);
            for (ResolveInfo resolveInfo:resolveInfoList){
                grantUriPermission(resolveInfo.activityInfo.packageName,fileUri,Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            }
            startActivityForResult(captureIntent,REQ_CAPTURE_PHOTO);
        }
    }
    private File getPhotoFile(){
        File parentFile = getFilesDir();
        return new File(parentFile,"capture_1.jpg");
    }
上述代码中,使用隐式Intent,MediaStore.ACTION_IMAGE_CAPTURE进行拍照。首先检查手机中是否有Camera应用,以免调用出现错误。接着我们获取应用的私有目录,并使用FileProvider将目录转化为Uri并使用MediaStore.EXTRA_OUTPUT重定向照片的存储位置。最后对Camera应用使用grantUriPermission()进行Uri写入的授权操作。由于手机中的Camera应用可能不止一个,还可能有美颜,美图之类的第三方应用,所以我们需要对所有Camera应用进行授权。

在onActivityResult回调函数中:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQ_TAKE_PHOTO){
            Bitmap bitmap = Utils.getScaleBitmap(getPhotoFile().getPath(),400,400);
            mImageView.setImageBitmap(bitmap);
            Uri fileUri = FileProvider.getUriForFile(this,"org.doit.canvas.demo.fileprovider",getPhotoFile());

            revokeUriPermission(fileUri,Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        }
    }
    public static Bitmap getScaleBitmap(String path,int destHeight,int destWidth){
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(path,options);

        int originalWidth = options.outWidth;
        int originalHeight = options.outHeight;

        int inSampleSize = 1;
        if (originalHeight > destHeight || originalWidth > destWidth){
            float scaleWidth = originalWidth / destWidth;
            float scaleHeight = originalHeight / destHeight;

            inSampleSize = Math.round(scaleHeight>scaleWidth? scaleHeight:scaleWidth);
        }

        options.inSampleSize = inSampleSize;
        options.inJustDecodeBounds=false;

        return BitmapFactory.decodeFile(path,options);
    }
在代码中,我们获取拍摄的图片之后对图片进行了处理之后进行显示,如果处理部分的代码看不懂的话, 点击阅读此博客。图片显示之后,需要使用revokeUriPermission取消去应用的Uri写入权限。
具体可以阅读一下博客: Android 7.0 行为变更 通过FileProvider在应用间共享文件吧
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值