1.在res下新建xml

file_provider_paths.xml 文件
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <!--内置SD卡 Environment.getExternalStorageDirectory() .表示共享所有的目录,也可以指定共享的目录--> <external-path name="external-path" path="."/> <!--内置SD卡 Context.getExternalCacheDir() .表示共享所有的目录,也可以指定共享的目录--> <external-cache-path name="external-cache-path" path="."/> <!--内置SD卡 Context.getExternalFilesDir(null) .表示共享所有的目录,也可以指定共享的目录--> <external-files-path name="external-files-path" path="."/> <!--data目录下 Context.getFilesDir() .表示共享所有的目录,也可以指定共享的目录--> <files-path name="files_path" path="."/> <!--data缓存目录 Context.getCacheDir() .表示共享所有的目录,也可以指定共享的目录--> <cache-path name="cache-path" path="."/> <!--这个标签Android官方文档中是没有提及,Android设备的根目录,该目录下包含着手机内部存储器,外置SD卡等所有文件的目录--> <root-path name="name" path="."/>
</paths> |
AndroidManifest.xml 文件配置
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.clj.blesample">
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> //添加的配置 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
<activity android:name=".MainActivity" tools:ignore="Instantiatable"> <intent-filter> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
<activity android:name=".operation.OperationActivity" tools:ignore="Instantiatable" />
//添加的配置 <provider //应该为android.support.v4.content.FileProvider 但我的配置文件中报错 我就重新建立一个MyFileProvider类继承FileProvider android:name="com.clj.blesample.operation.MyFileProvider" android:authorities="com.clj.blesample.fileProvider" android:exported="false" android:grantUriPermissions="true" tools:replace="android:authorities" > <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider_paths" tools:replace="android:resource" /> </provider>
</application>
</manifest> |
|
新建类 MyFileProvider
2.文件权限获取 在 onCreate()方法中调用它 获取手机权限
private void checkNeedPermissions(){ //6.0以上需要动态申请权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //多个权限一起申请 ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE }, 1); } } |
3.新建 ShareWechatFriend类
public class ShareWechatFriend {
public static void shareFile(Context mContext, File picFile) { checkFileUriExposure(); Intent intent = new Intent(Intent.ACTION_SEND); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); Uri uri = null; if (picFile != null) { //这部分代码主要功能是判断了下文件是否存在,在android版本高过7.0(包括7.0版本) //当前APP是不能直接向外部应用提供file开头的的文件路径, //需要通过FileProvider转换一下。否则在7.0及以上版本手机将直接crash。 try { ApplicationInfo applicationInfo = mContext.getApplicationInfo(); int targetSDK = applicationInfo.targetSdkVersion; if (targetSDK >= Build.VERSION_CODES.N && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //fileProvider 一定要与 AndroidManifest.xml 中 android:authorities 值保持一致 尤其是大小写 uri = FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName() + ".fileProvider", picFile); } else { uri = Uri.fromFile(picFile); } } catch (Exception e) { e.printStackTrace(); } } // System.out.println("获取url..."+uri); intent.putExtra(Intent.EXTRA_STREAM, uri); //传输图片或者文件 采用流的方式 intent.setType("*/*"); //分享文件 mContext.startActivity(Intent.createChooser(intent, "分享")); } /** * 分享前必须执行本代码,主要用于兼容SDK18以上的系统 */ private static void checkFileUriExposure() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); builder.detectFileUriExposure(); } } // 判断是否安装指定app public static boolean isInstallApp(Context context, String app_package) { final PackageManager packageManager = context.getPackageManager(); List<PackageInfo> pInfo = packageManager.getInstalledPackages(0); if (pInfo != null) { for (int i = 0; i < pInfo.size(); i++) { String pn = pInfo.get(i).packageName; if (app_package.equals(pn)) { return true; } } } return false; } } |
4.调用
//字符串写入文件 String s="sdhfksajdfh";
String filename =Environment.getExternalStorageDirectory()+"/log.txt";
File file =new File(filename); try{ if(!file.exists()){ file.createNewFile(); } FileWriter fileWritter = new FileWriter(file); fileWritter.write(s); fileWritter.close(); }catch(IOException e){ e.printStackTrace(); } Context context = this.getActivity().getApplicationContext(); ShareWechatFriend.shareFile(context,file); |