使用範例:圖庫選擇圖片打印成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.等等………
以上的資源例子如下:
- http://write.blog.csdn.net/postedit/7313543,
- file:///c:/WINDOWS/clock.avi
- git://github.com/user/project-name.git
- ftp://user1:1234@地址
- 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中配置:
- package="com.android.providers.telephony"
- <provider android:name="TelephonyProvider"
- android:authorities="telephony"
- android:exported="true"
- android:singleUser="true"
- android:multiprocess="false" />
好了,讓我們回去看看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及它的工具類
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);