代码之家  ›  专栏  ›  技术社区  ›  Antoine Nedelec

Android studio-难以共享应用程序资产中的图像/音频/视频文件

  •  1
  • Antoine Nedelec  · 技术社区  · 5 年前

    从资产文件夹

    • here ,或 here , ..)
    • 尝试将文件保存在本地存储上(例如 here )
    • 和其他人,但由于它不起作用,我不再有联系。。

    现在,这里是我的工作解决方案,只向whatsapp和messenger共享音频文件,所有其他应用都失败了)。

    public String getNewPathFromSbElem(SbElem sbElem, String fileName) {
        AssetManager assetManager = getAssets();
        String path = sbElem.soundPath;
        String newName = fileName;
        String newPath = getExternalFilesDir(null).getAbsolutePath() + File.separator + newName;
        InputStream in = null;
        OutputStream out = null;
        File outFile;
    
        File deleteFile = new File(newPath);
        if(deleteFile.exists()) {
            deleteFile.delete();
        }
    
        try {
            in = assetManager.open(path);
            outFile = new File(getExternalFilesDir(null), newName);
            out = new FileOutputStream(outFile);
            copyFile(in, out);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
        return newPath;
    }
    

    我要在whatsapp或messenger上分享的两个功能:

    public void shareOnWhatsApp(SbElem sbElem) {
        final String newPath = getNewPathFromSbElem(sbElem, "_share_temp_file.mp3");
        Intent whatsappIntent = new Intent(Intent.ACTION_SEND);
        whatsappIntent.setPackage("com.whatsapp");
        whatsappIntent.setType("audio/mp3");
        whatsappIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(newPath));
        whatsappIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    
        try {
            startActivity(whatsappIntent);
        } catch (android.content.ActivityNotFoundException ex) {
            Log.d("error", "WhatsApp not installed");
        }
    }
    
    public void shareOnMessenger (SbElem sbElem) {
        final String newPath = getNewPathFromSbElem(sbElem, "_share_temp_file.mp3");
        final File newFile = new File(newPath);
        final Uri newUri = FileProvider.getUriForFile(this, getString(R.string.file_provider_authority), newFile);
        final Integer SHARE_TO_MESSENGER_REQUEST_CODE = 1;
    
        String mimeType = "audio/*";
        ShareToMessengerParams shareToMessengerParams = ShareToMessengerParams.newBuilder(newUri, mimeType).build();
        MessengerUtils.shareToMessenger(this, SHARE_TO_MESSENGER_REQUEST_CODE, shareToMessengerParams);
    }
    

    问题是,我希望能够从我的资产文件夹a.mp3、a.jpg、a.png、gmail、whatsapp、slack或任何支持此扩展的应用程序中共享。。。

    因此,几乎所有关于共享资产的1000个在线问题/文章都是通过使用自定义内容提供商来回答的,因此我尝试了以下操作 :

    public void shareBasic () {
        // I added the test.jpg in the root of my asset folder
        // Tried with content / file / 2 or 3 '/', with package name and with assets / ...
        Uri theUri = Uri.parse("content:///com.MY_PACKAGE_NAME/test.jpg");
        //Uri theUri = Uri.parse("content:///assets/test.jpg");
        //Uri theUri = Uri.parse("file:///com.MY_PACKAGE_NAME/test.jpg");
        //Uri theUri = Uri.parse("file:///asset.jpg");
        Intent theIntent = new Intent(Intent.ACTION_SEND);
        // Tried with jpeg / png / jpg ...
        theIntent.setType("image/*");
        theIntent.putExtra(Intent.EXTRA_STREAM, theUri);
        theIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivity(theIntent);
    }
    

    这是我的 Android清单

        <provider
            android:name="MY_PACKAGE_NAME.MyContentProvider"
            android:authorities="MY_PACKAGE_NAME"
            android:grantUriPermissions="true"
            android:exported="true" />
    

    和文件提供程序(几乎在每个教程中都一样)

    public class MyContentProvider extends ContentProvider {
        @Override
        public boolean onCreate() {
            return true;
        }
    
        @Override
        public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
            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 );
        }
    
        @Nullable
        @Override
        public String getType(@NonNull Uri uri) {
            return null;
        }
    
        @Nullable
        @Override
        public Uri insert(@NonNull Uri uri, ContentValues values) {
            return null;
        }
    
        @Override
        public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
            return 0;
        }
    
        @Override
        public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
            return 0;
        }
    
        @Override
        public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
            AssetManager am = getContext().getAssets();
            String fileName = uri.getLastPathSegment();
            if(fileName == null)
                throw new FileNotFoundException();
            AssetFileDescriptor fileDescriptor = null;
            try {
                fileDescriptor = am.openFd(fileName);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return fileDescriptor;
        }
    }
    

    我想我犯了很大的错误,因为共享资产文件夹中的文件不应该这么费劲,

    0 回复  |  直到 5 年前
        1
  •  0
  •   CommonsWare    5 年前

    为了你的 ContentProvider 解决方案:

    • 你需要你的 query() 功能支持 OpenableColumns

    • 你需要你的 getType() 函数返回实际的MIME类型

    • 你的 Intent

    this old sample project 做个示范。