Мое текущее приложение для Android может включать Bluetooth, обнаруживать себя, просматривать список сопряженных устройств и выбирать файл на устройстве (например, изображение). Однако, когда я пытался нажать «отправить», приложение вылетало с ошибкой. Не уверен, что он отказывается отправлять или не получает файл (вчера у меня возникла проблема, когда он отказался отправить выбранное, сказав мне выбрать файл несколько раз. Я опубликую результаты сбоя и мой код mainActivity. Если у вас есть предложения или идеи, пожалуйста, дайте мне знать.
Ошибка: отладка устройства
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.bluetooth_demoproject, PID: 17593
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=300, data=null} to activity {com.example.bluetooth_demoproject/com.example.bluetooth_demoproject.MainActivity}: android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/Screenshots/Screenshot_20161013-215137.png exposed beyond app through ClipData.Item.getUri()
at android.app.ActivityThread.deliverResults(ActivityThread.java:4107)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4150)
at android.app.ActivityThread.-wrap20(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1517)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6120)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/Screenshots/Screenshot_20161013-215137.png exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
at android.net.Uri.checkFileUriExposed(Uri.java:2346)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:832)
at android.content.Intent.prepareToLeaveProcess(Intent.java:8909)
at android.content.Intent.prepareToLeaveProcess(Intent.java:8894)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1517)
at android.app.Activity.startActivityForResult(Activity.java:4224)
at android.app.Activity.startActivityForResult(Activity.java:4183)
at android.app.Activity.startActivity(Activity.java:4507)
at android.app.Activity.startActivity(Activity.java:4475)
at com.example.bluetooth_demoproject.MainActivity.onActivityResult(MainActivity.java:350)
at android.app.Activity.dispatchActivityResult(Activity.java:6917)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4103)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4150)
at android.app.ActivityThread.-wrap20(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1517)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6120)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Disconnected from the target VM, address: 'localhost:8601', transport: 'socket'
Вот мой MainActivity
package com.example.bluetooth_demoproject;
import android.app.Activity;
import android.app.Dialog;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Environment;
import android.view.Menu;
import android.view.MenuItem;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Set;
import java.io.File;
import java.util.List;
import java.util.ArrayList;
public class MainActivity extends Activity {
// Creating objects -----------------------------
private static final int REQUEST_ENABLE_BT = 0;
private static final int REQUEST_BLU = 1;
// private static final int REQUEST_DISCOVER_BT_ = 1;
private static int CUSTOM_DIALOG_ID = 0;
ListView dialog_ListView;
TextView mBluetoothStatus, mPairedDevicesList, mTextFolder;
ImageView mBluetoothIcon;
Button mOnButton, mDiscoverableButton, mPairedDevices, mbuttonOpenDialog, msendBluetooth, mbuttonUp;
File root, fileroot, curFolder;
EditText dataPath;
private static final int DISCOVER_DURATION = 300;
private List<String> fileList = new ArrayList<String>();
// -------------------------------------------------------
BluetoothAdapter mBlueAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dataPath =(EditText)findViewById(R.id.FilePath);
mTextFolder = findViewById(R.id.folder);
mBluetoothStatus = findViewById(R.id.BluetoothStatus);
mBluetoothIcon = findViewById(R.id.bluetoothIcon);
mOnButton = findViewById(R.id.onButton);
// mOffButton = findViewById(R.id.offButton);
mDiscoverableButton = findViewById(R.id.discoverableButton);
mPairedDevices = findViewById(R.id.pairedDevices);
mPairedDevicesList = findViewById(R.id.pairedDeviceList);
mbuttonOpenDialog = findViewById(R.id.opendailog);
msendBluetooth = findViewById(R.id.sendBluetooth);
mbuttonUp = findViewById(R.id.up);
mbuttonOpenDialog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dataPath.setText("");
showDialog(CUSTOM_DIALOG_ID);
}
});
root = new
File(Environment.getExternalStorageDirectory().getAbsolutePath());
curFolder = root;
msendBluetooth.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
sendViaBluetooth();
}
});
//adapter
mBlueAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBlueAdapter == null){
mBluetoothStatus.setText("Bluetooth is not available");
return;
}
else {
mBluetoothStatus.setText("Bluetooth is available");
}
//if Bluetooth isnt enabled, enable it
if (!mBlueAdapter.isEnabled()) {
Intent enableBtIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
//set image according to bluetooth Status
if (mBlueAdapter.isEnabled()) {
mBluetoothIcon.setImageResource(R.drawable.action_on);
}
else {
mBluetoothIcon.setImageResource(R.drawable.action_off);
}
//on button Click
mOnButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
if (!mBlueAdapter.isEnabled()) {
showToast("Turning Bluetooth on...");
// intent to on bluetooth
Intent intent = new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_ENABLE_BT);
}
else {
showToast("Bluetooth is already on");
}
}
});
//discover Bluetooth button
mDiscoverableButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (!mBlueAdapter.isDiscovering()) {
showToast("Making device discoverable");
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(intent, REQUEST_BLU);
}
}
});
// off button click
// mOffButton.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// if (mBlueAdapter.isEnabled()) {
// showToast("Turning Bluetooth off...");
// // intent to turn off bluetooth
// mBluetoothIcon.setImageResource(R.drawable.action_off);
// }
// else{
// showToast("Bluetooth is already off");
// }
//
// }
//});
//get paired device button click
mPairedDevices.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mBlueAdapter.isEnabled()) {
mPairedDevices.setText("Paired Devices");
Set<BluetoothDevice> devices = mBlueAdapter.getBondedDevices();
for (BluetoothDevice device : devices){
mPairedDevices.append("\nDevice: " + device.getName() + "," + device );
}
}
else {
//bluetooth is off and cant get paired devices
showToast("Turn on bluetooth to get paired devices");
}
}
});
}
// @Override
// protected void onPrepareDialog(int id, Dialog dialog) {
// super.onPrepareDialog(id, dialog);
// switch (id) {
// case CUSTOM_DIALOG_ID:
// ListDir(curFolder);
// break;
// }
// }
@Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
if (id == CUSTOM_DIALOG_ID) {
dialog = new Dialog(MainActivity.this);
dialog.setContentView(R.layout.dailoglayout);
dialog.setTitle("Select Files");
dialog.setCancelable(true);
dialog.setCanceledOnTouchOutside(true);
mTextFolder = (TextView) dialog.findViewById(R.id.folder);
mbuttonUp = (Button) dialog.findViewById(R.id.up);
mbuttonUp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ListDir(curFolder.getParentFile());
}
});
dialog_ListView = (ListView) dialog.findViewById(R.id.dialoglist);
dialog_ListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
File selected = new File(fileList.get(position));
if (selected.isDirectory()) {
ListDir(selected);
}
else if (selected.isFile()) {
getSelectedFile(selected);
}
else {
dismissDialog(CUSTOM_DIALOG_ID);
}
}
});
}
return dialog;
}
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
if (id == CUSTOM_DIALOG_ID) {
ListDir(curFolder);
}
}
public void getSelectedFile(File f) {
dataPath.setText(f.getAbsolutePath());
fileList.clear();
dismissDialog(CUSTOM_DIALOG_ID);
}
public void ListDir(File f) {
if (f.equals(root)) {
mbuttonUp.setEnabled(false);
}
else {
mbuttonUp.setEnabled(true);
}
curFolder = f;
mTextFolder.setText(f.getAbsolutePath());
dataPath.setText(f.getAbsolutePath());
File[] files = f.listFiles();
fileList.clear();
for (File file : files) {
fileList.add(file.getPath());
}
ArrayAdapter<String> directoryList = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fileList);
dialog_ListView.setAdapter(directoryList);
}
// exits to app --------------------------------
public void exit(View V) {
mBlueAdapter.disable();
Toast.makeText(this, "*** Now bluetooth is off...", Toast.LENGTH_LONG).show();
finish();
}
// send file via bluetooth ------------------------
public void sendViaBluetooth() {
if(!dataPath.equals(null)) {
if(mBlueAdapter == null) {
Toast.makeText(this, "Device doesnt support bluetooth", Toast.LENGTH_LONG).show();
}
else {
enableBluetooth();
}
}
else {
Toast.makeText(this, "please select a file", Toast.LENGTH_LONG).show();
}
}
public void enableBluetooth() {
showToast("Making device discoverable");
Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoveryIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVER_DURATION);
startActivityForResult(discoveryIntent, REQUEST_BLU);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == DISCOVER_DURATION && requestCode == REQUEST_BLU) {
Intent i = new Intent();
i.setAction(Intent.ACTION_SEND);// STOPPED HERE-----------------------------------------------------------------
i.setType("*/*");
File file = new File(dataPath.getText().toString());
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
PackageManager pm = getPackageManager();
List<ResolveInfo> list = pm.queryIntentActivities(i, 0);
if (list.size() > 0) {
String packageName = null;
String className = null;
boolean found = false;
for (ResolveInfo info : list) {
packageName = info.activityInfo.packageName;
if (packageName.equals("com.android.bluetooth")) {
className = info.activityInfo.name;
found = true;
break;
}
}
//CHECK BLUETOOTH available or not------------------------------------------------
if (!found) {
Toast.makeText(this, "Bluetooth not been found", Toast.LENGTH_LONG).show();
} else {
i.setClassName(packageName, className);
startActivity(i);
}
}
} else {
Toast.makeText(this, "Bluetooth is cancelled", Toast.LENGTH_LONG).show();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
// if (id == R.id.action_settings) {
// Toast.makeText(this, "**********************************\nDeveloper: www.santoshkumarsingh.com\n**********************************", Toast.LENGTH_LONG).show();
// return true;
// }
return super.onOptionsItemSelected(item);
}
//toast message function
private void showToast(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT) .show();
}
}