Android (파일 처리 응용, SD카드 폴더 / 파일 생성 및 삭제, SD카드 폴더 / 파일 목록 출력, 파일처리 - 프로젝트, 이미지 번호 표시)
1. 파일 처리 응용
- Device Manager 클릭 후 > 연필 모양 클릭
- Show Advanced Settings 클릭 > SD카드 용량 있는 지 확인
- build.gradle(Module)에서 targetSdk 29로 변경
- Device File Explorer를 통해 SD카드 파일 읽기 가능
- Download 폴더에 Upload
- text 파일 업로드
- 매니페스트 파일 상단에
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:requestLegacyExternalStorage="true"
- 코드 2줄 추가
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnRead"
android:text="SD 카드에서 파일 읽기"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editSD"
android:lines="10"/>
</LinearLayout>
- XML 작성
package kr.jeongmo.a0501proejct03
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log.println
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.core.app.ActivityCompat
import java.io.FileInputStream
import java.io.IOException
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE),
Context.MODE_PRIVATE
)
val btnRead = findViewById<Button>(R.id.btnRead)
val editSD = findViewById<EditText>(R.id.editSD)
btnRead.setOnClickListener {
try {
val inputStream = FileInputStream("/storage/emulated/0/Download/text.txt")
val txt = ByteArray(inputStream.available())
inputStream.read(txt)
editSD.setText(txt.toString(Charsets.UTF_8))
inputStream.close()
} catch (e : IOException) {
Toast.makeText(applicationContext, "에러", Toast.LENGTH_SHORT).show()
}
}
}
}
- 액티비티 코드 작성
- Allow > SD 카드에서 파일 읽기
2. SD카드에 폴더 및 파일 생성, 삭제
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnMkDir"
android:text="SD 카드에 디렉토리 생성"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnRmDir"
android:text="SD 카드에 디렉토리 삭제"/>
</LinearLayout>
// 2. SD카드 파일 생성, 삭제
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE),
Context.MODE_PRIVATE
)
val btnMkdir = findViewById<Button>(R.id.btnMkDir)
val btnRmdir = findViewById<Button>(R.id.btnRmDir)
val strSDpath = Environment.getExternalStorageDirectory().absolutePath
val myDir = File("${strSDpath}/MyDir")
btnMkdir.setOnClickListener {
myDir.mkdir()
}
btnRmdir.setOnClickListener {
myDir.delete()
}
- 디렉토리 생성 클릭 > MyDir 폴더 생성 확인
- 디렉토리 삭제 클릭 > MyDir 폴더 삭제 확인
3. SD카드 폴더, 파일 목록 출력
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnFileList"
android:text="시스템 폴더의 폴더/파일 목록"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editFileList"/>
</LinearLayout>
// 3. SD카드 폴더, 파일 목록
val btnFileList = findViewById<Button>(R.id.btnFileList)
val editFileList = findViewById<EditText>(R.id.editFileList)
btnFileList.setOnClickListener {
val sysDir = Environment.getRootDirectory().absolutePath
val sysFiles = File(sysDir).listFiles()
var strFname : String
for (i in sysFiles.indices) {
if (sysFiles[i].isDirectory == true)
strFname = "<폴더> " + sysFiles[i].toString()
else
strFname = "<파일> " + sysFiles[i].toString()
editFileList.setText(editFileList.text.toString() + "\n" + strFname)
}
}
- 버튼 클릭하면 파일 목록 출력
4. 파일처리 - 프로젝트
- 프로젝트 새로 생성
- targetSDK 29로 변경
- 메인 액티비티 동일 위치에 New > Kotlin Class 파일 생성
- 파일 명 : MyPictureView
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.View
import java.util.jar.Attributes
class MyPictureView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
}
- 임포트 파일 추가 후 > onDraw 메서드 추가
package kr.jeongmo.a0502project
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.View
import java.util.jar.Attributes
class MyPictureView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
var imagePath : String? = null
@SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
try {
if (imagePath != null) {
val bitmap = BitmapFactory.decodeFile(imagePath)
canvas.scale(2f, 2f, 0f, 0f)
canvas.drawBitmap(bitmap!!, 0f, 0f, null)
bitmap.recycle()
}
} catch (e : Exception) {
}
}
}
- MyPictureView 코드 작성
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kr.jeongmo.a0502project">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:requestLegacyExternalStorage="true"
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.0502Project">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
- ManiFests 코드 2줄 추가
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnPrev"
android:layout_weight="1"
android:text="이전 그림"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnNext"
android:layout_weight="1"
android:text="다음 그림"/>
</LinearLayout>
<kr.jeongmo.a0502project.MyPictureView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/myPictureView"/>
</LinearLayout>
package kr.jeongmo.a0502project
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.util.Log.println
import android.widget.Button
import androidx.core.app.ActivityCompat
import java.io.File
class MainActivity : AppCompatActivity() {
lateinit var btnPrev : Button
lateinit var btnNext : Button
lateinit var myPicture : MyPictureView
var curNum : Int = 1
var imageFiles : Array<File>? = null
lateinit var imageFname : String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "간단 이미지 뷰어"
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE),
Context.MODE_PRIVATE
)
btnPrev = findViewById(R.id.btnPrev)
btnNext = findViewById(R.id.btnNext)
myPicture = findViewById(R.id.myPictureView)
imageFiles =
File(Environment.getExternalStorageDirectory().absolutePath + "/Pictures").listFiles()
// 파일 목록 출력
var fileName = ""
for (i in imageFiles!!.indices) {
if (imageFiles!![i].isDirectory == true)
fileName = "<폴더> " + imageFiles!![i].toString()
else
fileName = "<파일> " + imageFiles!![i].toString()
}
imageFname = imageFiles!![1].toString()
myPicture.imagePath = imageFname
}
}
- 프로젝트 실행 하면 이미지 출력 확인
package kr.jeongmo.a0502project
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.util.Log.println
import android.widget.Button
import android.widget.Toast
import androidx.core.app.ActivityCompat
import java.io.File
class MainActivity : AppCompatActivity() {
lateinit var btnPrev : Button
lateinit var btnNext : Button
lateinit var myPicture : MyPictureView
var curNum : Int = 1
var imageFiles : Array<File>? = null
lateinit var imageFname : String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "간단 이미지 뷰어"
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE),
Context.MODE_PRIVATE
)
btnPrev = findViewById(R.id.btnPrev)
btnNext = findViewById(R.id.btnNext)
myPicture = findViewById(R.id.myPictureView)
imageFiles =
File(Environment.getExternalStorageDirectory().absolutePath + "/Pictures").listFiles()
// 파일 목록 출력
var fileName = ""
for (i in imageFiles!!.indices) {
if (imageFiles!![i].isDirectory == true)
fileName = "<폴더> " + imageFiles!![i].toString()
else
fileName = "<파일> " + imageFiles!![i].toString()
}
imageFname = imageFiles!![1].toString()
myPicture.imagePath = imageFname
btnPrev.setOnClickListener {
if (curNum <= 1) {
Toast.makeText(applicationContext, "첫번째 그림입니다.", Toast.LENGTH_SHORT).show()
} else {
curNum--
imageFname = imageFiles!![curNum].toString()
myPicture.imagePath=imageFname
myPicture.invalidate()
}
}
btnNext.setOnClickListener {
if (curNum >= imageFiles!!.size-1) {
Toast.makeText(applicationContext, "마지막 그림입니다.", Toast.LENGTH_SHORT).show()
} else {
curNum++
imageFname = imageFiles!![curNum].toString()
myPicture.imagePath=imageFname
myPicture.invalidate()
}
}
}
}
- 코드 추가
- 프로젝트 실행 후 이미지 변화 확인
MyPictureView.imagePath = imageFiles!![curIndex].toString()
btnPrev.setOnClickListener {
if (curIndex <= 1) {
Toast.makeText(applicationContext, "첫번째 그림입니다.", Toast.LENGTH_SHORT).show()
} else {
MyPictureView.imagePath = imageFiles!![--curIndex].toString()
MyPictureView.invalidate()
}
}
btnNext.setOnClickListener {
if (curIndex >= imageFiles!!.size-1) {
Toast.makeText(applicationContext, "마지막 그림입니다.", Toast.LENGTH_SHORT).show()
} else {
MyPictureView.imagePath = imageFiles!![++curIndex].toString()
MyPictureView.invalidate()
}
}
- 아래 쪽 코드 위 처럼 축약 가능
5. 파일처리 - 파일 갯수 표시
age kr.jeongmo.a0502_project_02
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.core.app.ActivityCompat
import java.io.File
class MainActivity : AppCompatActivity() {
lateinit var btnPrev : Button
lateinit var btnNext : Button
lateinit var textView : TextView
lateinit var MyPictureView : MyPictureView
var curIndex : Int = 1
var imageFiles : Array<File>? = null
lateinit var imageFname : String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "간단 이미지 뷰어"
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE),
Context.MODE_PRIVATE
)
btnPrev = findViewById(R.id.btnPrev)
btnNext = findViewById(R.id.btnNext)
textView = findViewById(R.id.textView)
MyPictureView = findViewById(R.id.myPictureView)
imageFiles =
File(Environment.getExternalStorageDirectory().absolutePath + "/Pictures").listFiles()
// 파일 목록 출력
var fileName = ""
for (i in imageFiles!!.indices) {
if (imageFiles!![i].isDirectory == true)
fileName = "<폴더> " + imageFiles!![i].toString()
else
fileName = "<파일> " + imageFiles!![i].toString()
}
MyPictureView.imagePath = imageFiles!![curIndex].toString()
btnPrev.setOnClickListener {
if (curIndex <= 1) {
Toast.makeText(applicationContext, "첫번째 그림입니다.", Toast.LENGTH_SHORT).show()
textView.text = "1/9"
} else {
MyPictureView.imagePath = imageFiles!![--curIndex].toString()
textView.text = curIndex.toString() + "/9"
MyPictureView.invalidate()
}
}
btnNext.setOnClickListener {
if (curIndex >= imageFiles!!.size-2) {
Toast.makeText(applicationContext, "마지막 그림입니다.", Toast.LENGTH_SHORT).show()
textView.text = "9/9"
} else {
MyPictureView.imagePath = imageFiles!![++curIndex].toString()
textView.text = curIndex.toString() + "/9"
MyPictureView.invalidate()
}
}
}
공부 과정을 정리한 것이라 내용이 부족할 수 있습니다.
부족한 내용은 추가 자료들로 보충해주시면 좋을 것 같습니다.
읽어주셔서 감사합니다 :)