Хорошие существующие ответы, некоторые из которых я использовал, чтобы придумать свой собственный:
Мне нужно получить путь из URI и получить URI из путей, и Google с трудом объясняет разницу, поэтому для тех, у кого такая же проблема (например, чтобы получить миниатюру из MediaStore
видео, физическое местоположение которого у вас уже есть). Первый:
/**
* Gets the corresponding path to a file from the given content:// URI
* @param selectedVideoUri The content:// URI to find the file path from
* @param contentResolver The content resolver to use to perform the query.
* @return the file path as a string
*/
private String getFilePathFromContentUri(Uri selectedVideoUri,
ContentResolver contentResolver) {
String filePath;
String[] filePathColumn = {MediaColumns.DATA};
Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePath = cursor.getString(columnIndex);
cursor.close();
return filePath;
}
Последний (который я делаю для видео, но также можно использовать для аудио или файлов или других типов хранимого контента, заменив MediaStore.Audio (и т. Д.) На MediaStore.Video):
/**
* Gets the MediaStore video ID of a given file on external storage
* @param filePath The path (on external storage) of the file to resolve the ID of
* @param contentResolver The content resolver to use to perform the query.
* @return the video ID as a long
*/
private long getVideoIdFromFilePath(String filePath,
ContentResolver contentResolver) {
long videoId;
Log.d(TAG,"Loading file " + filePath);
// This returns us content://media/external/videos/media (or something like that)
// I pass in "external" because that's the MediaStore's name for the external
// storage on my device (the other possibility is "internal")
Uri videosUri = MediaStore.Video.Media.getContentUri("external");
Log.d(TAG,"videosUri = " + videosUri.toString());
String[] projection = {MediaStore.Video.VideoColumns._ID};
// TODO This will break if we have no matching item in the MediaStore.
Cursor cursor = contentResolver.query(videosUri, projection, MediaStore.Video.VideoColumns.DATA + " LIKE ?", new String[] { filePath }, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
Log.d(TAG,"Video ID is " + videoId);
cursor.close();
return videoId;
}
По сути, столбец DATA
в MediaStore
(или в каком из его подразделов вы запрашиваете) хранит путь к файлу, так что вы можете использовать то, что знаете, чтобы найти этот DATA
или используйте поле для поиска того, что вы хотите.
Затем я дополнительно использую Scheme
, как указано выше, чтобы выяснить, что делать с моими данными:
private boolean getSelectedVideo(Intent imageReturnedIntent, boolean fromData) {
Uri selectedVideoUri;
//Selected image returned from another activity
// A parameter I pass myself to know whether or not I'm being "shared via" or
// whether I'm working internally to my app (fromData = working internally)
if(fromData){
selectedVideoUri = imageReturnedIntent.getData();
} else {
//Selected image returned from SEND intent
// which I register to receive in my manifest
// (so people can "share via" my app)
selectedVideoUri = (Uri)getIntent().getExtras().get(Intent.EXTRA_STREAM);
}
Log.d(TAG,"SelectedVideoUri = " + selectedVideoUri);
String filePath;
String scheme = selectedVideoUri.getScheme();
ContentResolver contentResolver = getContentResolver();
long videoId;
// If we are sent file://something or content://org.openintents.filemanager/mimetype/something...
if(scheme.equals("file") || (scheme.equals("content") && selectedVideoUri.getEncodedAuthority().equals("org.openintents.filemanager"))){
// Get the path
filePath = selectedVideoUri.getPath();
// Trim the path if necessary
// openintents filemanager returns content://org.openintents.filemanager/mimetype//mnt/sdcard/xxxx.mp4
if(filePath.startsWith("/mimetype/")){
String trimmedFilePath = filePath.substring("/mimetype/".length());
filePath = trimmedFilePath.substring(trimmedFilePath.indexOf("/"));
}
// Get the video ID from the path
videoId = getVideoIdFromFilePath(filePath, contentResolver);
} else if(scheme.equals("content")){
// If we are given another content:// URI, look it up in the media provider
videoId = Long.valueOf(selectedVideoUri.getLastPathSegment());
filePath = getFilePathFromContentUri(selectedVideoUri, contentResolver);
} else {
Log.d(TAG,"Failed to load URI " + selectedVideoUri.toString());
return false;
}
return true;
}
Когда Silverlight запрашивает междоменный файл .XAP, тип содержимого должен быть: application / x-silverlight-app . Кроме того, вам понадобится файл междоменной политики в другом домене. gl
Вы можете создать простой HTML-файл рядом с .xap, который содержит объект silverlight, и получить к нему доступ из iframe. Вот как http://silverlight.live.com/ , например, исправили эту проблему.
На главной странице subA.domain.com добавьте iframe, который показывает html-страницу в другом домене. :
<iframe src="http://subB.domain.com/SilverlightApp.html"
scrolling="no"
frameborder="0"
style="width:800px;height:600px">
</iframe>
и SilverlightApp.html на subBdomain.com могут выглядеть примерно так:
<html>
<body>
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2,"
type="application/x-silverlight-2"
width="800px" height="600px">
<param name="source" value="http://subB.domain.com/SilverlightApp.xap" />
<param name="onerror" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="2.0.31005.0" />
<param name="autoUpgrade" value="true" />
<param name="enableHtmlAccess" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807"
style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181"
alt="Get Microsoft Silverlight"
style="border-style: none" />
</a>
</object>
<iframe style='visibility: hidden; height: 0; width: 0; border: 0px'>
</iframe>
</div>
</body>
</html>
Чтобы помочь другим, у кого есть такая же проблема, и кто не хочет использовать IFrames, пожалуйста, смотрите эту ссылку , так как это решило мою проблему. Несмотря на то, что автор ссылается на Silverlight 2, он решил мою проблему в Silverlight 3. В случае, если ссылка упадет, мне нужно будет сделать 2 вещи:
-- В приложении Silverlight отредактируйте AppManifest. xml, чтобы добавить следующее:
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ExternalCallersFromCrossDomain="ScriptableOnly">
-- Если вы используете HtmlPage в вашем приложении Silverlight (например, при чтении QueryString, переданного на хостинговую страницу), вы также должны добавить:
<param name="enableHtmlAccess" value="true" />
к объекту Silverlight на хостинговой странице.
Пожалуйста, обратите внимание на то, что это связано с безопасностью, и я не могу не думать, что именно поэтому Microsoft не выходит за рамки своих возможностей по распространению этой информации. Однако в моем случае у меня нет элементов silverlight со скриптами, и поскольку я написал приложение silverlight, у меня нет проблем с хостинговой страницей, разрешающей приложению silverlight доступ к ней.
Исследуя это, я заметил, что эта проблема и соответствующие решения путаются с отдельной проблемой, проблемой серебряного xap доступа к wcf-сервису через границы домена. Для решения этой проблемы необходим файл clientaccesspolicy.xml, расположенный в корне сайта, на котором расположен wcf-сервис
Таким образом, 1-й сайт может получить доступ к xap-файлу на 2-м сайте, который получает доступ к сервису данных на 3-м сайте, для максимальной гибкости и повторного использования
.