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); |