Android---Uri full solution

Table of contents

Introduction to Uri

UriMatcher

Your content

Get the ID behind the Uri path

get id from path

Mutual conversion between uri, file and path

Uri file

Uri to path

file 转Uri

file to path

path to Uri

path to file

Uri encapsulated by document

Uri form before Android4.4

Uri form after Android4.4

Analyze the document by getting the image path code

Get image path after Android4.4

Uri content obtained above 4.4

Determine whether the Uri is document-encapsulated

Get the specified row in the image database data table

Get the Uri's path getAuthority()

Observe how to get the full path of the picture

Get image path before Android4.4

A demo that calls the album to get pictures

Regular Uri


Introduction to Uri

Universal Resource Identifier (Uri for short)

Uri represents the data to be operated, and resources (images, video clips) available on Android can be represented by Uri

Android's Uri consists of the following three parts

1. "content://", data path, identification ID (optional)

e.g. all images

1. Uri:content://media/external

2. Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

a picture

Uri:content://media/external/images/media/4

Android provides two tool classes for manipulating Uri, namely UriMatcher and ContentUris

UriMatcher

The UriMatcher class is mainly used to match Uri

public static final int BOOK_DIR = 0;
public static final int BOOK_ITEM = 1;
 
//第一步,初始化
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);  
 
//第二步,注册待匹配的Uri
matcher.addURI(AUTHORITY,"book",BOOK_DIR);
matcher.addURI(AUTHORITY,"book/#",BOOK_ITEM);
 
//第三步,进行匹配
Uri uri = Uri.parse("content://" + "com.example.yy" + "/book");  
int match = matcher.match(uri);  
       switch (match){
           case BOOK_DIR:  
               return "vnd.android.cursor.dir/book";  
           case BOOK_ITEM:  
               return "vnd.android.cursor.item/book";  
           default:  
               return null;  
       }  
//上面返回的是Uri对应的MIME

Your content

Get the ID behind the Uri path

//比如有这样一个Uri
Uri uri = Uri.parse("content://com.example.yy/book");
 
//通过ContentUris的withAppendedId()方法,为该Uri加上ID  
Uri resultUri = ContentUris.withAppendedId(uri, 10);
 
//最后resultUri为: 
//content://com.example.yy/book/10 

get id from path

Uri uri = Uri.parse("content://com.example.yy/book/10")  
long personid = ContentUris.parseId(uri);  

Mutual conversion between uri, file and path

Uri file

File = new File(new URI(uri.toString)));

Uri to path

private String getPath(Context context, Uri uri) {  
        String path = null;
        Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
        if (cursor == null) {
            return null;
        }
        if (cursor.moveToFirst()) {
            try {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        cursor.close();
        return path;
 }

file 转Uri

URI uri = file.toURI();

file to path

string path = file.getPath();

path to Uri

Uri uri = Uri.parse(path);

path to file

File file = new File(path);

Uri encapsulated by document

Uri form before Android4.4

Uri : content://media/extenral/images/media/17766

Uri form after Android4.4

content://com.android.providers.media.documents/document/image%3A82482

It can be seen that the system above 4.4 has been packaged with document

Analyze the document by getting the image path code

Get image path after Android4.4

private void handleImageOkKitKat(Intent data) {
        String imagePath=null;
        Uri uri = data.getData();
        Log.d("intent.getData :",""+uri);
        if (DocumentsContract.isDocumentUri(this,uri)){
            String docId = DocumentsContract.getDocumentId(uri);
            Log.d("getDocumentId(uri) :",""+docId);
            Log.d("uri.getAuthority() :",""+uri.getAuthority());
            if ("com.android.providers.media.documents".equals(uri.getAuthority())){
                String id = docId.split(":")[1];
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
            }
            else if ("com.android,providers.downloads.documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));
                imagePath = getImagePath(contentUri,null);
            }
 
        }
        else if ("content".equalsIgnoreCase(uri.getScheme())){
            imagePath = getImagePath(uri,null);
        }
        displayImage(imagePath);
    }

Uri content obtained above 4.4

Uri uri = data.getData(); Log.d("intent.getData :",""+uri);

Running result: D/uri=intent.getData::: content://com.android.providers .media.documents/document/image%3A82483 You can see that the Uri is different from the previous system version. Select different pictures to observe that the Uri is the same .

Determine whether the Uri is document-encapsulated

Static method: isDocumentUri(Context context, Uri uri)

DocumentsContract.isDocumentUri(this,uri

Get the specified row in the image database data table

Static method: getDocumentId(Uri uri)

String docId = DocumentsContract.getDocumentId(uri);

Running result: D/getDocumentId(uri) :: image:82482 returns a character string, which actually represents the location of the row in the database data table where the picture is stored.

Get the Uri's path getAuthority()

Object methods belonging to the Uri object.

uri.getAuthority()

Running result: D/uri.getAuthority() :: com.android.providers.media.documents can be judged by comparing the composition of Uri. "content://" + data path + mark ID (optional)

If the path is different, the way to get the picture is different

 if ("com.android.providers.media.documents".equals(uri.getAuthority())){
                String id = docId.split(":")[1];
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection); }
            else if ("com.android,providers.downloads.documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));
                imagePath = getImagePath(contentUri,null);
            }

 

The pictures under com.android.providers.media.documents path are specially packaged,

And com.android.providers.downloads.documents does not.

Observe how to get the full path of the picture

Here, observe the code of the method (getImagePath) to obtain the complete path of the image. The essence is to use the content provider to obtain data:

public String getImagePath(Uri uri,String selection) {
        String path = null;
        Cursor cursor = getContentResolver().query(uri,null,selection,null,null);   //内容提供器
        if (cursor!=null){
            if (cursor.moveToFirst()){
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));   //获取路径
            }
        }
        cursor.close();
        return path;
    }

