Pour lire un fichier sous Android, si votre application est installée sur un appareil exécutant Android 6.0 (niveau d'API 23) ou supérieur, vous devez demander les autorisations dangereuses au moment de l'exécution. (réf: Développeurs Android: demandez les autorisations de l'application). L'accès au système de fichiers /proc/net est limité sur Android 10+ Sur les appareils qui exécutent Android 10 ou version ultérieure, les applications ne peuvent pas accéder à /proc/net, qui comprend des informations sur l'état du réseau d'un appareil. Les applications qui ont besoin d'accéder à ces informations, telles que les VPN, doivent utiliser la classe NetworkStatsManager ou ConnectivityManager. (réf: Android Developers: Privacy changes in Android 10 > Restriction on access to /proc/net filesystem)

  1. package com.androidcorpo.readfile;
  2.  
  3. import android.Manifest;
  4. import android.content.pm.ApplicationInfo;
  5. import android.content.pm.PackageInfo;
  6. import android.content.pm.PackageManager;
  7. import android.os.Build;
  8. import android.os.Bundle;
  9. import android.text.method.ScrollingMovementMethod;
  10. import android.view.View;
  11. import android.widget.Button;
  12. import android.widget.TextView;
  13. import android.widget.Toast;
  14.  
  15. import androidx.annotation.NonNull;
  16. import androidx.appcompat.app.AppCompatActivity;
  17. import androidx.core.app.ActivityCompat;
  18. import androidx.core.content.ContextCompat;
  19.  
  20. import java.io.BufferedReader;
  21. import java.io.File;
  22. import java.io.FileNotFoundException;
  23. import java.io.FileReader;
  24. import java.io.IOException;
  25.  
  26. public class MainActivity extends AppCompatActivity {
  27.  
  28. //Try different files
  29. //String targetFile = "/sdcard/Download/Test.txt";
  30. //String targetFile = "/proc/cpuinfo";
  31. //String targetFile = "/proc/meminfo";
  32. String targetFile = "/proc/net/arp"; //Restricted since Android 10
  33.  
  34. Button btnRead;
  35. TextView tvFileContent;
  36. TextView tvMsg;
  37.  
  38. final int PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
  39.  
  40. @Override
  41. protected void onCreate(Bundle savedInstanceState) {
  42. super.onCreate(savedInstanceState);
  43. setContentView(R.layout.activity_main);
  44. dispExInfo();
  45.  
  46. btnRead = findViewById(R.id.read);
  47. btnRead.setText(targetFile);
  48. tvFileContent = findViewById(R.id.filecontent);
  49. //make this TextView scrollable
  50. tvFileContent.setMovementMethod(new ScrollingMovementMethod());
  51. tvMsg = findViewById(R.id.msg);
  52. tvMsg.setText("Click on READ button");
  53.  
  54. btnRead.setOnClickListener(new View.OnClickListener() {
  55. @Override
  56. public void onClick(View v) {
  57. tvMsg.setText("READ button clicked");
  58. toReadFile();
  59. }
  60. });
  61. }
  62.  
  63.  
  64. /*
  65.   Request Permission at Runtime, before read file.
  66.   */
  67. void toReadFile(){
  68. if (ContextCompat.checkSelfPermission(this,
  69. Manifest.permission.READ_EXTERNAL_STORAGE)
  70. != PackageManager.PERMISSION_GRANTED) {
  71. // Permission is not granted
  72. // Should we show an explanation?
  73. if (ActivityCompat.shouldShowRequestPermissionRationale(
  74. this,
  75. Manifest.permission.READ_EXTERNAL_STORAGE)) {
  76. // Show an explanation to the user *asynchronously* -- don't block
  77. // this thread waiting for the user's response! After the user
  78. // sees the explanation, try again to request the permission.
  79.  
  80. //to simplify, call requestPermissions again
  81. Toast.makeText(getApplicationContext(),
  82. "shouldShowRequestPermissionRationale",
  83. Toast.LENGTH_LONG).show();
  84. ActivityCompat.requestPermissions(this,
  85. new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
  86. PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
  87. } else {
  88. // No explanation needed; request the permission
  89. ActivityCompat.requestPermissions(this,
  90. new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
  91. PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
  92. }
  93. }else{
  94. // permission granted
  95. readFile(targetFile);
  96. }
  97. }
  98.  
  99. @Override
  100. public void onRequestPermissionsResult(
  101. int requestCode,
  102. @NonNull String[] permissions,
  103. @NonNull int[] grantResults) {
  104. if(requestCode == PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE){
  105. if (grantResults.length > 0
  106. && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  107. // permission was granted.
  108. Toast.makeText(getApplicationContext(),
  109. "permission was granted, thx:)",
  110. Toast.LENGTH_LONG).show();
  111.  
  112. readFile(targetFile);
  113. } else {
  114. // permission denied.
  115. Toast.makeText(getApplicationContext(),
  116. "permission denied! Oh:(",
  117. Toast.LENGTH_LONG).show();
  118. }
  119. return;
  120.  
  121. }else{
  122. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  123. }
  124. }
  125.  
  126. void readFile(String f){
  127. File file = new File(f);
  128. StringBuilder stringBuilder = new StringBuilder();
  129.  
  130. try {
  131. BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
  132. String line;
  133. while ((line = bufferedReader.readLine()) != null) {
  134. stringBuilder.append(line);
  135. stringBuilder.append('\n');
  136. }
  137. bufferedReader.close();
  138.  
  139. tvFileContent.setText(stringBuilder);
  140. tvMsg.setText("Done");
  141. } catch (FileNotFoundException e) {
  142. e.printStackTrace();
  143. tvMsg.setText(e.getMessage());
  144. } catch (IOException e) {
  145. e.printStackTrace();
  146. tvMsg.setText(e.getMessage());
  147. }
  148. }
  149.  
  150. /* ==========================================
  151.   display Exercise info
  152.   */
  153.  
  154. void dispExInfo(){
  155. TextView tvExercise = findViewById(R.id.exercise);
  156. TextView tvSysInfo = findViewById(R.id.sysinfo);
  157. TextView tvSdkInfo = findViewById(R.id.sdkinfo);
  158.  
  159. tvExercise.append(" (Java)");
  160.  
  161. String manufacturer = Build.MANUFACTURER;
  162. String model = Build.MODEL;
  163. String release = Build.VERSION.RELEASE;
  164.  
  165. tvSysInfo.setText(
  166. manufacturer + "\n"
  167. + model + "\n"
  168. + "Android: " + release + "\n");
  169.  
  170. PackageManager packageManager = getPackageManager();
  171. String packageName = getPackageName();
  172. int targetSdkVersion, minSdkVersion;
  173. int versionCode;
  174. String versionName;
  175.  
  176. try {
  177. PackageInfo packageInfo =
  178. packageManager.getPackageInfo(packageName, 0);
  179.  
  180. ApplicationInfo applicationInfo = packageInfo.applicationInfo;
  181. targetSdkVersion = applicationInfo.targetSdkVersion;
  182. minSdkVersion = applicationInfo.minSdkVersion;
  183.  
  184. tvSdkInfo.setText("targetSdkVersion = " + targetSdkVersion + "\n"
  185. + "minSdkVersion = " + minSdkVersion);
  186. } catch (PackageManager.NameNotFoundException e) {
  187. e.printStackTrace();
  188. Toast.makeText(getApplicationContext(),
  189. "NameNotFoundException: " + e.getMessage(),
  190. Toast.LENGTH_LONG).show();
  191. }
  192. }
  193. }
  194.  

L'autorisation d'utilisation de "android.permission.READ_EXTERNAL_STORAGE" est nécessaire dans AndroidManifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.androidcorpo.readfile">
  4. <application
  5. android:allowBackup="true"
  6. android:icon="@mipmap/ic_launcher"
  7. android:label="@string/app_name"
  8. android:roundIcon="@mipmap/ic_launcher_round"
  9. android:supportsRtl="true"
  10. android:theme="@style/Theme.JExReadTextFile">
  11. <activity android:name=".MainActivity">
  12. <intent-filter>
  13. <action android:name="android.intent.action.MAIN" />
  14.  
  15. <category android:name="android.intent.category.LAUNCHER" />
  16. </intent-filter>
  17. </activity>
  18. </application>
  19. <b><span style="color: red;"><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/></span></b>
  20. </manifest>

Exemple de code langage Kotlin

package com.androidcorpo.readfile

import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.view.View
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import java.io.*


class MainActivity : AppCompatActivity() {
    //Try different files
    //var targetFile = "/sdcard/Download/Test.txt";
    var targetFile = "/proc/cpuinfo";
    //var targetFile = "/proc/meminfo";
    //var targetFile = "/proc/net/arp" //Restricted since Android 10
    var btnRead: Button? = null
    var tvFileContent: TextView? = null
    var tvMsg: TextView? = null
    val PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        dispExInfo()
        btnRead = findViewById(R.id.read)
        btnRead!!.setText(targetFile)
        tvFileContent = findViewById(R.id.filecontent)
        //make this TextView scrollable
        tvFileContent!!.setMovementMethod(ScrollingMovementMethod())
        tvMsg = findViewById(R.id.msg)
        tvMsg!!.setText("Click on READ button")
        btnRead!!.setOnClickListener(View.OnClickListener {
            tvMsg!!.setText("READ button clicked")
            toReadFile()
        })
    }

    /*
    Request Permission at Runtime, before read file.
     */
    fun toReadFile() {
        if (ContextCompat.checkSelfPermission(this,
                        Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            // Permission is not granted
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(
                            this,
                            Manifest.permission.READ_EXTERNAL_STORAGE)) {
                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.

                //to simplify, call requestPermissions again
                Toast.makeText(applicationContext,
                        "shouldShowRequestPermissionRationale",
                        Toast.LENGTH_LONG).show()
                ActivityCompat.requestPermissions(this,
                        arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                        PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE)
            } else {
                // No explanation needed; request the permission
                ActivityCompat.requestPermissions(this,
                        arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                        PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE)
            }
        } else {
            // permission granted
            readFile(targetFile)
        }
    }

    override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<String>,
            grantResults: IntArray) {
        if (requestCode == PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE) {
            if (grantResults.size > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted.
                Toast.makeText(applicationContext,
                        "permission was granted, thx:)",
                        Toast.LENGTH_LONG).show()
                readFile(targetFile)
            } else {
                // permission denied.
                Toast.makeText(applicationContext,
                        "permission denied! Oh:(",
                        Toast.LENGTH_LONG).show()
            }
            return
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        }
    }

    fun readFile(f: String?) {
        val file = File(f)
        val stringBuilder = StringBuilder()
        try {
            val bufferedReader = BufferedReader(FileReader(file))
            var line: String?
            while (bufferedReader.readLine().also { line = it } != null) {
                stringBuilder.append(line)
                stringBuilder.append('\n')
            }
            bufferedReader.close()
            tvFileContent!!.text = stringBuilder
            tvMsg!!.text = "Done"
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
            tvMsg!!.text = e.message
        } catch (e: IOException) {
            e.printStackTrace()
            tvMsg!!.text = e.message
        }
    }

    /* ==========================================
    display Exercise info
     */
    fun dispExInfo() {
        val tvExercise = findViewById<TextView>(R.id.exercise)
        val tvSysInfo = findViewById<TextView>(R.id.sysinfo)
        val tvSdkInfo = findViewById<TextView>(R.id.sdkinfo)
        tvExercise.append(" (Kotlin)")
        val manufacturer = Build.MANUFACTURER
        val model = Build.MODEL
        val release = Build.VERSION.RELEASE
        tvSysInfo.text = """
             $manufacturer
             $model
             Android: $release
             
             """.trimIndent()
        val packageManager = packageManager
        val packageName = packageName
        val targetSdkVersion: Int
        val minSdkVersion: Int
        var versionCode: Int
        var versionName: String
        try {
            val packageInfo = packageManager.getPackageInfo(packageName, 0)
            val applicationInfo = packageInfo.applicationInfo
            targetSdkVersion = applicationInfo.targetSdkVersion
            minSdkVersion = applicationInfo.minSdkVersion
            tvSdkInfo.text = """
                targetSdkVersion = $targetSdkVersion
                minSdkVersion = $minSdkVersion
                """.trimIndent()
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
            Toast.makeText(applicationContext,
                    "NameNotFoundException: " + e.message,
                    Toast.LENGTH_LONG).show()
        }
    }
}