Fix: MANAGE_EXTERNAL_STORAGE 권한 추가로 파일 쓰기 오류 해결
문제: Android 11+ Scoped Storage로 인해 EPERM (Operation not permitted) 에러 발생 - Storage Access Framework로 디렉토리 선택했지만 File API로 쓰기 시도 - 권한 부족으로 파일 업로드(STOR) 실패 해결: - AndroidManifest.xml에 MANAGE_EXTERNAL_STORAGE 권한 추가 - MainActivity에서 Android 11+ (API 30+) 권한 요청 로직 추가 * Environment.isExternalStorageManager()로 권한 확인 * Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION으로 설정 화면 이동 * 서버 시작 전 권한 체크 추가 - 이 권한으로 외부 저장소 전체에 File API 접근 가능 사용자는 앱 실행 시 "All files access" 권한 활성화 필요 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||||
|
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import android.content.pm.PackageManager;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -145,20 +147,21 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void requestPermissions() {
|
private void requestPermissions() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
// Android 13+
|
// Android 11+ - Need MANAGE_EXTERNAL_STORAGE
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES)
|
if (!Environment.isExternalStorageManager()) {
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
try {
|
||||||
ActivityCompat.requestPermissions(this,
|
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
|
||||||
new String[]{
|
intent.setData(Uri.parse("package:" + getPackageName()));
|
||||||
Manifest.permission.READ_MEDIA_IMAGES,
|
startActivity(intent);
|
||||||
Manifest.permission.READ_MEDIA_VIDEO,
|
Toast.makeText(this, "Please grant 'All files access' permission", Toast.LENGTH_LONG).show();
|
||||||
Manifest.permission.READ_MEDIA_AUDIO
|
} catch (Exception e) {
|
||||||
},
|
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
|
||||||
PERMISSION_REQUEST_CODE);
|
startActivity(intent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
// Android 6.0 - 12
|
// Android 6.0 - 10
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
ActivityCompat.requestPermissions(this,
|
ActivityCompat.requestPermissions(this,
|
||||||
@@ -172,6 +175,15 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startFTPServer() {
|
private void startFTPServer() {
|
||||||
|
// Check permission first
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
if (!Environment.isExternalStorageManager()) {
|
||||||
|
Toast.makeText(this, "Please grant 'All files access' permission first", Toast.LENGTH_LONG).show();
|
||||||
|
requestPermissions();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!config.hasRootDirectory()) {
|
if (!config.hasRootDirectory()) {
|
||||||
Toast.makeText(this, "Please select a root directory first", Toast.LENGTH_LONG).show();
|
Toast.makeText(this, "Please select a root directory first", Toast.LENGTH_LONG).show();
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user