From the above, we can know that com.android.providers.media.documents use document package to add MediaStore.Images.Media.DATA column to the data table to form a new database

MediaStore.Images.Media.EXTERNAL_CONTENT_URI can only be queried based on MediaStore.Images.Media.DATA. At this time, the id (id does not refer to the docID of the previous getDocumentId(uri), but the numerical label obtained by dividing the docID with: ) is The label corresponding to the MediaStore.Images.Media.DATA column of the image row.

The com.android.providers.downloads.documents path is stored as a Uri in the form of versions prior to 4.4.

Get image path before Android4.4

private void handleImageBeforeKitKat(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri,null);
        displayImage(imagePath);
    }

Uri contains the id of the row where the picture is located.

Uri : content://media/extenral/images/media/17766

The path can be easily obtained using a content provider.

A demo that calls the album to get pictures

public class MainActivity extends AppCompatActivity {
 
 
    private static final int TAKE_PHOTO = 1;
    private static final int CROP_PHOTO = 2;
    private static final int CHOOSE_PIC = 3;
    private Button takePhoto;
    private Button choosePicture;
    private ImageView picture;
    Uri imageUri;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        picture = (ImageView) findViewById(R.id.picture);
        takePhoto = (Button) findViewById(R.id.take_photo);
        takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                File outputFile = new File(Environment.getExternalStorageDirectory(),"output_image.jpg");
                try{
                    if (outputFile.exists()){
                        outputFile.delete();
                    }
                    outputFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                imageUri = Uri.fromFile(outputFile);
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                startActivityForResult(intent,TAKE_PHOTO);
            }
        });
        choosePicture = (Button) findViewById(R.id.choose_picture);
        choosePicture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("android.intent.action.GET_CONTENT");
                intent.setType("image/*");
                startActivityForResult(intent,CHOOSE_PIC);
            }
        });
 
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        switch (requestCode){
            case TAKE_PHOTO:
                if (resultCode==RESULT_OK){
                    Intent intent = new Intent("com.android.camera.action.CROP");
                    intent.setDataAndType(imageUri,"image/*");
                    intent.putExtra("scale", true);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                    startActivityForResult(intent,CROP_PHOTO);
                }
                break;
            case CROP_PHOTO:
                if (resultCode==RESULT_OK){
                    try {
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                        picture.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case CHOOSE_PIC:
                if (resultCode==RESULT_OK){
                    if (Build.VERSION.SDK_INT>=19){
                        handleImageOkKitKat(data);
                    }
                    else{
                        handleImageBeforeKitKat(data);
                    }
                }
            default:
                break;
        }
    }
 
    private void handleImageBeforeKitKat(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri,null);
        displayImage(imagePath);
    }
 
    private void handleImageOkKitKat(Intent data) {
        String imagePath=null;
        Uri uri = data.getData();
        Log.d("uri=intent.getData :",""+uri);
        if (DocumentsContract.isDocumentUri(this,uri)){
            String docId = DocumentsContract.getDocumentId(uri);        //数据表里指定的行
            Log.d("getDocumentId(uri) :",""+docId);
            Log.d("uri.getAuthority() :",""+uri.getAuthority());
            if ("com.android.providers.media.documents".equals(uri.getAuthority())){
                String id = docId.split(":")[1];
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
            }
            else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));
                imagePath = getImagePath(contentUri,null);
            }
 
        }
        else if ("content".equalsIgnoreCase(uri.getScheme())){
            imagePath = getImagePath(uri,null);
        }
        displayImage(imagePath);
    }
 
    private void displayImage(String imagePath) {
        if (imagePath!=null){
            Bitmap bitImage = BitmapFactory.decodeFile(imagePath);
            picture.setImageBitmap(bitImage);
        }
        else{
            Toast.makeText(MainActivity.this,"failed to get image",Toast.LENGTH_SHORT).show();
        }
    }
 
    public String getImagePath(Uri uri,String selection) {
        String path = null;
        Cursor cursor = getContentResolver().query(uri,null,selection,null,null);   //内容提供器
        if (cursor!=null){
            if (cursor.moveToFirst()){
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));   //获取路径
            }
        }
        cursor.close();
        return path;
    }
}

