在 Android N 中通过蓝牙 opp 共享文件

share file over bluetooth opp in Android N

我正在尝试通过蓝牙共享文件。我尝试了以下两种方法将文件名传递给 ACTION_SEND 意图。 share activity 弹出,当我触摸连接的蓝牙设备时,我得到一个祝酒词 Bluetooth share: File Unknown file not sent。两种方法都失败了。

public void pushFileOverOpp(String filename) {
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_SEND);
    intent.setPackage("com.android.bluetooth");
    intent.setType("audio/mp3");
    File f = new File(Environment.getExternalStorageDirectory(), "images");
    File sample = new File(f, "sample.mp3");
    Uri u = Uri.parse(sample.toString());
    intent.putExtra(Intent.EXTRA_STREAM, u);
    mContext.startActivity(intent);
}

错误,日志-

OppService: URI : /storage/emulated/0/images/sample.mp3 OppService: HINT : null OppService: FILENAME: null OppService: MIMETYPE: audio/mp3

File f = new File(mContext.getFilesDir(), "images");
File sample = new File(f, "sample.mp3");
Uri u = FileProvider.getUriForFile(mContext,
           BuildConfig.APPLICATION_ID + ".provider", sample);
intent.putExtra(Intent.EXTRA_STREAM, u);

错误,日志-

OppService: URI : content://com.example.com.test.provider/tester/images/sample.mp3 OppService: HINT : null OppService: FILENAME: null

我查看了android源代码,当文件名为空时出现这个错误。日志还说文件名是空的。但我无法弄清楚确切的原因。有人可以帮帮我吗,我的代码有什么问题。

请参考此代码,它可以工作并使用 createChooser 方法共享文件。

          ArrayList<Uri> arrayList2 = new ArrayList<>();

            String MEDIA_PATH = new String(Environment.getExternalStorageDirectory() +
                    "/NewCallLogs/audio.mp3");

            File files = new File(MEDIA_PATH);
            Uri u = Uri.fromFile(files);
            arrayList2.add(u);

            Intent share = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
            share.setData(Uri.parse("mailto:"));
            share.setType("audio/mpeg");
            share.putExtra(android.content.Intent.EXTRA_STREAM, arrayList2);
            try {
                startActivity(Intent.createChooser(share, "Share..."));
               // getActivity().finish();
                Log.i("Finished sharing.", "");
            } catch (android.content.ActivityNotFoundException ex) {
                Toast.makeText(getActivity(), "nothing shared.", Toast.LENGTH_SHORT).show();
            }

仅在蓝牙中共享文件

  ArrayList<Uri> arrayList2 = new ArrayList<>();

            String MEDIA_PATH = new String(Environment.getExternalStorageDirectory() +
                    "/NewCallLogs/audio.mp3" );

            File files = new File(MEDIA_PATH);
            Uri u = Uri.fromFile(files);
            arrayList2.add(u);

            Intent share = new Intent(android.content.Intent.ACTION_SEND);
            share.setData(Uri.parse("mailto:"));
            share.setType("audio/mpeg");
            share.setPackage("com.android.bluetooth");
            share.putExtra(android.content.Intent.EXTRA_STREAM, arrayList2);
            startActivity(share);

经过一番研究,我明白了这个问题。有两个问题-

xml tag for external storage(/sdcard/) directory was wrong in xml file.

我改成如下。

    <root-path
    name="root"
    path="/" />

URI permission was not granted

mContext.grantUriPermission("com.android.bluetooth", u,
            Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 

修改以上代码后,文件共享就可以了!

完整的工作代码-

public boolean pushFileOverOpp(String filename) {
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_SEND);
    intent.setType("*/*"); // supports all mime types
    intent.setPackage("com.android.bluetooth"); //bluetooth package name, default opp

    File folder = new File(Environment.getExternalStorageDirectory(), "images");
    File file = new File(folder, filename);
    if (!file.exists()) {
        Logger.e("No such file " + filename + " exists!");
        return false;
    }
    Uri u = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".provider", file);
    intent.putExtra(Intent.EXTRA_STREAM, u);

    mContext.grantUriPermission("com.android.bluetooth", u,
            Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

    Logger.d("Sharing file over bluetooth " + folder.toString());
    mContext.startActivity(intent);
    return true;
}

谢谢。