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 @@ + + + + + + + + + + + + + +