Regular Uri

显示网页: 
  1. Uri uri = Uri.parse("http://www.google.com"); 
  2. Intent it = new Intent(Intent.ACTION_VIEW,uri); 
  3. startActivity(it); 
 
显示地图: 
  1. Uri uri = Uri.parse("geo:38.899533,-77.036476"); 
  2. Intent it = new Intent(Intent.Action_VIEW,uri); 
  3. startActivity(it); 
 
路径规划: 
  1. Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en"); 
  2. Intent it = new Intent(Intent.ACTION_VIEW,URI); 
  3. startActivity(it); 
 
拨打电话: 
调用拨号程序 
  1. Uri uri = Uri.parse("tel:xxxxxx"); 
  2. Intent it = new Intent(Intent.ACTION_DIAL, uri);   
  3. startActivity(it);   
  1. Uri uri = Uri.parse("tel.xxxxxx"); 
  2. Intent it =new Intent(Intent.ACTION_CALL,uri); 
  3. 要使用这个必须在配置文件中加入<uses-permission id="Android.permission.CALL_PHONE" /> 
 
发送SMS/MMS 
调用发送短信的程序 
  1. Intent it = new Intent(Intent.ACTION_VIEW); 
  2. it.putExtra("sms_body", "The SMS text"); 
  3. it.setType("vnd.android-dir/mms-sms"); 
  4. startActivity(it);   
发送短信 
  1. Uri uri = Uri.parse("smsto:0800000123"); 
  2. Intent it = new Intent(Intent.ACTION_SENDTO, uri); 
  3. it.putExtra("sms_body", "The SMS text"); 
  4. startActivity(it);   
发送彩信 
  1. Uri uri = Uri.parse("content://media/external/images/media/23"); 
  2. Intent it = new Intent(Intent.ACTION_SEND); 
  3. it.putExtra("sms_body", "some text"); 
  4. it.putExtra(Intent.EXTRA_STREAM, uri); 
  5. it.setType("image/png"); 
  6. startActivity(it); 
 
