根據URI取得文件的存儲位置

使用範例:圖庫選擇圖片打印成pdf圖片後使用toast提示文件保存路徑

/frameworks/base/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java

函數    private void onFinished(Uri... uris) {  中增加以下代碼

	if(android.os.SystemProperties.getBoolean("ro.print.showtoast", false)){
		Context context = (Context)DocumentsActivity.this;
		
		String fileName = getPath(context, uris[0]);
		Log.d("jimbo", "000 fileName=" + fileName);

		if(fileName == null){  //onFinished: uri=[content://com.mediatek.hotknotbeam.documents/document/%2Fstorage%2Fsdcard0%2FHotKnot%3A333333333333333.pdf]  打印到hotknot文件中顯示不出來,所以才增加以下代碼
			// MediaStore (and general)  
			if ("content".equalsIgnoreCase(uris[0].getScheme())) {  
			      fileName = getDataColumn(context, uris[0], null, null);  
				Log.d("jimbo", "111 fileName=" + fileName);
			}  
			// File  
			else if ("file".equalsIgnoreCase(uris[0].getScheme())) {  
				fileName = uris[0].getPath();  
				Log.d("jimbo", "222 fileName=" + fileName);
			}  
		}

		Log.d("jimbo", "end fileName=" + fileName);
		// show toast
		if(fileName != null){
			String toastStr = DocumentsActivity.this.getString(R.string.title_save)+":"+ fileName;
			android.widget.Toast.makeText(this, toastStr, android.widget.Toast.LENGTH_LONG).show();
		}
	}

以下代碼是度娘到的代碼:

	public static String getPath(final Context context, final Uri uri) {  
	    // DocumentProvider  
	    if (DocumentsContract.isDocumentUri(context, uri)) {  
		//Log.d("jimbo", " 0000000000000000000" );
	        // ExternalStorageProvider  
	        if (isExternalStorageDocument(uri)) {  
	            final String docId = DocumentsContract.getDocumentId(uri);  
	            final String[] split = docId.split(":");  
	            final String type = split[0];  
			//Log.d("jimbo", " 0000000000111111111" );
	            if ("primary".equalsIgnoreCase(type)) {  
	                return android.os.Environment.getExternalStorageDirectory() + "/" + split[1];  
	            }  
	        }  
	        // DownloadsProvider  
	        else if (isDownloadsDocument(uri)) {  
	            final String id = DocumentsContract.getDocumentId(uri);  
	            final Uri contentUri = android.content.ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));  
			//Log.d("jimbo", " 00000000002222222" );
	            return getDataColumn(context, contentUri, null, null);  
	        }  
	        // MediaProvider  
	        else if (isMediaDocument(uri)) {  
	            final String docId = DocumentsContract.getDocumentId(uri);  
	            final String[] split = docId.split(":");  
	            final String type = split[0];  
	            Uri contentUri = null;  
	            if ("image".equals(type)) {  
	                contentUri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;  
	            } else if ("video".equals(type)) {  
	                contentUri = android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI;  
	            } else if ("audio".equals(type)) {  
	                contentUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;  
	            }  
	            final String selection = "_id=?";  
	            final String[] selectionArgs = new String[] {  
	                    split[1]  
	            };  
			//Log.d("jimbo", " 0000000000333333" );
	            return getDataColumn(context, contentUri, selection, selectionArgs);  
	        } 
	    }
	    // MediaStore (and general)  
	    else if ("content".equalsIgnoreCase(uri.getScheme())) {  
		//Log.d("jimbo", " 11111111111111111" );
	        return getDataColumn(context, uri, null, null);  
	    }  
	    // File  
	    else if ("file".equalsIgnoreCase(uri.getScheme())) {  
		//Log.d("jimbo", " 2222222222222" );
	        return uri.getPath();  
	    }  
<span style="white-space:pre">		</span>Log.d("jimbo", " end---------- return null" );
	    return null;  
	}  
	/** 
	 * Get the value of the data column for this Uri. This is useful for 
	 * MediaStore Uris, and other file-based ContentProviders. 
	 * 
	 * @param context The context. 
	 * @param uri The Uri to query. 
	 * @param selection (Optional) Filter used in the query. 
	 * @param selectionArgs (Optional) Selection arguments used in the query. 
	 * @return The value of the _data column, which is typically a file path. 
	 */  
	public static String getDataColumn(Context context, Uri uri, String selection,  String[] selectionArgs) {  
	    Cursor cursor = null;  
	    final String column = "_data";  
	    final String[] projection = {  
	            column  
	    };  
	    try {  
	        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,  
	                null);  
	        if (cursor != null && cursor.moveToFirst()) {  
	            final int column_index = cursor.getColumnIndexOrThrow(column);  
	            return cursor.getString(column_index);  
	        }  
	    } finally {  
	        if (cursor != null)  
	            cursor.close();  
	    }  
	    return null;  
	}  
	/** 
	 * @param uri The Uri to check. 
	 * @return Whether the Uri authority is ExternalStorageProvider. 
	 */  
	public static boolean isExternalStorageDocument(Uri uri) {  
	    return "com.android.externalstorage.documents".equals(uri.getAuthority());  
	}  
	/** 
	 * @param uri The Uri to check. 
	 * @return Whether the Uri authority is DownloadsProvider. 
	 */  
	public static boolean isDownloadsDocument(Uri uri) {  
	    return "com.android.providers.downloads.documents".equals(uri.getAuthority());  
	}  
	/** 
	 * @param uri The Uri to check. 
	 * @return Whether the Uri authority is MediaProvider. 
	 */ 
	public static boolean isMediaDocument(Uri uri) {  
	    return "com.android.providers.media.documents".equals(uri.getAuthority());  
	}  

