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)
package com.androidcorpo.readfile; import android.Manifest; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; 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.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class MainActivity extends AppCompatActivity { //Try different files //String targetFile = "/sdcard/Download/Test.txt"; //String targetFile = "/proc/cpuinfo"; //String targetFile = "/proc/meminfo"; Button btnRead; TextView tvFileContent; TextView tvMsg; final int PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1; @Override protected void onCreate(Bundle savedInstanceState) { 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(new ScrollingMovementMethod()); tvMsg = findViewById(R.id.msg); tvMsg.setText("Click on READ button"); @Override tvMsg.setText("READ button clicked"); toReadFile(); } }); } /* Request Permission at Runtime, before read file. */ void toReadFile(){ if (ContextCompat.checkSelfPermission(this, != PackageManager.PERMISSION_GRANTED) { // Permission is not granted // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale( this, // 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(getApplicationContext(), "shouldShowRequestPermissionRationale", Toast.LENGTH_LONG).show(); ActivityCompat.requestPermissions(this, PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); } else { // No explanation needed; request the permission ActivityCompat.requestPermissions(this, PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); } }else{ // permission granted readFile(targetFile); } } @Override public void onRequestPermissionsResult( int requestCode, @NonNull int[] grantResults) { if(requestCode == PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE){ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted. Toast.makeText(getApplicationContext(), "permission was granted, thx:)", Toast.LENGTH_LONG).show(); readFile(targetFile); } else { // permission denied. Toast.makeText(getApplicationContext(), "permission denied! Oh:(", Toast.LENGTH_LONG).show(); } return; }else{ super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } StringBuilder stringBuilder = new StringBuilder(); try { String line; while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line); stringBuilder.append('\n'); } bufferedReader.close(); tvFileContent.setText(stringBuilder); tvMsg.setText("Done"); e.printStackTrace(); tvMsg.setText(e.getMessage()); e.printStackTrace(); tvMsg.setText(e.getMessage()); } } /* ========================================== display Exercise info */ void dispExInfo(){ TextView tvExercise = findViewById(R.id.exercise); TextView tvSysInfo = findViewById(R.id.sysinfo); TextView tvSdkInfo = findViewById(R.id.sdkinfo); tvExercise.append(" (Java)"); tvSysInfo.setText( manufacturer + "\n" + model + "\n" + "Android: " + release + "\n"); PackageManager packageManager = getPackageManager(); int targetSdkVersion, minSdkVersion; int versionCode; String versionName; try { PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0); ApplicationInfo applicationInfo = packageInfo.applicationInfo; targetSdkVersion = applicationInfo.targetSdkVersion; minSdkVersion = applicationInfo.minSdkVersion; tvSdkInfo.setText("targetSdkVersion = " + targetSdkVersion + "\n" + "minSdkVersion = " + minSdkVersion); e.printStackTrace(); Toast.makeText(getApplicationContext(), "NameNotFoundException: " + e.getMessage(), Toast.LENGTH_LONG).show(); } } }
package com.androidcorpo.readfile;
import android.Manifest;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
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.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
//Try different files
//String targetFile = "/sdcard/Download/Test.txt";
//String targetFile = "/proc/cpuinfo";
//String targetFile = "/proc/meminfo";
String targetFile = "/proc/net/arp"; //Restricted since Android 10
Button btnRead;
TextView tvFileContent;
TextView tvMsg;
final int PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
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(new ScrollingMovementMethod());
tvMsg = findViewById(R.id.msg);
tvMsg.setText("Click on READ button");
btnRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tvMsg.setText("READ button clicked");
toReadFile();
}
});
}
/*
Request Permission at Runtime, before read file.
*/
void 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(getApplicationContext(),
"shouldShowRequestPermissionRationale",
Toast.LENGTH_LONG).show();
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
}else{
// permission granted
readFile(targetFile);
}
}
@Override
public void onRequestPermissionsResult(
int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
if(requestCode == PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE){
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted.
Toast.makeText(getApplicationContext(),
"permission was granted, thx:)",
Toast.LENGTH_LONG).show();
readFile(targetFile);
} else {
// permission denied.
Toast.makeText(getApplicationContext(),
"permission denied! Oh:(",
Toast.LENGTH_LONG).show();
}
return;
}else{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
void readFile(String f){
File file = new File(f);
StringBuilder stringBuilder = new StringBuilder();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append('\n');
}
bufferedReader.close();
tvFileContent.setText(stringBuilder);
tvMsg.setText("Done");
} catch (FileNotFoundException e) {
e.printStackTrace();
tvMsg.setText(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
tvMsg.setText(e.getMessage());
}
}
/* ==========================================
display Exercise info
*/
void dispExInfo(){
TextView tvExercise = findViewById(R.id.exercise);
TextView tvSysInfo = findViewById(R.id.sysinfo);
TextView tvSdkInfo = findViewById(R.id.sdkinfo);
tvExercise.append(" (Java)");
String manufacturer = Build.MANUFACTURER;
String model = Build.MODEL;
String release = Build.VERSION.RELEASE;
tvSysInfo.setText(
manufacturer + "\n"
+ model + "\n"
+ "Android: " + release + "\n");
PackageManager packageManager = getPackageManager();
String packageName = getPackageName();
int targetSdkVersion, minSdkVersion;
int versionCode;
String versionName;
try {
PackageInfo packageInfo =
packageManager.getPackageInfo(packageName, 0);
ApplicationInfo applicationInfo = packageInfo.applicationInfo;
targetSdkVersion = applicationInfo.targetSdkVersion;
minSdkVersion = applicationInfo.minSdkVersion;
tvSdkInfo.setText("targetSdkVersion = " + targetSdkVersion + "\n"
+ "minSdkVersion = " + minSdkVersion);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"NameNotFoundException: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}
L'autorisation d'utilisation de "android.permission.READ_EXTERNAL_STORAGE" est nécessaire dans AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.androidcorpo.readfile"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.JExReadTextFile"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <b><span style="color: red;"><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/></span></b> </manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidcorpo.readfile">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.JExReadTextFile">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
</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()
}
}
}
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()
}
}
}