发送Email 
  1. 
  2. Uri uri = Uri.parse("mailto:[email protected]"); 
  3. Intent it = new Intent(Intent.ACTION_SENDTO, uri); 
  4. startActivity(it); 
  1. Intent it = new Intent(Intent.ACTION_SEND); 
  2. it.putExtra(Intent.EXTRA_EMAIL, "[email protected]"); 
  3. it.putExtra(Intent.EXTRA_TEXT, "The email body text"); 
  4. it.setType("text/plain"); 
  5. startActivity(Intent.createChooser(it, "Choose Email Client"));   
  1. Intent it=new Intent(Intent.ACTION_SEND);   
  2. String[] tos={"[email protected]"};   
  3. String[] ccs={"[email protected]"};   
  4. it.putExtra(Intent.EXTRA_EMAIL, tos);   
  5. it.putExtra(Intent.EXTRA_CC, ccs);   
  6. it.putExtra(Intent.EXTRA_TEXT, "The email body text");   
  7. it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");   
  8. it.setType("message/rfc822");   
  9. startActivity(Intent.createChooser(it, "Choose Email Client")); 
 
添加附件 
  1. Intent it = new Intent(Intent.ACTION_SEND); 
  2. it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text"); 
  3. it.putExtra(Intent.EXTRA_STREAM, "[url=]file:///sdcard/mysong.mp3[/url]"); 
  4. sendIntent.setType("audio/mp3"); 
  5. startActivity(Intent.createChooser(it, "Choose Email Client")); 
 
播放多媒体 
  1.   
  2. Intent it = new Intent(Intent.ACTION_VIEW); 
  3. Uri uri = Uri.parse("[url=]file:///sdcard/song.mp3[/url]"); 
  4. it.setDataAndType(uri, "audio/mp3"); 
  5. startActivity(it); 
  1. Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1"); 
  2. Intent it = new Intent(Intent.ACTION_VIEW, uri); 
  3. startActivity(it);   
 
Uninstall 程序 
  1. Uri uri = Uri.fromParts("package", strPackageName, null); 
  2. Intent it = new Intent(Intent.ACTION_DELETE, uri); 
  3. startActivity(it); 
 
//调用相册 
public static final String MIME_TYPE_IMAGE_JPEG = "image/*"; 
public static final int ACTIVITY_GET_IMAGE = 0; 
Intent getImage = new Intent(Intent.ACTION_GET_CONTENT); 
getImage.addCategory(Intent.CATEGORY_OPENABLE); 
getImage.setType(MIME_TYPE_IMAGE_JPEG); 
startActivityForResult(getImage, ACTIVITY_GET_IMAGE); 
 
//调用系统相机应用程序,并存储拍下来的照片 
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
time = Calendar.getInstance().getTimeInMillis(); 
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment 
.getExternalStorageDirectory().getAbsolutePath()+"/tucue", time + ".jpg"))); 
startActivityForResult(intent, ACTIVITY_GET_CAMERA_IMAGE); 
 
uninstall apk 
/**未测试 
Uri uninstallUri = Uri.fromParts("package", "xxx", null); 
returnIt = new Intent(Intent.ACTION_DELETE, uninstallUri); 
*/ 
Uri packageURI = Uri.parse("package:"+wistatmap);   
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);   
startActivity(uninstallIntent); 
 
install apk 
Uri installUri = Uri.fromParts("package", "xxx", null); 
returnIt = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri); 
play audio 
Uri playUri = Uri.parse("[url=]file:///sdcard/download/everything.mp3[/url]"); 
returnIt = new Intent(Intent.ACTION_VIEW, playUri); 
 
//发送附件 
Intent it = new Intent(Intent.ACTION_SEND);   
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");   
it.putExtra(Intent.EXTRA_STREAM, "[url=]file:///sdcard/eoe.mp3[/url]");   
sendIntent.setType("audio/mp3");   
startActivity(Intent.createChooser(it, "Choose Email Client")); 
 
//搜索应用 
Uri uri = Uri.parse("market://search?q=pname:pkg_name");   
Intent it = new Intent(Intent.ACTION_VIEW, uri);   
startActivity(it);   
//where pkg_name is the full package path for an application 
 
//进入联系人页面 
Intent intent = new Intent(); 
intent.setAction(Intent.ACTION_VIEW); 
intent.setData(People.CONTENT_URI); 
startActivity(intent); 
 
//查看指定联系人 
Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, info.id);//info.id联系人ID 
Intent intent = new Intent(); 
intent.setAction(Intent.ACTION_VIEW); 
intent.setData(personUri);
 
startActivity(intent); 


Guess you like

Origin blog.csdn.net/luoro/article/details/126508921