打印後的程序log結果:

D/jimbo   ( 2630): 000 fileName=null
D/jimbo   ( 2630): 111 fileName=/storage/sdcard0/HotKnot/IMG_20150101_085108.jpg (10).pdf
D/jimbo   ( 2630): end fileName=/storage/sdcard0/HotKnot/IMG_20150101_085108.jpg (10).pdf
D/jimbo   ( 2630):  0000000000000000000
D/jimbo   ( 2630):  00000000002222222
D/jimbo   ( 2630): 000 fileName=/storage/sdcard0/Download/IMG_20150101_085108.jpg (13).pdf
D/jimbo   ( 2630): end fileName=/storage/sdcard0/Download/IMG_20150101_085108.jpg (13).pdf



以下轉自:http://blog.csdn.net/sjz4860402/article/details/51223057


URI簡介

概念:統一資源標識符(Uniform Resource Identifier)

組成部分:
    1.訪問資源的命名機制(scheme)
    2.存放資源的主機名(authority)

    3.資源自身的名稱,由路徑表示(path)

格式:scheme:// authority//path,其中authority中又包括了host和port兩部分。

例如:
content://com.example.project:200/folder/subfolder/etc
 \---------/ \----------------------------/ \----/ \------------------------/
 Scheme          host             port              path
            \------------------------------------/

                            Authority


用處:uri主要用來表示一個資源。這個資源有很多種類,包括圖片,視頻,文件等。

針對資源的種類,uri用以下幾種scheme標識:

      1.Content:主要操作的是ContentProvider,所以它代表的是數據庫中的某個資源
      2.http:一個網站資源
      3.file:本地機器上的某個資源
      4.git:git倉庫中某個資源
      5.ftp:服務器上的某個資源
      6.ed2k:(電驢協議)
      7.等等………

以上的資源例子如下:
[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. http://write.blog.csdn.net/postedit/7313543,    
  2. file:///c:/WINDOWS/clock.avi  
  3. git://github.com/user/project-name.git  
  4. ftp://user1:1234@地址  
  5. ed2k://|file|%5BMAC%E7%89%88%E6%9E%81%E5%93%81%E9%A3%9E%E8%BD%A69%EF%BC%9A%E6%9C%80%E9%AB%98%E9%80%9A%E7%BC%89%5D.%5BMACGAME%5DNeed.For.Speed.Most.Wanted.dmg|4096933888|2c55f0ad2cb7f6b296db94090b63e88e|h=ltcxuvnp24ufx25h2x7ugfaxfchjkwxa|/  

Android中,由於很多資源(音頻、視頻、圖片、以及個人通信錄信息)都存入了數據庫,所以Android中對資源的使用一般是通過ContentProivder訪問數據庫,見得比較多的就是Content這種類型的uri。所以我們這裏也只是着重講Content類型的uri。


二.uri詳解

1.Authority部分:
在看Authority之前,讓我們先了解一下ContentProvider。
ContentProvider在android中的作用是對外共享數據, 也就是說你可以通過ContentProvider把應用中的數據共享給其他應用訪問,其他應用可以通過ContentProvider對你應用中的數據進行添刪改查。那麼其他的應用該怎麼找到這個ContentProvider?答案在AndroidManifest.xml中配置:
[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package="com.android.providers.telephony"  
  2.         <provider android:name="TelephonyProvider"  
  3.                   android:authorities="telephony"  
  4.                   android:exported="true"  
  5.                   android:singleUser="true"  
  6.                   android:multiprocess="false" />  
在這裏,規定了這個TelephonyProvider內容提供者對外提供的主機(authorities)爲telephony。
   好了,讓我們回去看看content://com.example.project:200/folder/subfolder/etc這個例子。host主要是用com.example.project來表示,這根本就是一個包名啊。但是通過AndroidManifest.xml配置後,就看到了最常見的uri:

所有SIM卡信息的Uri: content:// telephony/siminfo
某張SIM卡的Uri: content:// telephony/siminfo/2
所有圖片Uri: content://media/external
某個圖片的Uri:content://media/external/images/media/4

2.path部分:
path部分就簡單了,既然Authority指定了一個ContentProvider。那麼如果我們需要某個具體的資源,就需要通過查詢數據庫表,在表中存儲的位置等等信息了。所以content:// telephony/siminfo/2中siminfo代表的是數據庫表名,2代表的是表中某個具體的數值。


三.Uri及它的工具類

1.Uri.java
Uri主要的結構如下:
Uri的內部類:
------- StringUri  子孫類,使用不明
------- OpaqueUri 子孫類,使用不明
------- HierarchicalUri子孫類,Builder構建Uri的實例對象主要是使用了這個類。
------- Builder 靜態類,用於獲取Uri實例對象。
------- ….
由於Uri的構造方法是私有的,所以它提供了Builder這個靜態類用於獲取Uri的實例對象。除了獲取對象外,它還提供了很多實用的方法,比如:
Public Uri Build()-------獲取Uri的實例對象
Public Builder encodedPath(String path)--------根據path構建Builder對象
public Builder authority(String authority)-------根據authority構建Builder對象




URI使用實例:

Uri的總結也就這些,最後,記錄一下常用的幾個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);



發佈了37 篇原創文章 · 獲贊 22 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章