Bud*_*ril 19 android share assets image
我正在尝试从我的资源文件夹中共享图像.我的代码是:
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/jpg");
share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///assets/myImage.jpg"));
startActivity(Intent.createChooser(share, "Share This Image"));
Run Code Online (Sandbox Code Playgroud)
但它不起作用.你有什么想法?
smi*_*324 15
可以通过自定义从资源文件夹共享文件(包括图像) ContentProvider
您需要扩展ContentProvider,在清单中注册并实现该openAssetFile方法.然后,您可以通过Uris 评估资产
@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
AssetManager am = getContext().getAssets();
String file_name = uri.getLastPathSegment();
if(file_name == null)
throw new FileNotFoundException();
AssetFileDescriptor afd = null;
try {
afd = am.openFd(file_name);
} catch (IOException e) {
e.printStackTrace();
}
return afd;
}
Run Code Online (Sandbox Code Playgroud)
int*_*dis 11
这个博客解释了这一切:
http
://nowherenearithaca.blogspot.co.uk/2012/03/too-easy-using-contentprovider-to-send.html
基本上,这就在清单中:
<provider android:name="yourclass.that.extendsContentProvider" android:authorities="com.yourdomain.whatever"/>
Run Code Online (Sandbox Code Playgroud)
内容提供程序类具有以下内容:
@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
AssetManager am = getContext().getAssets();
String file_name = uri.getLastPathSegment();
if(file_name == null)
throw new FileNotFoundException();
AssetFileDescriptor afd = null;
try {
afd = am.openFd(file_name);
} catch (IOException e) {
e.printStackTrace();
}
return afd;//super.openAssetFile(uri, mode);
}
Run Code Online (Sandbox Code Playgroud)
调用代码执行此操作:
Uri theUri = Uri.parse("content://com.yourdomain.whatever/someFileInAssetsFolder");
Intent theIntent = new Intent(Intent.ACTION_SEND);
theIntent.setType("image/*");
theIntent.putExtra(Intent.EXTRA_STREAM,theUri);
theIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Subject for message");
theIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Body for message");
startActivity(theIntent);
Run Code Online (Sandbox Code Playgroud)
Kik*_*uto 11
补充@intrepidis回答的内容:
您将需要覆盖方法,例如上面的示例类:
package com.android.example;
import android.content.ContentProvider;
import android.net.Uri;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import java.io.FileNotFoundException;
import android.content.ContentValues;
import android.database.Cursor;
import java.io.IOException;
import android.os.CancellationSignal;
public class AssetsProvider extends ContentProvider
{
@Override
public AssetFileDescriptor openAssetFile( Uri uri, String mode ) throws FileNotFoundException
{
Log.v( TAG, "AssetsGetter: Open asset file" );
AssetManager am = getContext( ).getAssets( );
String file_name = uri.getLastPathSegment( );
if( file_name == null )
throw new FileNotFoundException( );
AssetFileDescriptor afd = null;
try
{
afd = am.openFd( file_name );
}
catch(IOException e)
{
e.printStackTrace( );
}
return afd;//super.openAssetFile(uri, mode);
}
@Override
public String getType( Uri p1 )
{
// TODO: Implement this method
return null;
}
@Override
public int delete( Uri p1, String p2, String[] p3 )
{
// TODO: Implement this method
return 0;
}
@Override
public Cursor query( Uri p1, String[] p2, String p3, String[] p4, String p5 )
{
// TODO: Implement this method
return null;
}
@Override
public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal )
{
// TODO: Implement this method
return super.query( uri, projection, selection, selectionArgs, sortOrder, cancellationSignal );
}
@Override
public Uri insert( Uri p1, ContentValues p2 )
{
// TODO: Implement this method
return null;
}
@Override
public boolean onCreate( )
{
// TODO: Implement this method
return false;
}
@Override
public int update( Uri p1, ContentValues p2, String p3, String[] p4 )
{
// TODO: Implement this method
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
我需要重写两次查询方法.并在androidmanifest.xml中的标记上方添加以下行:
<provider
android:name="com.android.example.AssetsProvider"
android:authorities="com.android.example"
android:grantUriPermissions="true"
android:exported="true" />
Run Code Online (Sandbox Code Playgroud)
有了这个,所有的工作就像一个魅力:D
由于这里的其他答案都不适合我(2019 年),我通过将资产复制到应用程序的内部文件目录然后共享此文件来解决问题。就我而言,我需要共享资产文件夹中的 pdf 文件。
在 AndroidManifest.xml 中添加一个文件提供程序(无需使用自定义提供程序):
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
Run Code Online (Sandbox Code Playgroud)
在 res/xml/ 中创建 filepaths.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path
name="root"
path="/" />
</paths>
Run Code Online (Sandbox Code Playgroud)
当然,如果您管理应用程序目录中的其他文件,则应该在此处使用子目录。
现在在您想要触发共享意图的类中。
1.在files目录下创建一个空文件
private fun createFileInFilesDir(filename: String): File {
val file = File(filesDir.path + "/" + filename)
if (file.exists()) {
if (!file.delete()) {
throw IOException()
}
}
if (!file.createNewFile()) {
throw IOException()
}
return file
}
Run Code Online (Sandbox Code Playgroud)
2.将asset的内容复制到文件中
private fun copyAssetToFile(assetName: String, file: File) {
val buffer = ByteArray(1024)
val inputStream = assets.open(assetName)
val outputStream: OutputStream = FileOutputStream(file)
while (inputStream.read(buffer) > 0) {
outputStream.write(buffer)
}
}
Run Code Online (Sandbox Code Playgroud)
3. 为文件创建共享意图
private fun createIntentForFile(file: File, intentAction: String): Intent {
val uri = FileProvider.getUriForFile(this, applicationContext.packageName + ".provider", file)
val intent = Intent(intentAction)
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
intent.setDataAndType(uri, "application/pdf")
return intent
}
Run Code Online (Sandbox Code Playgroud)
4. 执行1-3并触发intent
private fun sharePdfAsset(assetName: String, intentAction: String) {
try {
val file = createFileInFilesDir(assetName)
copyAssetToFile(assetName, file)
val intent = createIntentForFile(file, intentAction)
startActivity(Intent.createChooser(intent, null))
} catch (e: IOException) {
e.printStackTrace()
AlertDialog.Builder(this)
.setTitle(R.string.error)
.setMessage(R.string.share_error)
.show()
}
}
Run Code Online (Sandbox Code Playgroud)
5. 调用函数
sharePdfAsset("your_pdf_asset.pdf", Intent.ACTION_SEND)
Run Code Online (Sandbox Code Playgroud)
如果您想在共享后删除该文件,您可能可以startActivityForResult()在共享后使用并删除它。通过更改,intentAction您还可以通过使用此过程来执行“打开方式...”操作Intent.ACTION_VIEW。对于assets, filesDir, ... 您需要参加Activity或拥有一个Context课程。
| 归档时间: |
|
| 查看次数: |
16606 次 |
| 最近记录: |