diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..5489fee
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..07edeb0
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..762edfb
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,94 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+
+android {
+ compileSdkVersion 25
+ buildToolsVersion "25.0.3"
+ defaultConfig {
+ applicationId "org.ntlab.tag"
+ minSdkVersion 21
+ targetSdkVersion 25
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+ packagingOptions {
+ exclude 'META-INF/rxjava.properties'
+ exclude 'META-INF/DEPENDENCIES.txt'
+ exclude 'META-INF/LICENSE.txt'
+ exclude 'META-INF/LICENSE.md'
+ exclude 'META-INF/NOTICE.txt'
+ exclude 'META-INF/NOTICE'
+ exclude 'META-INF/LICENSE'
+ exclude 'META-INF/DEPENDENCIES'
+ exclude 'META-INF/notice.txt'
+ exclude 'META-INF/license.txt'
+ exclude 'META-INF/dependencies.txt'
+ exclude 'META-INF/LGPL2.1'
+ exclude 'META-INF/ASL2.0'
+ }
+ dataBinding {
+ enabled = true
+ }
+}
+
+kapt {
+ generateStubs = true
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
+ implementation 'com.android.support:appcompat-v7:25.4.0'
+ testImplementation 'junit:junit:4.12'
+
+ // google map
+ implementation 'com.google.android.gms:play-services-maps:9.8.0'
+ implementation 'com.android.support.constraint:constraint-layout:1.0.2'
+
+ // Android Desigh
+ compile 'com.android.support:design:25.4.0'
+
+ // Card View
+ // CardView
+ compile "com.android.support:cardview-v7:25.4.0"
+
+ // Android BootStrap
+ compile 'com.beardedhen:androidbootstrap:2.3.1'
+
+ // OkHttp
+ compile 'com.squareup.okhttp3:okhttp:3.7.0'
+
+ // rxJava, rxAndroid
+ compile 'io.reactivex.rxjava2:rxjava:2.0.0-RC3'
+ compile 'io.reactivex.rxjava2:rxandroid:2.0.0-RC1'
+
+ // retrofit2
+ compile 'com.squareup.retrofit2:converter-gson:2.1.0'
+ compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
+ compile 'com.squareup.retrofit2:retrofit:2.1.0'
+
+ // chuck
+ compile 'com.readystatesoftware.chuck:library:1.0.4'
+
+ // Kotlin DataBinding
+ kapt 'com.android.databinding:compiler:2.5.0-alpha-preview-02'
+
+ // StyleableToast
+ compile 'com.muddzdev:styleabletoast:1.0.9'
+ implementation 'com.android.support:support-v4:25.4.0'
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..45bcd7b
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/matsumoto_k/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/org/ntlab/tag/ExampleInstrumentedTest.kt b/app/src/androidTest/java/org/ntlab/tag/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..a383e38
--- /dev/null
+++ b/app/src/androidTest/java/org/ntlab/tag/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package org.ntlab.tag
+
+import android.support.test.InstrumentationRegistry
+import android.support.test.runner.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getTargetContext()
+ assertEquals("org.ntlab.tag", appContext.packageName)
+ }
+}
diff --git a/app/src/debug/res/values/google_maps_api.xml b/app/src/debug/res/values/google_maps_api.xml
new file mode 100644
index 0000000..3a74e45
--- /dev/null
+++ b/app/src/debug/res/values/google_maps_api.xml
@@ -0,0 +1,24 @@
+
+
+ AIzaSyBMnFFA8Azg2BssGUGiN3cu8UbuzTyq_tU
+
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..f1fddd5
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/tag/MainActivity.kt b/app/src/main/java/org/ntlab/tag/MainActivity.kt
new file mode 100644
index 0000000..b01b6e0
--- /dev/null
+++ b/app/src/main/java/org/ntlab/tag/MainActivity.kt
@@ -0,0 +1,12 @@
+package org.ntlab.tag
+
+import android.support.v7.app.AppCompatActivity
+import android.os.Bundle
+
+class MainActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+ }
+}
diff --git a/app/src/main/kotlin/org/ntlab/tag/App.kt b/app/src/main/kotlin/org/ntlab/tag/App.kt
new file mode 100644
index 0000000..c5816f6
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/App.kt
@@ -0,0 +1,25 @@
+package org.ntlab.tag
+
+import android.app.Application
+import org.ntlab.tag.model.MyPreferenceManager
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class App : Application() {
+ override fun onCreate() {
+ super.onCreate()
+ MyPreferenceManager.init(this)
+ }
+
+ fun getUserId() = MyPreferenceManager.getPref(Constant.USER_ID, -1)
+ fun getUserName() = MyPreferenceManager.getPref(Constant.USER_NAME, "none")
+
+ fun setUserId(userId: Int) {
+ MyPreferenceManager.setPref(Constant.USER_ID, userId)
+ }
+
+ fun setUsername(userName: String) {
+ MyPreferenceManager.setPref(Constant.USER_NAME, userName)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/Constant.kt b/app/src/main/kotlin/org/ntlab/tag/Constant.kt
new file mode 100644
index 0000000..8960c5b
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/Constant.kt
@@ -0,0 +1,16 @@
+package org.ntlab.tag
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class Constant {
+ companion object {
+ const val END_POINT = "http://10.0.2.2:8080/TagServer/webapi/"
+
+ /**
+ * SharedPreferencesのkey
+ */
+ const val USER_ID = "userId"
+ const val USER_NAME = "userName"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/activity/InRoomActivity.kt b/app/src/main/kotlin/org/ntlab/tag/activity/InRoomActivity.kt
new file mode 100644
index 0000000..00c889f
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/activity/InRoomActivity.kt
@@ -0,0 +1,58 @@
+package org.ntlab.tag.activity
+
+import android.content.Intent
+import android.databinding.DataBindingUtil
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.LinearLayoutManager
+import kotlinx.android.synthetic.main.activity_in_room.*
+import org.ntlab.tag.R
+import org.ntlab.tag.adapter.InRoomListAdapter
+import org.ntlab.tag.api.regist.RoomApiResponse
+import org.ntlab.tag.contract.InRoomListViewContract
+import org.ntlab.tag.databinding.ActivityInRoomBinding
+import org.ntlab.tag.viewmodel.InRoomViewModel
+
+class InRoomActivity : AppCompatActivity(), InRoomListViewContract {
+
+ var viewModel: InRoomViewModel? = null
+ var adapter: InRoomListAdapter? = null
+ var roomData: RoomApiResponse? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val binding = DataBindingUtil.setContentView(this, R.layout.activity_in_room)
+ setUpViews()
+
+
+ roomData = intent.getSerializableExtra("roomData") as RoomApiResponse
+ viewModel = InRoomViewModel(this, this as InRoomListViewContract, adapter!!)
+ binding.viewModel = viewModel
+ }
+
+ fun setUpViews() {
+ inRoomRecyclerView.layoutManager = LinearLayoutManager(this)
+ adapter = InRoomListAdapter(this, this as InRoomListViewContract)
+ inRoomRecyclerView.adapter = adapter
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ viewModel?.onDestroy()
+ }
+
+ override fun getRoomInfo(): RoomApiResponse {
+ return this.roomData!!
+ }
+
+ override fun startActivity(item: RoomApiResponse) {
+ val intent = Intent(this@InRoomActivity, TagActivity::class.java)
+ intent.putExtra("roomData", item)
+ startActivity(intent)
+ }
+
+ override fun finishActivity() {
+ viewModel?.finishActivity()
+ finish()
+ }
+}
diff --git a/app/src/main/kotlin/org/ntlab/tag/activity/RegistActivity.kt b/app/src/main/kotlin/org/ntlab/tag/activity/RegistActivity.kt
new file mode 100644
index 0000000..24cd278
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/activity/RegistActivity.kt
@@ -0,0 +1,42 @@
+package org.ntlab.tag.activity
+
+import android.content.Intent
+import android.databinding.DataBindingUtil
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import org.ntlab.tag.App
+import org.ntlab.tag.R
+import org.ntlab.tag.contract.RegistContract
+import org.ntlab.tag.databinding.ActivityRegistBinding
+import org.ntlab.tag.utils.sensor.GpsSensor
+import org.ntlab.tag.viewmodel.RegistViewModel
+
+class RegistActivity : AppCompatActivity(), RegistContract {
+ var viewModel: RegistViewModel? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ val gpsSensor = GpsSensor()
+ gpsSensor.checkSensor(this)
+
+ val app = App()
+ if (app.getUserId() != -1) {
+ startActivity()
+ }
+
+ val binding = DataBindingUtil.setContentView(this, R.layout.activity_regist);
+ viewModel = RegistViewModel(this as RegistContract)
+ binding.viewModel = viewModel
+ }
+
+ override fun startActivity() {
+ startActivity(Intent(this@RegistActivity, RoomListActivity::class.java))
+ finish()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ viewModel?.onDestroy()
+ }
+}
diff --git a/app/src/main/kotlin/org/ntlab/tag/activity/RoomListActivity.kt b/app/src/main/kotlin/org/ntlab/tag/activity/RoomListActivity.kt
new file mode 100644
index 0000000..b296208
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/activity/RoomListActivity.kt
@@ -0,0 +1,65 @@
+package org.ntlab.tag.activity
+
+import android.content.Intent
+import android.databinding.DataBindingUtil
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.LinearLayoutManager
+import kotlinx.android.synthetic.main.activity_room_list.*
+import org.ntlab.tag.R
+import org.ntlab.tag.adapter.RoomListAdapter
+import org.ntlab.tag.api.regist.RoomApiResponse
+import org.ntlab.tag.contract.RoomListViewContract
+import org.ntlab.tag.databinding.ActivityRoomListBinding
+import org.ntlab.tag.viewmodel.RoomViewModel
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class RoomListActivity : AppCompatActivity(), RoomListViewContract {
+
+ var viewModel: RoomViewModel? = null
+ var adapter: RoomListAdapter? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ val binding = DataBindingUtil.setContentView(this, R.layout.activity_room_list)
+
+ setUpViews()
+
+ viewModel = RoomViewModel(this, adapter!!, this as RoomListViewContract)
+ binding.viewModel = viewModel
+ }
+
+ fun setUpViews() {
+ roomRecyclerView.layoutManager = LinearLayoutManager(this)
+ adapter = RoomListAdapter(this, this as RoomListViewContract)
+ roomRecyclerView.adapter = adapter
+ }
+
+ override fun showRoom(items: ArrayList) {
+ adapter?.setItemAndRefresh(items)
+ }
+
+ override fun startRoomDetailActivity(item: RoomApiResponse) {
+ val intent = Intent(this@RoomListActivity, InRoomActivity::class.java)
+ intent.putExtra("roomData", item)
+ startActivity(intent)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ viewModel?.onDestroy()
+ }
+
+ override fun onStart() {
+ super.onStart()
+ viewModel?.onStart()
+ }
+
+ override fun onStop() {
+ super.onStop()
+ viewModel?.onStop()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/activity/TagActivity.kt b/app/src/main/kotlin/org/ntlab/tag/activity/TagActivity.kt
new file mode 100644
index 0000000..335a537
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/activity/TagActivity.kt
@@ -0,0 +1,91 @@
+package org.ntlab.tag.activity
+
+import android.annotation.SuppressLint
+import android.databinding.DataBindingUtil
+import android.os.Bundle
+import android.support.v4.app.FragmentActivity
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.OnMapReadyCallback
+import com.google.android.gms.maps.SupportMapFragment
+import com.google.android.gms.maps.model.MapStyleOptions
+import com.google.android.gms.maps.model.Marker
+import org.ntlab.tag.App
+import org.ntlab.tag.R
+import org.ntlab.tag.api.regist.RoomApiResponse
+import org.ntlab.tag.databinding.ActivityTagBinding
+import org.ntlab.tag.model.GpsModel
+import org.ntlab.tag.utils.sensor.GpsSensor
+import org.ntlab.tag.viewmodel.TagViewModel
+import java.util.*
+import kotlin.collections.HashMap
+
+class TagActivity : FragmentActivity(), OnMapReadyCallback {
+
+ private var mMap: GoogleMap? = null
+ private var timer: Timer? = null
+ private var tagId: Int = -1
+ private var userId: Int = -1
+ private var maxRoomNum: Int = -1
+ private var myLocationLoad = false;
+ private var load = false;
+ private var demonUserId = -1;
+ private var demonChangeFlug = false;
+ private var app: App? = null
+
+ private var viewModel: TagViewModel? = null
+
+ // 自分の位置のマーカー
+ private var myLocationMarker: Marker? = null
+ // 味方の位置のマーカー
+ private var otherPlayerMarker: HashMap = HashMap()
+
+ companion object {
+ const val RequireMyLocation = "RequireMyLocation"
+ const val ChangeMyLocation = "ChangeMyLocation"
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ val roomData: RoomApiResponse = intent.getSerializableExtra("roomData") as RoomApiResponse
+
+ val binding = DataBindingUtil.setContentView(this, R.layout.activity_tag)
+ viewModel = TagViewModel(this, roomData)
+ binding.viewModel = viewModel
+
+ val gpsSensor = GpsSensor()
+ gpsSensor.checkSensor(this)
+
+ val mapFragment = supportFragmentManager
+ .findFragmentById(R.id.map) as SupportMapFragment
+ mapFragment.getMapAsync(this)
+
+ viewModel?.setRxBus()
+ }
+
+ override fun onPostResume() {
+ super.onPostResume()
+ GpsModel.settingGpsModel(this)
+ GpsModel.startGps(this)
+
+ viewModel?.onPostResume()
+
+ }
+
+ override fun onPause() {
+ super.onStop()
+ GpsModel.stopGps()
+ viewModel?.onPause()
+ }
+
+
+ @SuppressLint("MissingPermission")
+ override fun onMapReady(googleMap: GoogleMap) {
+ mMap = googleMap
+ this.mMap?.setIndoorEnabled(false)
+ this.mMap?.uiSettings?.isIndoorLevelPickerEnabled = false
+ this.mMap?.uiSettings?.isMapToolbarEnabled = false
+ this.mMap?.setMapStyle(MapStyleOptions.loadRawResourceStyle(this, R.raw.style_json))
+ viewModel?.setMap(mMap!!)
+ }
+}
diff --git a/app/src/main/kotlin/org/ntlab/tag/adapter/InRoomListAdapter.kt b/app/src/main/kotlin/org/ntlab/tag/adapter/InRoomListAdapter.kt
new file mode 100644
index 0000000..349f5d5
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/adapter/InRoomListAdapter.kt
@@ -0,0 +1,69 @@
+package org.ntlab.tag.adapter
+
+import android.content.Context
+import android.databinding.DataBindingUtil
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import org.ntlab.tag.R
+import org.ntlab.tag.api.regist.RoomApiResponse
+import org.ntlab.tag.contract.InRoomListViewContract
+import org.ntlab.tag.databinding.InRoomListItemBinding
+import org.ntlab.tag.viewmodel.InRoomItemViewModel
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class InRoomListAdapter(var context: Context, var view: InRoomListViewContract) : RecyclerView.Adapter() {
+
+ var items: ArrayList? = null
+
+ inner class ViewHolder(var itemView: View, viewModel: InRoomItemViewModel) : RecyclerView.ViewHolder(itemView) {
+ var viewModel: InRoomItemViewModel? = null
+
+ init {
+ this.viewModel = viewModel
+ }
+
+
+ fun loadItem(item: RoomApiResponse.RoomPlayerList) {
+ viewModel?.loadItem(getItemPosition(item), item)
+ }
+ }
+
+ fun setItemAndRefresh(items: ArrayList) {
+ println("setItemAndRefresh")
+ this.items = items
+ notifyDataSetChanged()
+ }
+
+ fun getItemPosition(item: RoomApiResponse.RoomPlayerList): Int {
+ if (items?.size != 0) {
+ return items?.indexOf(item)!!
+ }
+ return 0
+ }
+
+ fun getItemAt(position: Int): RoomApiResponse.RoomPlayerList? {
+ return items?.get(position)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
+ val item = getItemAt(position)
+ holder?.loadItem(item!!)
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
+ val binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.in_room_list_item, parent, false)
+ binding.viewModel = InRoomItemViewModel(view)
+ return ViewHolder(binding.root, binding.viewModel!!)
+ }
+
+ override fun getItemCount(): Int {
+ if (items == null) {
+ return 0
+ }
+ return items?.size!!
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/adapter/RoomListAdapter.kt b/app/src/main/kotlin/org/ntlab/tag/adapter/RoomListAdapter.kt
new file mode 100644
index 0000000..eeccbae
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/adapter/RoomListAdapter.kt
@@ -0,0 +1,60 @@
+package org.ntlab.tag.adapter
+
+import android.content.Context
+import android.databinding.DataBindingUtil
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import org.ntlab.tag.R
+import org.ntlab.tag.api.regist.RoomApiResponse
+import org.ntlab.tag.contract.RoomListViewContract
+import org.ntlab.tag.databinding.RoomListItemBinding
+import org.ntlab.tag.viewmodel.ListItemViewModel
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class RoomListAdapter(var context: Context, var view: RoomListViewContract) : RecyclerView.Adapter() {
+
+ var items: ArrayList? = null
+
+ inner class ViewHolder(itemView: View, viewModel: ListItemViewModel) : RecyclerView.ViewHolder(itemView) {
+ var viewModel: ListItemViewModel? = null
+
+ init {
+ this.viewModel = viewModel
+ }
+
+ fun loadItem(item: RoomApiResponse) {
+ viewModel?.loadItem(item)
+ }
+ }
+
+ fun setItemAndRefresh(items: ArrayList) {
+ this.items = items
+ notifyDataSetChanged()
+ }
+
+ fun getItemAt(position: Int): RoomApiResponse? {
+ return items?.get(position)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
+ val item = getItemAt(position)
+ holder?.loadItem(item!!)
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
+ val binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.room_list_item, parent, false)
+ binding.viewModel = ListItemViewModel(view)
+ return ViewHolder(binding.root, binding.viewModel!!)
+ }
+
+ override fun getItemCount(): Int {
+ if (items == null) {
+ return 0
+ }
+ return items?.size!!
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/BaseApi.kt b/app/src/main/kotlin/org/ntlab/tag/api/BaseApi.kt
new file mode 100644
index 0000000..5ab5fe2
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/BaseApi.kt
@@ -0,0 +1,25 @@
+package org.ntlab.tag.api
+
+import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
+import org.ntlab.tag.Constant
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+open class BaseApi {
+ var endpoint = Constant.END_POINT;
+
+ fun getClient(): Retrofit {
+// val builder = OkHttpClient.Builder()
+// val okHttpClient = builder.addInterceptor(ChuckInterceptor(this)).build()
+ val retrofit = Retrofit.Builder()
+ .baseUrl(endpoint)
+ .addConverterFactory(GsonConverterFactory.create())
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+ .build()
+ return retrofit
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/regist/RegistApiClient.kt b/app/src/main/kotlin/org/ntlab/tag/api/regist/RegistApiClient.kt
new file mode 100644
index 0000000..29bfaa3
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/regist/RegistApiClient.kt
@@ -0,0 +1,41 @@
+package org.ntlab.tag.api.regist
+
+import io.reactivex.Observer
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
+import org.ntlab.tag.api.BaseApi
+import org.ntlab.tag.model.RxBus
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+object RegistApiClient : BaseApi() {
+
+ fun regist(userName: String) {
+ val registService = getClient().create(RegistService::class.java).postRegist(userName)
+ registService.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable?) {
+ println("onSubscribe")
+ }
+
+ override fun onComplete() {
+ println("test")
+ }
+
+ override fun onNext(value: RegistApiResponse?) {
+ if (value != null) {
+ RxBus.send(value)
+ }
+ println("onNext")
+ }
+
+ override fun onError(e: Throwable?) {
+ println("onError")
+ }
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/regist/RegistApiResponse.kt b/app/src/main/kotlin/org/ntlab/tag/api/regist/RegistApiResponse.kt
new file mode 100644
index 0000000..86230f5
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/regist/RegistApiResponse.kt
@@ -0,0 +1,9 @@
+package org.ntlab.tag.api.regist
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class RegistApiResponse(
+ var userId: Int,
+ var userName: String
+)
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/regist/RegistService.kt b/app/src/main/kotlin/org/ntlab/tag/api/regist/RegistService.kt
new file mode 100644
index 0000000..29bcc3f
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/regist/RegistService.kt
@@ -0,0 +1,18 @@
+package org.ntlab.tag.api.regist
+
+import io.reactivex.Observable
+import retrofit2.http.POST
+import retrofit2.http.Query
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+interface RegistService {
+
+ /**
+ * Account作成
+ */
+ @POST("accounts")
+ fun postRegist(@Query("userName") userName: String): Observable
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/room/RoomApiClient.kt b/app/src/main/kotlin/org/ntlab/tag/api/room/RoomApiClient.kt
new file mode 100644
index 0000000..d4a6b88
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/room/RoomApiClient.kt
@@ -0,0 +1,172 @@
+package org.ntlab.tag.api.regist
+
+import io.reactivex.Observer
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
+import org.ntlab.tag.Constant
+import org.ntlab.tag.api.BaseApi
+import org.ntlab.tag.model.RxBus
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+object RoomApiClient : BaseApi() {
+
+ fun getRooms() {
+ val getRoomService = getClient().create(RoomService::class.java).getRooms()
+ getRoomService.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Observer> {
+ override fun onSubscribe(d: Disposable?) {
+ println("onSubscribeGetRoom")
+ }
+
+ override fun onComplete() {
+ println("test")
+ }
+
+ override fun onNext(value: ArrayList?) {
+ if (value != null) {
+ RxBus.send(value)
+ }
+ }
+
+ override fun onError(e: Throwable?) {
+ println("onError")
+ println(e?.message)
+ }
+ })
+ }
+
+ fun postRooms(userId: Int, roomName: String) {
+ val getRoomService = getClient().create(RoomService::class.java).postRooms(userId, roomName)
+ getRoomService.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable?) {
+ println("onSubscribePostRoom")
+ }
+
+ override fun onComplete() {
+ }
+
+ override fun onNext(value: RoomApiResponse?) {
+ if (value != null) {
+ RxBus.send(value)
+ }
+ }
+
+ override fun onError(e: Throwable?) {
+ println("onError")
+ println(e?.message)
+ }
+ })
+ }
+
+ fun putRooms(userId: Int, roomId: Int) {
+ val getRoomService = getClient().create(RoomService::class.java).putRooms(userId, roomId)
+ getRoomService.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable?) {
+ println("onSubscribePutRoom")
+ }
+
+ override fun onComplete() {
+ }
+
+ override fun onNext(value: RoomApiResponse?) {
+ if (value != null) {
+ RxBus.send(value)
+ }
+ }
+
+ override fun onError(e: Throwable?) {
+ println("onError")
+ println(e?.message)
+ }
+ })
+ }
+
+ fun outRoom(out: String) {
+ println("${Constant.END_POINT}rooms/${out}")
+ print("outRoomですよ")
+ val outRoomService = getClient().create(RoomService::class.java).outRooms(out)
+ outRoomService.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object :Observer{
+ override fun onComplete() {
+
+ }
+
+ override fun onError(e: Throwable?) {
+ println(e)
+ }
+
+ override fun onSubscribe(d: Disposable?) {
+
+ }
+
+ override fun onNext(value: Void?) {
+ println("onNext")
+ }
+ })
+
+ }
+
+ fun deleteRoom(roomId: Int) {
+ getClient().create(RoomService::class.java).deleteRoom(roomId)
+ }
+
+ fun getInRoom(userId: Int, roomId: Int) {
+ val getRoomService = getClient().create(RoomService::class.java).getRoom(roomId = roomId, userId = userId)
+ getRoomService.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable?) {
+ println("onSubscribePutRoom")
+ }
+
+ override fun onComplete() {
+ }
+
+ override fun onNext(value: RoomApiResponse?) {
+ if (value != null) {
+ RxBus.send(value)
+ }
+ }
+
+ override fun onError(e: Throwable?) {
+ println("onError")
+ println(e?.message)
+ }
+ })
+ }
+
+ fun updateRoom(userId: Int, roomId: Int, start: Boolean, ready: Boolean) {
+ val getRoomService = getClient().create(RoomService::class.java).updateRoom(roomId = roomId, userId = userId, ready = ready, start = start)
+ getRoomService.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable?) {
+ println("onSubscribePutRoom")
+ }
+
+ override fun onComplete() {
+ }
+
+ override fun onNext(value: RoomApiResponse?) {
+ if (value != null) {
+ RxBus.send(value)
+ }
+ }
+
+ override fun onError(e: Throwable?) {
+ println("onError")
+ println(e?.message)
+ }
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/room/RoomApiResponse.kt b/app/src/main/kotlin/org/ntlab/tag/api/room/RoomApiResponse.kt
new file mode 100644
index 0000000..619fac8
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/room/RoomApiResponse.kt
@@ -0,0 +1,26 @@
+package org.ntlab.tag.api.regist
+
+import java.io.Serializable
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class RoomApiResponse(
+ var hostUserId: Int,
+ var hostUserName: String,
+ var roomId: Int,
+ var roomName: String,
+ var start: Boolean,
+ var success: Boolean,
+ var allReady: Boolean,
+ var tagId: Int,
+ var maxRoomNum: Int,
+ var roomPlayerList: ArrayList
+) : Serializable {
+ inner class RoomPlayerList(
+ var host: Boolean,
+ var ready: Boolean,
+ var userId: Int,
+ var userName: String
+ ) : Serializable
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/room/RoomService.kt b/app/src/main/kotlin/org/ntlab/tag/api/room/RoomService.kt
new file mode 100644
index 0000000..3864da3
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/room/RoomService.kt
@@ -0,0 +1,52 @@
+package org.ntlab.tag.api.regist
+
+import io.reactivex.Observable
+import retrofit2.http.*
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+interface RoomService {
+
+ /**
+ * Room一覧
+ */
+ @GET("rooms")
+ fun getRooms(): Observable>
+
+ /**
+ * Room作成
+ */
+ @POST("rooms")
+ fun postRooms(@Query("userId") userId: Int, @Query("roomName") roomName: String): Observable
+
+ /**
+ * Room入室
+ */
+ @PUT("rooms")
+ fun putRooms(@Query("userId") userId: Int, @Query("roomId") roomId: Int): Observable
+
+ /**
+ * Room退出
+ */
+ @PUT("rooms/{out}")
+ fun outRooms(@Path(value = "out", encoded = true) out: String): Observable
+
+ /**
+ * Room削除
+ */
+ @DELETE("rooms")
+ fun deleteRoom(@Query("roomId") roomId: Int)
+
+ /**
+ * Room内部の情報取得
+ */
+ @GET("rooms/{roomId}")
+ fun getRoom(@retrofit2.http.Path(value = "roomId", encoded = false) roomId: Int, @Query("userId") userId: Int): Observable
+
+ /**
+ * Room内部の情報更新
+ */
+ @PUT("rooms/{roomId}")
+ fun updateRoom(@retrofit2.http.Path(value = "roomId", encoded = false) roomId: Int, @Query("userId") userId: Int, @Query("start") start: Boolean = false, @Query("ready") ready: Boolean = false): Observable
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/tag/ApiBodyPojo.kt b/app/src/main/kotlin/org/ntlab/tag/api/tag/ApiBodyPojo.kt
new file mode 100644
index 0000000..12b3903
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/tag/ApiBodyPojo.kt
@@ -0,0 +1,11 @@
+package org.ntlab.tag.api.tag
+
+/**
+ * Created by matsumoto_k on 2017/07/08.
+ */
+class ApiBodyPojo(
+ var userId: Int,
+ var latitude: Double,
+ var longitude: Double,
+ var isDemon: Boolean
+)
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/tag/TagApiClient.kt b/app/src/main/kotlin/org/ntlab/tag/api/tag/TagApiClient.kt
new file mode 100644
index 0000000..e7f1992
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/tag/TagApiClient.kt
@@ -0,0 +1,68 @@
+package org.ntlab.tag.api.tag
+
+import io.reactivex.Observer
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
+import org.ntlab.tag.api.BaseApi
+import org.ntlab.tag.api.regist.RoomApiClient
+import org.ntlab.tag.model.RxBus
+
+/**
+ * Created by matsumoto_k on 2017/07/08.
+ */
+object TagApiClient : BaseApi() {
+
+ fun getTag(tagId: Int) {
+ val getRoomService = RoomApiClient.getClient().create(TagService::class.java).getTag(tagId)
+ getRoomService.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable?) {
+ println("onSubscribeGetTag")
+ }
+
+ override fun onComplete() {
+ println("test")
+ }
+
+ override fun onNext(value: TagApiResponse?) {
+ if (value != null) {
+ RxBus.send(value)
+ }
+ }
+
+ override fun onError(e: Throwable?) {
+ println("onError")
+ println(e?.message)
+ }
+ })
+ }
+
+ fun updatePlayer(tagId: Int, userId: Int, player: ApiBodyPojo) {
+ val getRoomService = RoomApiClient.getClient().create(TagService::class.java).updatePlayer(tagId, userId, player)
+ getRoomService.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable?) {
+ println("onSubscribeGetTag")
+ }
+
+ override fun onComplete() {
+ println("test")
+ }
+
+ override fun onNext(value: Void?) {
+ if (value != null) {
+
+ }
+ }
+
+ override fun onError(e: Throwable?) {
+ println("onError")
+ println(e?.message)
+ }
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/tag/TagApiResponse.kt b/app/src/main/kotlin/org/ntlab/tag/api/tag/TagApiResponse.kt
new file mode 100644
index 0000000..e82dfbb
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/tag/TagApiResponse.kt
@@ -0,0 +1,18 @@
+package org.ntlab.tag.api.tag
+
+/**
+ * Created by matsumoto_k on 2017/07/08.
+ */
+class TagApiResponse(
+ var load: Boolean,
+ var tagId: Int,
+ var time: Double,
+ var playerList: ArrayList) {
+ inner class TagPlayer(
+ var demon: Boolean,
+ var latitude: Double,
+ var longitude: Double,
+ var userId: Int,
+ var userName: String
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/api/tag/TagService.kt b/app/src/main/kotlin/org/ntlab/tag/api/tag/TagService.kt
new file mode 100644
index 0000000..da226c6
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/api/tag/TagService.kt
@@ -0,0 +1,19 @@
+package org.ntlab.tag.api.tag
+
+import io.reactivex.Observable
+import retrofit2.http.*
+
+/**
+ * Created by matsumoto_k on 2017/07/08.
+ */
+interface TagService {
+
+ // Tag情報を取得
+ @GET("tags/{tagId}")
+ fun getTag(@Path(value = "tagId", encoded = true) tagId: Int): Observable
+
+ // プレイヤー情報を更新
+ @PUT("tags/{tagId}")
+ fun updatePlayer(@Path(value = "tagId", encoded = true) tagId: Int, @Query("userId") userId: Int, @Body player: ApiBodyPojo): Observable
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/contract/InRoomListViewContract.kt b/app/src/main/kotlin/org/ntlab/tag/contract/InRoomListViewContract.kt
new file mode 100644
index 0000000..86d5521
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/contract/InRoomListViewContract.kt
@@ -0,0 +1,12 @@
+package org.ntlab.tag.contract
+
+import org.ntlab.tag.api.regist.RoomApiResponse
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+interface InRoomListViewContract {
+ fun getRoomInfo(): RoomApiResponse
+ fun finishActivity()
+ fun startActivity(item: RoomApiResponse)
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/contract/RegistContract.kt b/app/src/main/kotlin/org/ntlab/tag/contract/RegistContract.kt
new file mode 100644
index 0000000..e9ede61
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/contract/RegistContract.kt
@@ -0,0 +1,8 @@
+package org.ntlab.tag.contract
+
+/**
+ * Created by matsumoto_k on 2017/07/08.
+ */
+interface RegistContract {
+ fun startActivity()
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/contract/RoomListViewContract.kt b/app/src/main/kotlin/org/ntlab/tag/contract/RoomListViewContract.kt
new file mode 100644
index 0000000..0d2433f
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/contract/RoomListViewContract.kt
@@ -0,0 +1,11 @@
+package org.ntlab.tag.contract
+
+import org.ntlab.tag.api.regist.RoomApiResponse
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+interface RoomListViewContract {
+ fun showRoom(items: ArrayList)
+ fun startRoomDetailActivity(item: RoomApiResponse)
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/model/GpsModel.kt b/app/src/main/kotlin/org/ntlab/tag/model/GpsModel.kt
new file mode 100644
index 0000000..c716a5a
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/model/GpsModel.kt
@@ -0,0 +1,81 @@
+package org.ntlab.tag.model
+
+import android.Manifest
+import android.content.Context
+import android.content.pm.PackageManager
+import android.database.Observable
+import android.location.Criteria
+import android.location.Location
+import android.location.LocationListener
+import android.location.LocationManager
+import android.os.Bundle
+import android.support.v4.app.ActivityCompat
+import org.ntlab.tag.activity.TagActivity
+
+/**
+ * Created by matsumoto_k on 2017/07/08
+ */
+object GpsModel : LocationListener {
+ private val minTime: Long = 3000
+ private val minDistance = 1f
+ private var locationManager: LocationManager? = null
+ var latitude: Double? = null
+ var longitude: Double? = null
+ var oblatitude: Observable? = null
+ var oblongitude: Observable? = null
+
+ fun settingGpsModel(context: Context) {
+ this.locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager?
+ }
+
+ fun startGps(context: Context) {
+ if (locationManager != null) {
+ try {
+ if (ActivityCompat.checkSelfPermission(context!!,
+ Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context!!,
+ Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ return
+ }
+
+
+ val criteria = Criteria()
+ criteria.isAltitudeRequired = false
+ criteria.isSpeedRequired = false
+ criteria.isCostAllowed = true
+ criteria.isBearingRequired = false
+ var bestProvider = locationManager?.getBestProvider(criteria, true)
+
+ if (locationManager?.isProviderEnabled(LocationManager.NETWORK_PROVIDER)!!) {
+ bestProvider = LocationManager.NETWORK_PROVIDER
+ }
+
+ criteria.horizontalAccuracy = Criteria.ACCURACY_HIGH
+ criteria.verticalAccuracy = Criteria.ACCURACY_HIGH
+ println(bestProvider)
+ locationManager?.requestLocationUpdates(bestProvider, minTime, minDistance, this)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+ }
+
+ fun stopGps() {
+ locationManager?.removeUpdates(GpsModel)
+ }
+
+ override fun onLocationChanged(location: Location?) {
+ latitude = location?.latitude
+ longitude = location?.longitude
+ RxBus.send(TagActivity.ChangeMyLocation)
+ }
+
+ override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {
+ }
+
+ override fun onProviderEnabled(provider: String?) {
+ }
+
+ override fun onProviderDisabled(provider: String?) {
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/model/MyPreferenceManager.kt b/app/src/main/kotlin/org/ntlab/tag/model/MyPreferenceManager.kt
new file mode 100644
index 0000000..c529687
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/model/MyPreferenceManager.kt
@@ -0,0 +1,38 @@
+package org.ntlab.tag.model
+
+import android.content.Context
+import android.content.SharedPreferences
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+/**
+ * SharedPreferencesを管理するクラス
+ */
+class MyPreferenceManager {
+ companion object {
+ private const val DATA_NAME = "data"
+ private var prefs: SharedPreferences? = null
+ private var editor: SharedPreferences.Editor? = null
+
+ fun init(context: Context) {
+ prefs = context.getSharedPreferences(DATA_NAME, Context.MODE_PRIVATE)
+ editor = prefs?.edit()
+ }
+
+ fun setPref(key: String, value: String) {
+ editor?.putString(key, value)
+ editor?.commit()
+ }
+
+ fun setPref(key: String, value: Int) {
+ editor?.putInt(key, value)
+ editor?.commit()
+ }
+
+ fun getPref(key: String, initialValue: String) = prefs?.getString(key, initialValue)
+ fun getPref(key: String, initialValue: Int) = prefs?.getInt(key, initialValue)
+ fun getPref(key: String, initialValue: Float) = prefs?.getFloat(key, initialValue)
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/model/RxBus.kt b/app/src/main/kotlin/org/ntlab/tag/model/RxBus.kt
new file mode 100644
index 0000000..f839399
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/model/RxBus.kt
@@ -0,0 +1,48 @@
+package org.ntlab.tag.model
+
+import io.reactivex.Observable
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.disposables.Disposable
+import io.reactivex.subjects.PublishSubject
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+object RxBus {
+
+ private val subscriptionsMap: HashMap by lazy {
+ HashMap()
+ }
+
+ val bus = (PublishSubject.create()).toSerialized()
+
+ fun send(event: Any) {
+ bus.onNext(event)
+ }
+
+ inline fun observe(): Observable {
+ return bus.ofType(eventType::class.java)
+ }
+
+ fun unregister(subscriber: Any) {
+ val compositeSubscription = subscriptionsMap[subscriber]
+ if (compositeSubscription == null) {
+ } else {
+ compositeSubscription.clear()
+ subscriptionsMap.remove(subscriber)
+ }
+ }
+
+ internal fun register(subscriber: Any, subscription: Disposable) {
+ var compositeDisposable = subscriptionsMap[subscriber]
+ if (compositeDisposable == null) {
+ compositeDisposable = CompositeDisposable()
+ }
+ compositeDisposable.add(subscription)
+ subscriptionsMap[subscriber] = compositeDisposable
+ }
+}
+
+fun Disposable.registerInBus(subscriber: Any) {
+ RxBus.register(subscriber, this)
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/utils/MapUtil.kt b/app/src/main/kotlin/org/ntlab/tag/utils/MapUtil.kt
new file mode 100644
index 0000000..6541f0e
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/utils/MapUtil.kt
@@ -0,0 +1,33 @@
+package org.ntlab.tag.utils
+
+import android.Manifest
+import android.content.Context
+import android.content.pm.PackageManager
+import android.location.LocationManager
+
+/**
+ * Created by matsumoto_k on 2017/07/08.
+ */
+class MapUtil {
+ companion object {
+ fun checkGpsPermission(context: Context): Boolean {
+ if (android.os.Build.VERSION.SDK_INT < 23) {
+ //Android6.0未満
+ return true
+ } else {
+ return context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
+ }
+ }
+
+ fun checkGps(context: Context): Boolean {
+ val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
+ if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
+ println("gps is enable")
+ return true
+ } else {
+ println("gps is unable")
+ return false
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/utils/sensor/GpsSensor.kt b/app/src/main/kotlin/org/ntlab/tag/utils/sensor/GpsSensor.kt
new file mode 100644
index 0000000..4950a5c
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/utils/sensor/GpsSensor.kt
@@ -0,0 +1,38 @@
+package org.ntlab.tag.utils.sensor
+
+import android.provider.Settings
+import org.ntlab.tag.utils.MapUtil
+
+/**
+ * Created by matsumoto_k on 2017/07/08
+ */
+class GpsSensor : SensorBase {
+
+ override fun checkPermission(activity: android.app.Activity): Boolean {
+ if (!MapUtil.Companion.checkGpsPermission(activity)) {
+ android.support.v4.app.ActivityCompat.requestPermissions(activity,
+ arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), 1);
+ return false
+ } else {
+ return true
+ }
+ }
+
+ override fun checkEnable(activity: android.app.Activity): Boolean {
+ return MapUtil.Companion.checkGps(activity)
+ }
+
+ override fun showDialog(activity: android.app.Activity) {
+ android.app.AlertDialog.Builder(activity).setMessage("GPSが有効になっていません。")
+ .setCancelable(false)
+ .setPositiveButton("GPS設定起動",
+ android.content.DialogInterface.OnClickListener { dialog, id ->
+ val callGPSSettingIntent = android.content.Intent(
+ Settings.ACTION_LOCATION_SOURCE_SETTINGS)
+ activity.startActivity(callGPSSettingIntent)
+ }).setNegativeButton("キャンセル",
+ android.content.DialogInterface.OnClickListener { dialog, id ->
+ dialog.cancel()
+ }).show()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/utils/sensor/SensorBase.kt b/app/src/main/kotlin/org/ntlab/tag/utils/sensor/SensorBase.kt
new file mode 100644
index 0000000..ae636c9
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/utils/sensor/SensorBase.kt
@@ -0,0 +1,23 @@
+package org.ntlab.tag.utils.sensor
+
+import android.app.Activity
+
+/**
+ * Created by matsumoto_k on 2017/07/08
+ */
+interface SensorBase {
+ fun checkSensor(activity: Activity): Boolean {
+ if (checkPermission(activity)) {
+ if (checkEnable(activity)) {
+ return true
+ } else {
+ showDialog(activity)
+ }
+ }
+ return false
+ }
+
+ fun checkPermission(activity: Activity): Boolean
+ fun checkEnable(activity: Activity): Boolean
+ fun showDialog(activity: Activity)
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/viewmodel/InRoomItemViewModel.kt b/app/src/main/kotlin/org/ntlab/tag/viewmodel/InRoomItemViewModel.kt
new file mode 100644
index 0000000..3c7db82
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/viewmodel/InRoomItemViewModel.kt
@@ -0,0 +1,34 @@
+package org.ntlab.tag.viewmodel
+
+import android.databinding.ObservableBoolean
+import android.databinding.ObservableField
+import android.databinding.ObservableInt
+import android.view.View
+import org.ntlab.tag.api.regist.RoomApiResponse
+import org.ntlab.tag.contract.InRoomListViewContract
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class InRoomItemViewModel(var view: InRoomListViewContract) {
+ val userName = ObservableField()
+ val readyVisible = ObservableInt(View.GONE)
+ val ready = ObservableBoolean()
+ val start = ObservableBoolean()
+ var position: Int? = null
+ var item: RoomApiResponse.RoomPlayerList? = null
+
+ fun loadItem(position: Int, item: RoomApiResponse.RoomPlayerList) {
+ this.userName.set(item.userName)
+ this.position = position
+ this.item = item
+ if (item.ready) {
+ readyVisible.set(View.VISIBLE)
+ } else {
+ readyVisible.set(View.GONE)
+ }
+
+ this.ready.set(item.ready)
+ println(this.ready.get())
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/viewmodel/InRoomViewModel.kt b/app/src/main/kotlin/org/ntlab/tag/viewmodel/InRoomViewModel.kt
new file mode 100644
index 0000000..6f30311
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/viewmodel/InRoomViewModel.kt
@@ -0,0 +1,115 @@
+package org.ntlab.tag.viewmodel
+
+import android.content.Context
+import android.databinding.BaseObservable
+import android.databinding.ObservableBoolean
+import android.databinding.ObservableField
+import android.databinding.ObservableInt
+import android.view.View
+import org.ntlab.tag.App
+import org.ntlab.tag.adapter.InRoomListAdapter
+import org.ntlab.tag.api.regist.RoomApiClient
+import org.ntlab.tag.api.regist.RoomApiResponse
+import org.ntlab.tag.contract.InRoomListViewContract
+import org.ntlab.tag.model.RxBus
+import org.ntlab.tag.model.registerInBus
+import java.util.*
+import kotlin.concurrent.schedule
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class InRoomViewModel(var context: Context, var view: InRoomListViewContract, var adapter: InRoomListAdapter) : BaseObservable() {
+
+ val readyText = ObservableField()
+ val readyEnable = ObservableBoolean(true)
+ val unReadyVisible = ObservableInt(View.INVISIBLE)
+ val outRoomVisible = ObservableInt(View.VISIBLE)
+
+ var timer: Timer? = null
+ var app: App? = null
+ var isHost = false
+
+ init {
+
+ app = App()
+
+ //自分がホストかどうか
+ isHost = this.view.getRoomInfo().hostUserId == app?.getUserId()
+ if (isHost) {
+ //ホストの時の処理
+ readyText.set("開始")
+ readyEnable.set(false)
+ } else {
+ //ホスト以外の時の処理
+ readyText.set("準備完了")
+ }
+
+ timer = Timer()
+ timer?.schedule(500, 1000) {
+ println("on")
+ val hoge = RoomApiClient
+ hoge.getInRoom(userId = app?.getUserId()!!, roomId = view.getRoomInfo().roomId)
+ }
+
+ RxBus.observe().subscribe {
+ println(it.allReady)
+ if (isHost) {
+ if (this.readyEnable.get() != it.allReady) {
+ this@InRoomViewModel.readyEnable.set(it.allReady)
+ }
+ }
+ if (it.start) {
+ this.view.finishActivity()
+ this.view.startActivity(it)
+ }
+ adapter.setItemAndRefresh(it.roomPlayerList)
+ }.registerInBus(this)
+
+ RxBus.observe().subscribe {
+
+ }.registerInBus(this)
+ }
+
+ fun setStartEnable(enable: Boolean) {
+ this.setStartEnable(enable)
+ }
+
+ fun onClickReadyButton(view: View) {
+ if (isHost) {
+ //ホストの時の処理
+ RoomApiClient.updateRoom(userId = app?.getUserId()!!, roomId = this.view.getRoomInfo().roomId, ready = true, start = true)
+ } else {
+ //ホスト以外の時の処理
+ if (readyEnable.get()) {
+ RoomApiClient.updateRoom(userId = app?.getUserId()!!, roomId = this.view.getRoomInfo().roomId, ready = true, start = false)
+ readyEnable.set(false)
+ unReadyVisible.set(View.VISIBLE)
+ outRoomVisible.set(View.INVISIBLE)
+
+ }
+ }
+ }
+
+ fun onClickUnReady(view: View) {
+ readyEnable.set(true)
+ unReadyVisible.set(View.INVISIBLE)
+ outRoomVisible.set(View.VISIBLE)
+ RoomApiClient.updateRoom(userId = app?.getUserId()!!, roomId = this.view.getRoomInfo().roomId, ready = false, start = false)
+ }
+
+ fun onClickOutRoom(view: View) {
+ RoomApiClient.outRoom("${this.view.getRoomInfo().roomId}/${app?.getUserId()!!}")
+ this.view.finishActivity()
+ }
+
+ fun finishActivity() {
+ RxBus.unregister(this)
+ timer?.cancel()
+ val app = App()
+ }
+
+
+ fun onDestroy() {
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/viewmodel/ListItemViewModel.kt b/app/src/main/kotlin/org/ntlab/tag/viewmodel/ListItemViewModel.kt
new file mode 100644
index 0000000..bf3bea7
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/viewmodel/ListItemViewModel.kt
@@ -0,0 +1,40 @@
+package org.ntlab.tag.viewmodel
+
+import android.databinding.ObservableField
+import android.view.View
+import org.ntlab.tag.App
+import org.ntlab.tag.api.regist.RoomApiClient
+import org.ntlab.tag.api.regist.RoomApiResponse
+import org.ntlab.tag.contract.RoomListViewContract
+import org.ntlab.tag.model.RxBus
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class ListItemViewModel(var view: RoomListViewContract) {
+ val roomId = ObservableField()
+ val hostName = ObservableField()
+ val roomName = ObservableField()
+ val maxNum = ObservableField()
+ val currentNum = ObservableField()
+
+ var item: RoomApiResponse? = null
+
+ fun loadItem(item: RoomApiResponse) {
+ this.roomId.set(item.roomId.toString())
+ this.hostName.set(item.hostUserName)
+ this.roomName.set(item.roomName)
+ this.maxNum.set(item.maxRoomNum.toString())
+ this.currentNum.set(item.roomPlayerList.size.toString())
+ this.item = item
+ }
+
+ // ルームのクリックリスナー
+ fun onClick(view: View) {
+ val app = App()
+ val roomService = RoomApiClient
+ println("onClick")
+ roomService.putRooms(app.getUserId()!!, this.roomId.get().toInt())
+ RxBus.send(RoomViewModel.RequireEnterRoom)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/viewmodel/RegistViewModel.kt b/app/src/main/kotlin/org/ntlab/tag/viewmodel/RegistViewModel.kt
new file mode 100644
index 0000000..fa55403
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/viewmodel/RegistViewModel.kt
@@ -0,0 +1,45 @@
+package org.ntlab.tag.viewmodel
+
+import android.databinding.BaseObservable
+import android.databinding.Bindable
+import android.databinding.ObservableField
+import android.view.View
+import org.ntlab.tag.App
+import org.ntlab.tag.api.regist.RegistApiClient
+import org.ntlab.tag.api.regist.RegistApiResponse
+import org.ntlab.tag.contract.RegistContract
+import org.ntlab.tag.model.RxBus
+import org.ntlab.tag.model.registerInBus
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class RegistViewModel(view: RegistContract) : BaseObservable() {
+
+ @Bindable
+ val userName = ObservableField();
+
+ init {
+ RxBus.observe().subscribe {
+ val app = App()
+ app.setUserId(it.userId)
+ app.setUsername(it.userName)
+ view.startActivity()
+ }.registerInBus(this)
+ }
+
+ fun onClickRegist(view: View) {
+ if (userName.get() != null) {
+ regist(userName.get())
+ }
+ }
+
+ fun regist(userName: String) {
+ val registClient = RegistApiClient
+ registClient.regist(userName)
+ }
+
+ fun onDestroy() {
+ RxBus.unregister(this)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/viewmodel/RoomViewModel.kt b/app/src/main/kotlin/org/ntlab/tag/viewmodel/RoomViewModel.kt
new file mode 100644
index 0000000..7415056
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/viewmodel/RoomViewModel.kt
@@ -0,0 +1,95 @@
+package org.ntlab.tag.viewmodel
+
+import android.app.AlertDialog
+import android.content.Context
+import android.databinding.BaseObservable
+import android.databinding.ObservableInt
+import android.view.View
+import android.widget.EditText
+import android.widget.Toast
+import org.ntlab.tag.App
+import org.ntlab.tag.adapter.RoomListAdapter
+import org.ntlab.tag.api.regist.RoomApiClient
+import org.ntlab.tag.api.regist.RoomApiResponse
+import org.ntlab.tag.contract.RoomListViewContract
+import org.ntlab.tag.model.RxBus
+import org.ntlab.tag.model.registerInBus
+
+
+/**
+ * Created by matsumoto_k on 2017/07/07.
+ */
+class RoomViewModel(var context: Context, var adapter: RoomListAdapter, var view: RoomListViewContract) : BaseObservable() {
+
+ val progressVisible = ObservableInt(View.GONE)
+
+ companion object {
+ const val RequireEnterRoom = "RequireEnterRoom"
+ }
+
+
+ // 更新ボタンのクリックリスナー
+ fun onClickFab(view: View) {
+ val roomApi = RoomApiClient
+ roomApi.getRooms()
+ }
+
+ // 部屋作成ボタンのクリックリスナー
+ fun onClickCreateRoom(view: View) {
+ //テキスト入力を受け付けるビューを作成します。
+ val editView = EditText(context)
+ AlertDialog.Builder(context)
+ .setTitle("ルーム作成")
+ .setMessage("ルーム名を入力して下さい")
+ //setViewにてビューを設定します。
+ .setView(editView)
+ .setPositiveButton("OK") { dialog, whichButton ->
+ val app = App()
+ val roomApi = RoomApiClient
+ roomApi.postRooms(app.getUserId()!!, editView.text.toString())
+ }
+ .setNegativeButton("キャンセル") { dialog, whichButton -> }
+ .show()
+ }
+
+ fun onDestroy() {
+ RxBus.unregister(this)
+ }
+
+ fun onStart() {
+ val roomApi = RoomApiClient
+ roomApi.getRooms()
+
+ RxBus.observe>().subscribe {
+ adapter.setItemAndRefresh(it)
+ }.registerInBus(this)
+
+ RxBus.observe().subscribe {
+ when (it) {
+ RequireEnterRoom -> {
+ progressVisible.set(View.VISIBLE)
+ }
+ }
+ }.registerInBus(this)
+
+ RxBus.observe().subscribe {
+ progressVisible.set(View.GONE)
+
+ //入室成功
+ if (it.success) {
+ view?.startRoomDetailActivity(it)
+ }
+ //入室失敗
+ else {
+ val roomApi = RoomApiClient
+ roomApi.getRooms()
+ Toast.makeText(context, "ルームが満員です", Toast.LENGTH_SHORT).show()
+ }
+ }.registerInBus(this)
+ }
+
+ fun onStop() {
+ RxBus.unregister(this)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/ntlab/tag/viewmodel/TagViewModel.kt b/app/src/main/kotlin/org/ntlab/tag/viewmodel/TagViewModel.kt
new file mode 100644
index 0000000..a64f394
--- /dev/null
+++ b/app/src/main/kotlin/org/ntlab/tag/viewmodel/TagViewModel.kt
@@ -0,0 +1,228 @@
+package org.ntlab.tag.viewmodel
+
+import android.app.Activity
+import android.databinding.BaseObservable
+import android.databinding.ObservableField
+import android.databinding.ObservableInt
+import android.view.View
+import android.widget.Toast
+import com.google.android.gms.maps.CameraUpdateFactory
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.model.*
+import org.ntlab.tag.App
+import org.ntlab.tag.R
+import org.ntlab.tag.activity.TagActivity
+import org.ntlab.tag.api.regist.RoomApiResponse
+import org.ntlab.tag.api.tag.ApiBodyPojo
+import org.ntlab.tag.api.tag.TagApiClient
+import org.ntlab.tag.api.tag.TagApiResponse
+import org.ntlab.tag.model.GpsModel
+import org.ntlab.tag.model.RxBus
+import org.ntlab.tag.model.registerInBus
+import java.util.*
+import kotlin.concurrent.schedule
+
+/**
+ * Created by matsumoto_k on 2017/07/09.
+ */
+class TagViewModel(var context: Activity, var roomData: RoomApiResponse) : BaseObservable() {
+
+ var mMap: GoogleMap? = null
+ private var timer: Timer? = null
+ private var tagId: Int = -1
+ private var userId: Int = -1
+ private var maxRoomNum: Int = -1
+ private var allPlayerLoad = false;
+ private var demonUserId = -1;
+ private var demonChangeFlug = false;
+ private var app: App? = null
+
+ // 自分の位置のマーカー
+ private var myLocationMarker: Marker? = null
+ // 味方の位置のマーカー
+ private var otherPlayerMarker: HashMap = HashMap()
+
+ val myLocationButtonEnable = ObservableInt(View.GONE)
+ val loadingLayoutEnable = ObservableInt(View.VISIBLE)
+ val loadingMessage = ObservableField("位置情報を取得中です")
+ val time = ObservableField()
+
+ fun setMap(googleMap: GoogleMap) {
+ this.mMap = googleMap
+ }
+
+ init {
+
+ app = App()
+
+
+ tagId = roomData.tagId
+ maxRoomNum = roomData.maxRoomNum
+ userId = App().getUserId()!!
+ }
+
+ fun onPostResume() {
+ timer = Timer()
+ timer?.schedule(500, 1000) {
+ if (GpsModel.latitude != null) {
+
+ // 自分の位置のマーカーを作成
+ if (myLocationMarker == null) {
+ context.runOnUiThread(object : Runnable {
+ override fun run() {
+ myLocationMarker = mMap?.addMarker(MarkerOptions().position(LatLng(GpsModel.latitude!!, GpsModel.longitude!!)).icon(BitmapDescriptorFactory.fromResource(R.drawable.my_location_icon)).title(app?.getUserName()))
+ }
+ })
+
+ // 初回位置情報を送信
+ TagApiClient.updatePlayer(tagId, userId, ApiBodyPojo(userId, GpsModel.latitude!!, GpsModel.longitude!!, false))
+ context.runOnUiThread(object : Runnable {
+ override fun run() {
+ onClickMyLocation(null)
+ }
+ })
+
+ if (!allPlayerLoad) {
+ loadingMessage.set("他プレイヤーの位置情報を取得中です。\nしばらくお待ちください。")
+ }
+
+ }
+
+ // 全てのプレイヤーの情報を取得する
+ TagApiClient.getTag(tagId)
+
+ }
+ }
+ }
+
+ fun onPause() {
+ timer?.cancel()
+ }
+
+ fun setRxBus() {
+ RxBus.observe().subscribe {
+ // 全てのプレイヤーの位置情報ロードが終了したら
+ if (it.load) {
+ // 自分以外のプレイヤーのマーカーを追加(初回のみ)
+ if (this.otherPlayerMarker.size == 0) {
+ for (player in it.playerList) {
+ if (player.demon) {
+ Toast.makeText(context, "最初の鬼は${player.userName}さんです。", Toast.LENGTH_LONG).show()
+ demonUserId = player.userId
+ }
+ if (player.userId == userId) {
+ if (player.demon) {
+ myLocationMarker?.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.demon_icon))
+ }
+ continue
+ }
+ context.runOnUiThread(object : Runnable {
+ override fun run() {
+ println("${player.userId}のマーカー追加")
+ if (player.demon) {
+ otherPlayerMarker.put(player.userId, mMap?.addMarker(MarkerOptions().position(LatLng(player.latitude, player.longitude)).icon(BitmapDescriptorFactory.fromResource(R.drawable.demon_icon)).title(player.userName))!!)
+ } else {
+ otherPlayerMarker.put(player.userId, mMap?.addMarker(MarkerOptions().position(LatLng(player.latitude, player.longitude)).icon(BitmapDescriptorFactory.fromResource(R.drawable.friend_icon)).title(player.userName))!!)
+ }
+ }
+ })
+ }
+ loadingLayoutEnable.set(View.GONE)
+ myLocationButtonEnable.set(View.VISIBLE)
+ return@subscribe
+ }
+
+ // 鬼が変わったかどうか判定
+ for (player in it.playerList) {
+ if (player.demon) {
+ if (player.userId != demonUserId) {
+ demonChangeFlug = true
+ demonUserId = player.userId
+ Toast.makeText(context, "鬼が入れ替わりました。\n" +
+ "新しい鬼は${player.userName}さんです。", Toast.LENGTH_LONG).show()
+ break
+ }
+ }
+ }
+
+ // 1秒に一回全てのプレイヤーの情報を更新
+ for (player in it.playerList) {
+ val latlng = LatLng(player.latitude, player.longitude)
+ context.runOnUiThread {
+ // 自分の情報更新
+ if (player.userId == userId) {
+ myLocationMarker?.position = latlng
+ if (demonChangeFlug) {
+ if (player.demon) {
+ myLocationMarker?.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.demon_icon))
+ } else {
+ myLocationMarker?.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.my_location_icon))
+ }
+ }
+ }
+ // 他のプレイヤーの情報更新
+ else {
+ if (demonChangeFlug) {
+ if (player.demon) {
+ otherPlayerMarker.get(player.userId)?.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.demon_icon))
+ } else {
+ otherPlayerMarker.get(player.userId)?.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.friend_icon))
+ }
+ }
+ otherPlayerMarker.get(player.userId)?.position = latlng
+ }
+ }
+ }
+
+ time.set("${(it.time.toInt() / 60)}:${String.format("%02d", it.time.toInt() % 60)}")
+
+ if (demonChangeFlug) {
+ demonChangeFlug = false;
+ }
+
+ }
+ }.registerInBus(this)
+
+ RxBus.observe().subscribe {
+ when (it) {
+ TagActivity.RequireMyLocation -> {
+ if (GpsModel.latitude != null && GpsModel.longitude != null) {
+ val myLatLng = LatLng(GpsModel.latitude!!, GpsModel.longitude!!)
+ val cameraPosition = CameraPosition.Builder()
+ .target(myLatLng)
+ .zoom(16f)
+ .build()
+ mMap?.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 1000, null)
+ } else {
+ println("null")
+ }
+ }
+ TagActivity.ChangeMyLocation -> {
+ // myLocationのマーカーの位置情報を更新
+ context.runOnUiThread(object : Runnable {
+ override fun run() {
+ myLocationMarker?.position = LatLng(GpsModel.latitude!!, GpsModel.longitude!!)
+ }
+ })
+
+ // myLocationの変更APi処理
+ TagApiClient.updatePlayer(tagId, userId, ApiBodyPojo(userId, GpsModel.latitude!!, GpsModel.longitude!!, false))
+ }
+ }
+ }.registerInBus(this)
+ }
+
+ fun onClickMyLocation(view: View?) {
+ if (GpsModel.latitude != null && GpsModel.longitude != null) {
+ val myLatLng = LatLng(GpsModel.latitude!!, GpsModel.longitude!!)
+ val cameraPosition = CameraPosition.Builder()
+ .target(myLatLng)
+ .zoom(16f)
+ .build()
+ mMap?.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 1000, null)
+ } else {
+ println("null")
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/create_room.png b/app/src/main/res/drawable/create_room.png
new file mode 100644
index 0000000..dcd2b0e
--- /dev/null
+++ b/app/src/main/res/drawable/create_room.png
Binary files differ
diff --git a/app/src/main/res/drawable/demon_icon.png b/app/src/main/res/drawable/demon_icon.png
new file mode 100644
index 0000000..8572de9
--- /dev/null
+++ b/app/src/main/res/drawable/demon_icon.png
Binary files differ
diff --git a/app/src/main/res/drawable/friend_icon.png b/app/src/main/res/drawable/friend_icon.png
new file mode 100644
index 0000000..2e17234
--- /dev/null
+++ b/app/src/main/res/drawable/friend_icon.png
Binary files differ
diff --git a/app/src/main/res/drawable/my_location.png b/app/src/main/res/drawable/my_location.png
new file mode 100644
index 0000000..5662d5c
--- /dev/null
+++ b/app/src/main/res/drawable/my_location.png
Binary files differ
diff --git a/app/src/main/res/drawable/my_location_icon.png b/app/src/main/res/drawable/my_location_icon.png
new file mode 100644
index 0000000..fc8ae72
--- /dev/null
+++ b/app/src/main/res/drawable/my_location_icon.png
Binary files differ
diff --git a/app/src/main/res/drawable/mylocation.png b/app/src/main/res/drawable/mylocation.png
new file mode 100644
index 0000000..2fbc4e1
--- /dev/null
+++ b/app/src/main/res/drawable/mylocation.png
Binary files differ
diff --git a/app/src/main/res/drawable/room_out.png b/app/src/main/res/drawable/room_out.png
new file mode 100644
index 0000000..19fed87
--- /dev/null
+++ b/app/src/main/res/drawable/room_out.png
Binary files differ
diff --git a/app/src/main/res/drawable/update.png b/app/src/main/res/drawable/update.png
new file mode 100644
index 0000000..b246222
--- /dev/null
+++ b/app/src/main/res/drawable/update.png
Binary files differ
diff --git a/app/src/main/res/layout/activity_in_room.xml b/app/src/main/res/layout/activity_in_room.xml
new file mode 100644
index 0000000..39f987b
--- /dev/null
+++ b/app/src/main/res/layout/activity_in_room.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..f4cdeaa
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_regist.xml b/app/src/main/res/layout/activity_regist.xml
new file mode 100644
index 0000000..9047fc2
--- /dev/null
+++ b/app/src/main/res/layout/activity_regist.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_room_list.xml b/app/src/main/res/layout/activity_room_list.xml
new file mode 100644
index 0000000..4ae123f
--- /dev/null
+++ b/app/src/main/res/layout/activity_room_list.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_tag.xml b/app/src/main/res/layout/activity_tag.xml
new file mode 100644
index 0000000..828ac38
--- /dev/null
+++ b/app/src/main/res/layout/activity_tag.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_tag_overlay.xml b/app/src/main/res/layout/fragment_tag_overlay.xml
new file mode 100644
index 0000000..be738ac
--- /dev/null
+++ b/app/src/main/res/layout/fragment_tag_overlay.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/in_room_list_item.xml b/app/src/main/res/layout/in_room_list_item.xml
new file mode 100644
index 0000000..a99a148
--- /dev/null
+++ b/app/src/main/res/layout/in_room_list_item.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/room_list_item.xml b/app/src/main/res/layout/room_list_item.xml
new file mode 100644
index 0000000..23558f7
--- /dev/null
+++ b/app/src/main/res/layout/room_list_item.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..5507303
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8fab6a3
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..6bc7fcd
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..1eecc0e
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..ec87dce
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..05ca079
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6f67f21
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8bac0f2
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..0327e13
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..bacd3e7
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/raw/style_json.json b/app/src/main/res/raw/style_json.json
new file mode 100644
index 0000000..fc491a7
--- /dev/null
+++ b/app/src/main/res/raw/style_json.json
@@ -0,0 +1,200 @@
+[
+ {
+ "featureType": "all",
+ "elementType": "labels",
+ "stylers": [
+ {
+ "visibility": "off"
+ }
+ ]
+ },
+ {
+ "featureType": "administrative",
+ "elementType": "all",
+ "stylers": [
+ {
+ "visibility": "simplified"
+ },
+ {
+ "color": "#5b6571"
+ },
+ {
+ "lightness": "35"
+ }
+ ]
+ },
+ {
+ "featureType": "administrative.neighborhood",
+ "elementType": "all",
+ "stylers": [
+ {
+ "visibility": "off"
+ }
+ ]
+ },
+ {
+ "featureType": "landscape",
+ "elementType": "all",
+ "stylers": [
+ {
+ "visibility": "on"
+ },
+ {
+ "color": "#f3f4f4"
+ }
+ ]
+ },
+ {
+ "featureType": "landscape.man_made",
+ "elementType": "geometry",
+ "stylers": [
+ {
+ "weight": 0.9
+ },
+ {
+ "visibility": "off"
+ }
+ ]
+ },
+ {
+ "featureType": "poi.park",
+ "elementType": "geometry.fill",
+ "stylers": [
+ {
+ "visibility": "on"
+ },
+ {
+ "color": "#83cead"
+ }
+ ]
+ },
+ {
+ "featureType": "road",
+ "elementType": "all",
+ "stylers": [
+ {
+ "visibility": "on"
+ },
+ {
+ "color": "#ffffff"
+ }
+ ]
+ },
+ {
+ "featureType": "road",
+ "elementType": "labels",
+ "stylers": [
+ {
+ "visibility": "off"
+ }
+ ]
+ },
+ {
+ "featureType": "road.highway",
+ "elementType": "all",
+ "stylers": [
+ {
+ "visibility": "on"
+ },
+ {
+ "color": "#fee379"
+ }
+ ]
+ },
+ {
+ "featureType": "road.highway",
+ "elementType": "geometry",
+ "stylers": [
+ {
+ "visibility": "on"
+ }
+ ]
+ },
+ {
+ "featureType": "road.highway",
+ "elementType": "labels",
+ "stylers": [
+ {
+ "visibility": "off"
+ }
+ ]
+ },
+ {
+ "featureType": "road.highway",
+ "elementType": "labels.icon",
+ "stylers": [
+ {
+ "visibility": "off"
+ }
+ ]
+ },
+ {
+ "featureType": "road.highway.controlled_access",
+ "elementType": "labels.icon",
+ "stylers": [
+ {
+ "visibility": "off"
+ }
+ ]
+ },
+ {
+ "featureType": "road.arterial",
+ "elementType": "all",
+ "stylers": [
+ {
+ "visibility": "simplified"
+ },
+ {
+ "color": "#ffffff"
+ }
+ ]
+ },
+ {
+ "featureType": "road.arterial",
+ "elementType": "labels",
+ "stylers": [
+ {
+ "visibility": "off"
+ }
+ ]
+ },
+ {
+ "featureType": "road.arterial",
+ "elementType": "labels.icon",
+ "stylers": [
+ {
+ "visibility": "off"
+ }
+ ]
+ },
+ {
+ "featureType": "water",
+ "elementType": "all",
+ "stylers": [
+ {
+ "visibility": "on"
+ },
+ {
+ "color": "#7fc8ed"
+ }
+ ]
+ },
+ {
+ "featureType": "transit.station",
+ "elementType": "labels.text",
+ "stylers": [
+ {
+ "visibility": "on"
+ }
+ ]
+ },
+ {
+ "featureType": "transit.station",
+ "elementType": "labels.icon",
+ "stylers": [
+ {
+ "visibility": "on"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..42cca66
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,7 @@
+
+ Tag
+ Map
+
+
+ Hello blank fragment
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/app/src/release/res/values/google_maps_api.xml b/app/src/release/res/values/google_maps_api.xml
new file mode 100644
index 0000000..1ef79e9
--- /dev/null
+++ b/app/src/release/res/values/google_maps_api.xml
@@ -0,0 +1,20 @@
+
+
+ YOUR_KEY_HERE
+
diff --git a/app/src/test/java/org/ntlab/tag/ExampleUnitTest.kt b/app/src/test/java/org/ntlab/tag/ExampleUnitTest.kt
new file mode 100644
index 0000000..768c59b
--- /dev/null
+++ b/app/src/test/java/org/ntlab/tag/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package org.ntlab.tag
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..87cf60a
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,29 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ ext.kotlin_version = '1.1.2-4'
+ repositories {
+ maven { url 'https://maven.google.com' }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.0.0-alpha3'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ // Kotlin Android Extensions
+ classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ maven { url 'https://maven.google.com' }
+ jcenter()
+ mavenCentral()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..9ddafb4
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+compileOptions.incremental = false
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..6bbad95
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jul 07 15:54:19 JST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-milestone-1-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..9d82f78
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'