안드로이드에서 USB 메모리에 데이터를 저장하는 방법은 USB OTG(On-The-Go) 기능을 활용합니다. 이를 위해서는 USB 드라이브에 접근하기 위해 적절한 권한을 부여받고, UsbManager
와 UsbDevice
를 사용하여 USB 장치에 접근해야 합니다. 또한, API 레벨 21(Lollipop) 이상에서는 Storage Access Framework
(SAF)를 통해 외부 저장소에 접근할 수 있습니다.
아래는 USB 메모리에 파일을 저장하는 방법에 대한 단계별 가이드입니다.
1. 매니페스트 파일에 권한 추가
AndroidManifest.xml
파일에 필요한 권한을 추가합니다.
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.usb.host"/>
2. USB 장치 접근 설정
UsbManager
를 사용하여 USB 장치에 접근합니다. USB 장치 접근을 허용하는 코드와 USB 장치 연결을 처리하는 BroadcastReceiver
를 설정합니다.
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String ACTION_USB_PERMISSION = "com.example.USB_PERMISSION";
private UsbManager usbManager;
private UsbDevice device;
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
// 권한이 부여된 경우
Log.d("USB", "Permission granted for device " + device);
// USB 메모리에 데이터 저장
saveFileToUsb();
}
} else {
Log.d("USB", "Permission denied for device " + device);
}
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(usbReceiver, filter);
// USB 장치 탐색 및 권한 요청
discoverUsbDevices();
}
private void discoverUsbDevices() {
for (UsbDevice device : usbManager.getDeviceList().values()) {
PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(device, permissionIntent);
}
}
private void saveFileToUsb() {
// 여기에 파일 저장 로직 추가
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(usbReceiver);
}
}
3. 파일 저장 로직 추가
saveFileToUsb
메서드에 USB 메모리에 파일을 저장하는 로직을 추가합니다. 이 예제에서는 DocumentFile
을 사용하여 파일을 저장합니다.
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import androidx.documentfile.provider.DocumentFile;
import java.io.FileOutputStream;
import java.io.IOException;
private void saveFileToUsb() {
// SAF를 사용하여 USB 메모리에 파일 저장
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, REQUEST_CODE_SAVE_TO_USB);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_SAVE_TO_USB && resultCode == RESULT_OK) {
Uri treeUri = data.getData();
if (treeUri != null) {
saveFile(treeUri);
}
}
}
private void saveFile(Uri treeUri) {
Context context = getApplicationContext();
ContentResolver contentResolver = context.getContentResolver();
DocumentFile pickedDir = DocumentFile.fromTreeUri(context, treeUri);
// 저장할 파일 생성
DocumentFile file = pickedDir.createFile("text/plain", "example.txt");
try (ParcelFileDescriptor pfd = contentResolver.openFileDescriptor(file.getUri(), "w");
FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor())) {
String textContent = "Hello, USB!";
fileOutputStream.write(textContent.getBytes());
Log.d("USB", "File written successfully.");
} catch (IOException e) {
Log.e("USB", "Failed to write file", e);
}
}
4. 파일 저장에 대한 권한 요청
USB 메모리에 파일을 저장하기 위해서는 MANAGE_EXTERNAL_STORAGE
권한이 필요합니다. 이를 위해 사용자에게 권한을 요청합니다.
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
private static final int REQUEST_CODE_WRITE_SETTINGS = 200;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 권한 요청
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (!Environment.isExternalStorageManager()) {
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS);
}
} else {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_WRITE_SETTINGS);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 권한 부여됨
} else {
// 권한 거부됨
}
}
}
이제 USB 메모리에 파일을 저장할 수 있는 기능이 구현되었습니다. USB 장치가 연결되면 BroadcastReceiver
를 통해 권한을 요청하고, 권한이 부여되면 SAF를 사용하여 파일을 저장합니다.