'2020/05/09'에 해당되는 글 2건

728x90

화면 전환을 한 경우, 로그인 화면은 다시 보이지 않도록 해야 한다.

 

val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK)
// FLAG_ACTIVITY_CLEARTOP : 실행할 activity가 이미 스택에 존재하면 해당 activity 위에 존재하는 다른 activity 모두 종료시킨다.
// FLAG_ACTIVITY_SINGLE_TOP : 호출하는 activity가 자신을 가리키는 경우, 기존의 activity를 재활용한다.
// 활동의 인스턴스가 이미 현재 작업의 맨 위에 있으면 시스템은 활동의 새 인스턴스를 생성하지 않고
// onNewIntent() 메서드를 호출하여 인텐트를 기존 인스턴스로 라우팅한다.
// https://developer.android.com/guide/components/activities/tasks-and-back-stack 읽어보면 된다.
// FLAG_ACTIVITY_CLEAR_TASK :
// FLAG_ACTIVITY_NEW_TASK : service, notification 등에서 액티비티를 시작하기 위해선 꼭 붙여야 한다.
// 스택에 없으면 새로운 task 생성하고 launch 시키고, 스택에 있으면 해당 task가 Foreground로 온다.
startActivity(intent)
finish() // 현재 activity 제거. login 화면은 다시 사용하지 않도록 하기 위해서
 

 

 

 

 

메모를 추가/수정하고, AddEditMemoActivity 를 종료하면서, 아래와 같은 FLAG를 지정한 경우

val intent = Intent(this@AddEditMemoActivity, MainActivity::class.java)
intent.apply {
    this.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
}
startActivity(intent)
overridePendingTransition(R.anim.fadein, R.anim.fadeout)
finish()
 

 

MainActivity 는 onNewIntent 를 수행하므로 여기에 필요한 코드를 추가한다.

 
override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    Log.d(TAG, "onNewIntent()")
    getMemoFromServer()
}
블로그 이미지

Link2Me

,
728x90

Java 기반 volley 라이브러리에 대한 사용예제는 https://link2me.tistory.com/1533 를 참조하면 된다.


앱 build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.link2me.android.volley"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

    implementation 'com.google.android.material:material:1.1.0'
    implementation 'gun0912.ted:tedpermission:2.0.0'
    implementation 'com.android.volley:volley:1.1.1'
}


AndroidManifest.xml

- 필요한 퍼미션을 추가한다.

- android:usesCleartextTraffic="true" 를 추가한다. Android 9 이상에서 http 통신 가능하도록 하기 위해서.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.link2me.android.volley">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    <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/AppTheme.NoActionBar"
        android:usesCleartextTraffic="true">
        <activity android:name=".LoginActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity" />
    </application>

</manifest>
 


activity_login.xml

- https://link2me.tistory.com/1807 참조


LoginActivity.kt

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.telephony.PhoneNumberUtils
import android.telephony.TelephonyManager
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import kotlinx.android.synthetic.main.activity_login.*
import org.json.JSONException
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.HashMap

class LoginActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        context = this@LoginActivity
        initView()
    }

    fun initView() {
        // 코틀린에서는 더 이상 findViewById()를 사용하지 않아도 된다.
        // Kotlin Android Extension 만 적용시키면, 레이아웃 import 시키는 것만으로도 XML에서 정의내린 위젯들을 Id로 읽어들인다.
        btn_login.setOnClickListener{
            val url: String = "http://www.abc.com/mobile/mlogin.php"
            val loginID: String = et_id.text.toString().trim()
            val loginPW: String = et_pw.text.toString().trim()
            loginVolley(this, url, loginID, loginPW)
        }
    }

    private fun loginVolley(context: Context, url: String, userid: String, password: String) {
        // https://developer.android.com/training/volley/simple GET 방법

        // 1. RequestQueue 생성 및 초기화
        val requestQueue = Volley.newRequestQueue(context)

        // 2. Request Obejct인 StringRequest 생성
        val request: StringRequest = object : StringRequest(Method.POST, url,
            Response.Listener { response ->
                showJSONList(response)
            },
            Response.ErrorListener { error ->
                Toast.makeText(context, error.toString(), Toast.LENGTH_LONG).show()
            }
        ) {
            override fun getParams(): Map<String, String> {
                val params: MutableMap<String,String> = HashMap()
                params["userid"] = userid
                params["password"] = password
                params["mobileNO"] = getPhoneNumber() // 로그인하는 휴대폰번호 정보
                params["uID"] = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
                return params
            }
        }
        // 3) 생성한 StringRequest를 RequestQueue에 추가
        requestQueue.add(request)
    }

    fun showJSONList(response: String) {
        try {
            Log.e("TAG",response)
            val jsonObject = JSONObject(response)
            jsonObject.let {
                if(it.getString("userinfo") == null) {
                    showAlert(it.getString("result").toString(), it.getString("message").toString())
                } else {
                    if(it.getString("result").toString().equals("success")){
                        val jsonInfo = JSONObject(it.getString("userinfo").toString())
                        jsonInfo.let{
                            // Preference 에 대한 정보 기록은 생략한다.
                            startActivity(Intent(this,MainActivity::class.java))
                        }
                    }
                }
            }
        } catch (e: JSONException) {
            e.printStackTrace()
        }
    }

    companion object {
        var context: Context? = null

        @SuppressLint("MissingPermission") // TED퍼미션을 미리 설정했다는 가정하에
        fun getPhoneNumber(): String {
            var phoneNumber = ""
            try {
                val telephony = context?.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
                if (telephony.line1Number != null) {
                    phoneNumber = telephony.line1Number
                } else {
                    if (telephony.simSerialNumber != null) {
                        phoneNumber = telephony.simSerialNumber
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
            if (phoneNumber.startsWith("+82")) {
                phoneNumber = phoneNumber.replace("+82", "0")
            }
            phoneNumber = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                PhoneNumberUtils.formatNumber(
                    phoneNumber,
                    Locale.getDefault().country
                )
            } else {
                PhoneNumberUtils.formatNumber(phoneNumber)
            }
            return phoneNumber
        }

        fun showAlert(title: String, message: String) {
            val builder = context?.let {
                AlertDialog.Builder(it)
                    .setTitle(title)
                    .setMessage(message)
                    .setCancelable(false)
                    .setPositiveButton("OK") { dialog, id -> dialog.dismiss() }
            }
            val alert = builder!!.create()
            alert.show()
        }
    }

}


블로그 이미지

Link2Me

,