diff --git a/app/build.gradle b/app/build.gradle index 8a5b3fa..f34f8ff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,7 +4,7 @@ compileSdkVersion 28 defaultConfig { applicationId "com.example.cosmosclient" - minSdkVersion 15 + minSdkVersion 26 targetSdkVersion 28 versionCode 1 versionName "1.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c02723a..85fa6bb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -74,10 +74,16 @@ android:label="グループ一覧" android:theme="@style/AppTheme.NoActionBar"> - - + + + + + + + @@ -90,8 +96,7 @@ - - + \ No newline at end of file diff --git a/app/src/main/java/com/example/cosmosclient/GPSresources/StoreLocationsMethods.java b/app/src/main/java/com/example/cosmosclient/GPSresources/StoreLocationsMethods.java deleted file mode 100644 index 51c215e..0000000 --- a/app/src/main/java/com/example/cosmosclient/GPSresources/StoreLocationsMethods.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.example.cosmosclient.GPSresources; - -import android.location.Location; - -import com.example.cosmosclient.entities.Feature; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -public class StoreLocationsMethods { - private double NowLat; - private double NowLon; - private HashMap> feature = new HashMap<>(); - /*戻り値となる通知が必要なお店情報を格納する連想配列を作成*/ - private ArrayList nearShops=new ArrayList<>(); - - public StoreLocationsMethods(double NowLat, double NowLon){ - this.NowLat=NowLat; - this.NowLon=NowLon; - } - public void updateLocations(double NowLat,double NowLon){ - this.NowLat=NowLat; - this.NowLon=NowLon; - } - public double getNowLat(){ - return this.NowLat; - } - public double getNowLon(){ - return this.NowLon; - } - - public void setNearShops(HashMap> feature){ - this.feature=feature; - //HashMapを順番に実行 - for(HashMap.Entry> e : feature.entrySet()) { - //ArrayList>を回していく - for(int i=0; i < e.getValue().size();i++) { - float[] distance = getDistance(this.NowLat, this.NowLon, e.getValue().get(i).getLocation().getLatitude(), e.getValue().get(i).getLocation().getLongitude()); - // distance[0] = [2点間の距離] - //m単位 - if (distance[0] <= 50) { - /*ここから通知に必要な近い店の情報を格納する処理を記述*/ - /*中身を作成*/ - Feature childFeature = new Feature(); - childFeature.setCode(e.getValue().get(i).getCode()); - childFeature.setLocation(e.getValue().get(i).getLocation()); - childFeature.setName(e.getValue().get(i).getName()); - if(nearShops.indexOf(childFeature)==-1){ - /*通知に必要な近い店の情報を格納する処理を格納*/ - nearShops.add(childFeature); - } - } - } - } - } - public ArrayList getNearShops() { - return nearShops; - } - - /*通知送信後、通知すべきショップ情報リストから削除する*/ - /*引数はArrayList型*/ - /*引数のArrayListと一致するものをnearShopsから削除する*/ - public void deleteNearShops(ArrayList deleteList) { - for(int i=0; i < deleteList.size();i++){ - if(nearShops.indexOf(deleteList)!=-1){ - /*ここで削除*/ - nearShops.remove(nearShops.indexOf(deleteList)); - } - - } - - } - - - public float[] getDistance(double x, double y, double x2, double y2) { - // 結果を格納するための配列を生成 - float[] results = new float[3]; - // results[0] = [2点間の距離] - // results[1] = [始点から見た方位角] - // results[2] = [終点から見た方位角] - - // 距離計算 - Location.distanceBetween(x, y, x2, y2, results); - - return results; - } -} diff --git a/app/src/main/java/com/example/cosmosclient/app/Cosmos.java b/app/src/main/java/com/example/cosmosclient/app/Cosmos.java index ede712b..d050520 100644 --- a/app/src/main/java/com/example/cosmosclient/app/Cosmos.java +++ b/app/src/main/java/com/example/cosmosclient/app/Cosmos.java @@ -1,13 +1,16 @@ package com.example.cosmosclient.app; import android.app.Application; +import android.content.ComponentCallbacks; +import android.content.res.Configuration; +import android.util.Log; import com.example.cosmosclient.entities.AreaInformation; import com.example.cosmosclient.entities.Group; -import com.example.cosmosclient.entities.Location; +import android.content.SharedPreferences; -import java.util.HashMap; - +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; public class Cosmos extends Application { @@ -16,13 +19,91 @@ private HashMap groups = new HashMap<>(); private String uId=null; private HashMap areaInfo = new HashMap<>(); + private ArrayList areaInfoKey= new ArrayList<>(); + private String TAG = Cosmos.class.getSimpleName(); + + public Cosmos() { + super(); + Log.d(TAG, " Constructor"); + } + + @Override + public void onCreate() { + Log.d(TAG, " onCreate"); + super.onCreate(); + } + + @Override + public void onTerminate() { + Log.d(TAG, " onTerminate"); + super.onTerminate(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + Log.d(TAG, " onConfigurationChanged"); + super.onConfigurationChanged(newConfig); + } + + @Override + public void onLowMemory() { + Log.d(TAG, " onLowMemory"); + super.onLowMemory(); + } + + @Override + public void onTrimMemory(int level) { + Log.d(TAG, " onTrimMemory"); + super.onTrimMemory(level); + } + + @Override + public void registerComponentCallbacks(ComponentCallbacks callback) { + Log.d(TAG, " registerComponentCallbacks"); + super.registerComponentCallbacks(callback); + } + + @Override + public void unregisterComponentCallbacks(ComponentCallbacks callback) { + Log.d(TAG, " unregisterComponentCallbacks"); + super.unregisterComponentCallbacks(callback); + } + + @Override + public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { + Log.d(TAG, " registerActivityLifecycleCallbacks"); + super.registerActivityLifecycleCallbacks(callback); + } + + @Override + public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { + Log.d(TAG, " unregisterActivityLifecycleCallbacks"); + super.unregisterActivityLifecycleCallbacks(callback); + } + + @Override + public void registerOnProvideAssistDataListener(OnProvideAssistDataListener callback) { + Log.d(TAG, " registerOnProvideAssistDataListener"); + super.registerOnProvideAssistDataListener(callback); + } + + @Override + public void unregisterOnProvideAssistDataListener(OnProvideAssistDataListener callback) { + Log.d(TAG, " unregisterOnProvideAssistDataListener"); + super.unregisterOnProvideAssistDataListener(callback); + } //token処理 public void setToken(String token){ - this.token = token; + SharedPreferences prefData = getSharedPreferences("pref_data", MODE_PRIVATE); + SharedPreferences.Editor editor = prefData.edit(); + editor.putString("token", token); + editor.commit(); } public String getToken(){ + SharedPreferences prefData = getSharedPreferences("pref_data", MODE_PRIVATE); + String token = prefData.getString("token", ""); return token; } @@ -48,12 +129,21 @@ return groups.get(gId); } + public Collection getGroups() { + return groups.values(); + } + //uId処理 public void setuId(String uId){ - this.uId = uId; + SharedPreferences prefData = getSharedPreferences("pref_data", MODE_PRIVATE); + SharedPreferences.Editor editor = prefData.edit(); + editor.putString("uId", uId); + editor.commit(); } public String getuId(){ + SharedPreferences prefData = getSharedPreferences("pref_data", MODE_PRIVATE); + String uId = prefData.getString("uId", ""); return uId; } @@ -65,4 +155,11 @@ return areaInfo.get(areaId); } + public ArrayList AreaInfoGetKey(){ + for(int key : areaInfo.keySet()){ + areaInfoKey.add(key); + } + return areaInfoKey; + } + } diff --git a/app/src/main/java/com/example/cosmosclient/entities/AreaInformation.java b/app/src/main/java/com/example/cosmosclient/entities/AreaInformation.java index 4a581ac..3dc2816 100644 --- a/app/src/main/java/com/example/cosmosclient/entities/AreaInformation.java +++ b/app/src/main/java/com/example/cosmosclient/entities/AreaInformation.java @@ -5,14 +5,14 @@ import java.util.HashMap; public class AreaInformation { - private Location location = new Location(); + private CosmosLocation location = new CosmosLocation(); private HashMap> feature = new HashMap<>(); private Time lastUpdated; - public void setLocation(Location location){ + public void setLocation(CosmosLocation location){ this.location = location; } - public Location getLocation(){ + public CosmosLocation getLocation(){ return this.location; } diff --git a/app/src/main/java/com/example/cosmosclient/entities/CosmosLocation.java b/app/src/main/java/com/example/cosmosclient/entities/CosmosLocation.java new file mode 100644 index 0000000..a13d9db --- /dev/null +++ b/app/src/main/java/com/example/cosmosclient/entities/CosmosLocation.java @@ -0,0 +1,24 @@ +package com.example.cosmosclient.entities; + +public class CosmosLocation { + private double latitude; + private double longitude; + + public void setLatitude(double latitude) { + this.latitude = latitude; + } + public double getLatitude() { + return latitude; + } + + public void setLongitude(double longitude) { + this.longitude = longitude; + } + public double getLongitude() { + return longitude; + } + + public int hashCode(){ + return (int)((latitude+90)/0.1)+(int)((longitude/0.1)*1800); + } +} diff --git a/app/src/main/java/com/example/cosmosclient/entities/Feature.java b/app/src/main/java/com/example/cosmosclient/entities/Feature.java index 63c3374..e498d67 100644 --- a/app/src/main/java/com/example/cosmosclient/entities/Feature.java +++ b/app/src/main/java/com/example/cosmosclient/entities/Feature.java @@ -1,15 +1,22 @@ package com.example.cosmosclient.entities; public class Feature { - private String name; + private String genre; private int code; - private Location location = new Location(); + private CosmosLocation location = new CosmosLocation(); - public void setName(String name){ - this.name = name; + public void setLatitude(double latitude) { + location.setLatitude(latitude); } - public String getName(){ - return this.name; + public void setLongitude(double longitude) { + location.setLongitude(longitude); + } + + public String getGenre() { + return genre; + } + public void setGenre(String genre) { + this.genre = genre; } public void setCode(int code){ @@ -19,10 +26,10 @@ return this.code; } - public void setLocation(Location location){ + public void setLocation(CosmosLocation location){ this.location = location; } - public Location getLocation(){ + public CosmosLocation getLocation(){ return this.location; } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/example/cosmosclient/entities/Location.java b/app/src/main/java/com/example/cosmosclient/entities/Location.java deleted file mode 100644 index 113b555..0000000 --- a/app/src/main/java/com/example/cosmosclient/entities/Location.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.example.cosmosclient.entities; - -public class Location { - private double latitude; - private double longitude; - - public void setLatitude(double latitude) { - this.latitude = latitude; - } - public double getLatitude() { - return latitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - public double getLongitude() { - return longitude; - } - - public int hashCode(){ - return (int)((latitude+90)/0.1)+(int)((longitude/0.1)*1800); - } -} diff --git a/app/src/main/java/com/example/cosmosclient/resources/LocationRest.java b/app/src/main/java/com/example/cosmosclient/resources/LocationRest.java new file mode 100644 index 0000000..0e74d20 --- /dev/null +++ b/app/src/main/java/com/example/cosmosclient/resources/LocationRest.java @@ -0,0 +1,20 @@ +package com.example.cosmosclient.resources; + +import com.example.cosmosclient.entities.AreaInformation; +import com.example.cosmosclient.entities.Feature; + +import java.util.ArrayList; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + + +public interface LocationRest { + + @GET("shops") + Call> LocationService(@Query("leftLatitude") String leftLat, + @Query("leftLongitude") String leftLon, + @Query("rightLatitude") String rightLat, + @Query("rightLongitude") String rightLon); +} \ No newline at end of file diff --git a/app/src/main/java/com/example/cosmosclient/resources/ShopRest.java b/app/src/main/java/com/example/cosmosclient/resources/ShopRest.java deleted file mode 100644 index 0d9a51c..0000000 --- a/app/src/main/java/com/example/cosmosclient/resources/ShopRest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.cosmosclient.resources; - -import com.example.cosmosclient.entities.Feature; - -import retrofit2.Call; -import retrofit2.http.GET; -import retrofit2.http.Query; - -public interface ShopRest { - - @GET("rest") - Call ShopRequest(@Query("longitude") double longitude, - @Query("latitude") double latitude, - @Query("longitudeRange") double longitudeRange, - @Query("latitudeRange") double latitudeRange, - @Query("shop") int shop); -} diff --git a/app/src/main/java/com/example/cosmosclient/services/CosmosBackgroundService.java b/app/src/main/java/com/example/cosmosclient/services/CosmosBackgroundService.java new file mode 100644 index 0000000..683e060 --- /dev/null +++ b/app/src/main/java/com/example/cosmosclient/services/CosmosBackgroundService.java @@ -0,0 +1,542 @@ +package com.example.cosmosclient.services; + +import android.Manifest; +import android.app.IntentService; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Intent; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.graphics.Color; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Build; +import android.os.Bundle; +import android.os.IBinder; +import android.provider.Settings; +import android.support.annotation.Nullable; +import android.support.annotation.RequiresApi; +import android.support.v4.app.ActivityCompat; +import android.util.Log; +import android.widget.Toast; + +import com.example.cosmosclient.R; +import com.example.cosmosclient.app.Cosmos; +import com.example.cosmosclient.entities.CosmosLocation; +import com.example.cosmosclient.entities.Feature; +import com.example.cosmosclient.entities.Group; +import com.example.cosmosclient.entities.GroupListResponse; +import com.example.cosmosclient.entities.RequestList; +import com.example.cosmosclient.entities.jsons.GroupJson; +import com.example.cosmosclient.resources.GroupsRest; +import com.example.cosmosclient.resources.LocationRest; + +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.TimeZone; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.jackson.JacksonConverterFactory; + +import static android.app.Notification.EXTRA_NOTIFICATION_ID; + + +public class CosmosBackgroundService extends IntentService implements LocationListener { + private Context context; + private LocationManager locationManager; + private static final int MinTime = 1000;/*最小時間間隔*/ + private static final float MinDistance = 1;/*最小距離間隔*/ + private boolean isServiceRunning = false; //サービスが起動しているかを確認 + private String TAG = CosmosBackgroundService.class.getSimpleName(); + private List notifications =null; + private CosmosLocation LOC = new CosmosLocation(); + private double leftLat,leftLon,rightLat,rightLon; //ここに計算予定 + private int count = 0; + private NotificationManager notificationManager; + + + + public CosmosBackgroundService() { + super("CosmosBackgroundService"); + Log.d(TAG, "Constructor"); + } + + @Override + public void setIntentRedelivery(boolean enabled) { + Log.d(TAG, "setIntentRedelivery"); + super.setIntentRedelivery(enabled); + } + + @Override + public void onCreate() { + Log.d(TAG, "onCreate"); + super.onCreate(); + context = getApplicationContext(); + // LocationManager インスタンス生成 + locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); + notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); + int importance = NotificationManager.IMPORTANCE_HIGH; + NotificationChannel mChannel = new NotificationChannel("cosmos", "cosmosChannel", importance); + notificationManager.createNotificationChannel(mChannel); + } + + @Override + public void onStart(@Nullable Intent intent, int startId) { + Log.d(TAG, "onStart"); + super.onStart(intent, startId); + } + + @RequiresApi(api = Build.VERSION_CODES.O) + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.d(TAG, "onStartCommand"); + if(!isServiceRunning) { + int requestCode = 0; + String channelId = "default"; + String title = context.getString(R.string.app_name); + PendingIntent pendingIntent = + PendingIntent.getActivity(context, requestCode, + intent, PendingIntent.FLAG_UPDATE_CURRENT); + // ForegroundにするためNotificationが必要、Contextを設定 + NotificationManager notificationManager = + (NotificationManager) context. + getSystemService(Context.NOTIFICATION_SERVICE); + // Notification Channel 設定 + NotificationChannel channel = new NotificationChannel( + channelId, title, NotificationManager.IMPORTANCE_DEFAULT); + channel.setDescription("Silent Notification"); + // 通知音を消さないと毎回通知音が出てしまう + // この辺りの設定はcleanにしてから変更 + channel.setSound(null, null); + // 通知ランプを消す + channel.enableLights(false); + channel.setLightColor(Color.BLUE); + // 通知バイブレーション無し + channel.enableVibration(false); + if (notificationManager != null) { + notificationManager.createNotificationChannel(channel); + android.app.Notification notification = new android.app.Notification.Builder(context, channelId) + .setContentTitle(title) + // 本来なら衛星のアイコンですがandroid標準アイコンを設定 + .setSmallIcon(android.R.drawable.btn_star) + .setContentText("GPS") + .setAutoCancel(true) + .setContentIntent(pendingIntent) + .setWhen(System.currentTimeMillis()) + .build(); + + // startForeground + startForeground(1, notification); + } + + startGPS(); + Timer timer = new Timer(); + TimerTask task = new TimerTask() { + @Override + public void run() { + startUpdateRequest(); + } + }; + //timer.scheduleAtFixedRate(定期的に実行したいタスク,初回のタスク実行までの時間(ms),実行するタスクの間隔(ms)); + timer.scheduleAtFixedRate(task, 10000, 30000); + isServiceRunning = true; + } + + return START_NOT_STICKY; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + @Override + protected void onHandleIntent(Intent intent) { + Log.d(TAG, "onHandleIntent"); + } + + protected void startGPS() { + Log.d(TAG, "startGPS"); + final boolean gpsEnabled + = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + + if (!gpsEnabled) { + // GPSを設定するように促す + enableLocationSettings(); + } + + if (locationManager != null) { + try { + if (ActivityCompat.checkSelfPermission(this, + Manifest.permission.ACCESS_FINE_LOCATION) != + PackageManager.PERMISSION_GRANTED) { + return; + } +// Log.d(TAG, "requestLocationUpdates:"); + + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, + MinTime, MinDistance, this); + } catch (Exception e) { +// Log.d(TAG, "Exception:"); + + e.printStackTrace(); + } + } else { + } + } + + @Override + public void onDestroy() { + Log.d(TAG, "onDestroy"); + super.onDestroy(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + Log.d(TAG, "onConfigurationChanged"); + super.onConfigurationChanged(newConfig); + } + + @Override + public void onLowMemory() { + Log.d(TAG, "onLowMemory"); + super.onLowMemory(); + } + + @Override + public void onTrimMemory(int level) { + Log.d(TAG, "onTrimMemory"); + super.onTrimMemory(level); + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + Log.d(TAG, "onBind"); + return super.onBind(intent); + } + + @Override + public boolean onUnbind(Intent intent) { + Log.d(TAG, "onUnbind"); + return super.onUnbind(intent); + } + + @Override + public void onRebind(Intent intent) { + Log.d(TAG, "onRebind"); + super.onRebind(intent); + } + + @Override + public void onTaskRemoved(Intent rootIntent) { + Log.d(TAG, "onTaskRemoved"); + super.onTaskRemoved(rootIntent); + } + + @Override + protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + Log.d(TAG, "dump"); + super.dump(fd, writer, args); + } + + @Override + public void onLocationChanged(Location location) { + final Cosmos cosmos = (Cosmos) getApplication(); +// Log.d(TAG, "onLocationChanged"); + Log.d(TAG, "lat:" + location.getLatitude()); + Log.d(TAG, "lon:" + location.getLongitude()); + + updateAreaInformation(location); + this.notifications=searchNotifications(cosmos,location); + sendNotifications(this, notifications); + + + } + + private void sendNotifications(CosmosBackgroundService cosmosBackgroundService, List notifications) { + int notificationId = 1; + //以下はボタンについてだよ + Intent intent = new Intent(cosmosBackgroundService, NotificationDone.class); + //snoozeIntent.setAction(ACTION_NOTIFICATION_OFF); + intent.putExtra(EXTRA_NOTIFICATION_ID, 0); + //以下2行はテスト用。本来はNotificationから取ってくる。 + intent.putExtra("gId", UUID.randomUUID().toString()); + intent.putExtra("rId", "rid2"); + int randamCode = (int)(Math.random()*100000); + PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(cosmosBackgroundService, randamCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + +// android.app.Notification.Action action = new android.app.Notification.Action(R.drawable.notification_icon, "ボタンだよ", snoozePendingIntent); + android.app.Notification notification = new android.app.Notification.Builder(cosmosBackgroundService) + .setContentTitle("通知タイトル") + .setContentText("通知ないよう") + .setSmallIcon(R.drawable.icon_no) + .setChannelId("cosmos") +// .setGroup("") +// .addAction(action) + .build(); + notificationManager.notify(notificationId, notification); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + Log.d(TAG, "onStatusChanged"); + } + + @Override + public void onProviderEnabled(String provider) { + Log.d(TAG, "onProviderEnabled"); + } + + @Override + public void onProviderDisabled(String provider) { + Log.d(TAG, "onProviderDisabled"); + + } + + private void startUpdateRequest() { + final Cosmos app = (Cosmos) getApplication(); + if(app.getuId() != null) { + final String uId, token; + uId = app.getuId(); + token = app.getToken(); + + //retrofitの処理 + final Retrofit retrofit = new Retrofit.Builder() + .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/cosmos/rest/") + .addConverterFactory(JacksonConverterFactory.create()) + .build(); + //interfaceから実装を取得 + final GroupsRest getGroupsService = retrofit.create(GroupsRest.class); + final GroupsRest getRequestsService = retrofit.create(GroupsRest.class); + + //API呼び出しのための値入力 + final Call call = getGroupsService.getGroups(uId, token); + + //サーバからデータ受け取り + call.enqueue(new Callback() { + //成功時 + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + final GroupListResponse groupListresult = response.body(); + Log.d(TAG, "GroupListResponseグループ情報通信取得しました"); + + new Thread(new Runnable() { + public void run() { + for (GroupJson groupJson : groupListresult.getGroups()) { + app.setGroup(new Group(groupJson)); + if (groupJson.getRequestHash() != app.getGroup(groupJson.getgId()).getRequestHash()) { + //RequestList取得するための必要な情報 + final String gId = groupJson.getgId(); + final boolean detail = true; + int quantity = 20; + + final Call requestsListByGidCall = getRequestsService.getRequestsListByGid(gId, token, detail, quantity); + Response requestListResponse; + try { + requestListResponse = requestsListByGidCall.execute(); + if (requestListResponse.isSuccessful()) { + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo")); + RequestList requestList = requestListResponse.body(); + app.getGroup(groupJson.getgId()).setRequestList(requestList); + app.getGroup(groupJson.getgId()).setRequestHash(groupJson.getRequestHash()); + Log.d(TAG, groupJson.getName() + "のRequestListを取得しました"); + } else { + // onFailure + try { + System.out.println(requestListResponse.errorBody().string()); + } catch (IOException e) { + e.printStackTrace(); + } + + //onFailureでキャッチできないエラーの処理 + Log.d(TAG, groupJson.getName() + "の通信エラー"); + } + } catch (IOException e) { + e.printStackTrace(); + Log.d(TAG, groupJson.getName() + "のRequestListの取得失敗しました"); + } + } + } + } + }).start(); + } else { + //onFailureでキャッチできないエラー用 + Log.d(TAG, "GroupListResponseグループ情報通信エラー"); + } + } + + //失敗時 + @Override + public void onFailure(Call call, Throwable t) { + t.printStackTrace(); + Log.d(TAG, "GroupListResponseグループ情報取得失敗"); + } + }); + } else { + Log.d(TAG, "app.getuId()がnull"); + } + + } + + private void enableLocationSettings() { + Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); + settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(settingsIntent); + } + + private void updateAreaInformation(Location location){ + Cosmos app = (Cosmos) getApplication(); + count = 0; + LOC.setLatitude(location.getLatitude()); + LOC.setLongitude(location.getLongitude()); + for(int i = 0;i> call = LocationService.LocationService(String.valueOf(leftLat), + String.valueOf(leftLon), String.valueOf(rightLat), String.valueOf(rightLon)); + + //サーバからデータ受け取り + call.enqueue(new Callback>() { + //成功時 + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful()) { + ArrayList result = response.body(); + + //app/Cosmosに情報保存 + Cosmos app = (Cosmos) getApplication(); +// app.setAreaInfo(); + + } else { + //onFailureでキャッチできないエラー用 + Toast.makeText(CosmosBackgroundService.this, + "通信エラー", Toast.LENGTH_LONG).show(); + } + } + + //失敗時 + @Override + public void onFailure(Call> call, Throwable t) { + t.printStackTrace(); + Toast.makeText(CosmosBackgroundService.this, + "区画情報の更新に失敗しました", Toast.LENGTH_SHORT).show(); + } + }); + } + + + } + public List searchNotifications(Cosmos cosmos, Location location){ + + double NowLat =location.getLatitude(); + double NowLon =location.getLongitude(); + //業番:notification + HashMap> codeToNotification = new HashMap<>(); + //業番:feature + HashMap> codeToFeature = new HashMap<>(); + ArrayList groups =(ArrayList) cosmos.getGroups(); + + //現在時刻取得 + Date nowDate = new Date(); + //codeToNotificationを作成。Featureはnull + for(int i = 0 ; i < groups.size(); i++) { + //requestのArrayListを回す + for (int j = 0; j < groups.get(i).getRequestList().getRequests().size(); j++) { + //codeToNotificationに格納するArrayListを初期化 + ArrayList notifications = null; + //期限内かつ未達成のrequestのみ取得 + if (groups.get(i).getRequestList().getRequests().get(j).getDeadline().after(nowDate) && groups.get(i).getRequestList().getRequests().get(j).isDone() == false) { + //notificationを作成 + Notification notification = new Notification(groups.get(i).getRequestList().getRequests().get(j),groups.get(i),null); + //指定したkey(業番)を持っているHashMapがなければ作成する。 + if(codeToNotification.get(groups.get(i).getRequestList().getRequests().get(j).getLocation())==null){ + notifications.add(notification); + codeToNotification.put(groups.get(i).getRequestList().getRequests().get(j).getLocation(),notifications); + }else{ + //keyをすでに持っている場合はArrayListにnotification単体を追加していく + codeToNotification.get(groups.get(i).getRequestList().getRequests().get(j).getLocation()).add(notification); + } + } + } + } + //cosmosから区画情報から取得 + + CosmosLocation cosmosLocation = new CosmosLocation(); + cosmosLocation.setLatitude(NowLat); + cosmosLocation.setLongitude(NowLon); + int areaInfoId = cosmosLocation.hashCode(); + codeToFeature=cosmos.getAreaInfo(areaInfoId).getFeature(); + //codeToFeatureの中の50m圏外Featureを削除していく。 + //HashMapを順番に実行 + for(HashMap.Entry> e : codeToFeature.entrySet()) { + //ArrayList>を回していく + for(int i=e.getValue().size(); i >= 0;i--) { + float[] distance = getDistance(NowLat, NowLon, e.getValue().get(i).getLocation().getLatitude(), e.getValue().get(i).getLocation().getLongitude()); + // distance[0] = [2点間の距離] + //50m圏外のFeatureを削除 + if (distance[0] > 50) { + e.getValue().remove(i); + } + } + //codeToNotificationのkeyとcodeToFeatureのkeyが一致すれば + //codeToFeatureのArrayをcodeToNotificationのArrayfeaturesに代入する + if(codeToNotification.containsKey(e.getKey())==true){ + for(int j=0;j result = new ArrayList(); + + for (ArrayList list: codeToNotification.values()) { + result.addAll(list); + } + + return result; + } + public float[] getDistance(double x, double y, double x2, double y2) { + // 結果を格納するための配列を生成 + float[] results = new float[3]; + // results[0] = [2点間の距離] + // results[1] = [始点から見た方位角] + // results[2] = [終点から見た方位角] + + // 距離計算 + Location.distanceBetween(x, y, x2, y2, results); + + return results; + + } + +} diff --git a/app/src/main/java/com/example/cosmosclient/services/CosmosBootReceiver.java b/app/src/main/java/com/example/cosmosclient/services/CosmosBootReceiver.java new file mode 100644 index 0000000..20ae4d2 --- /dev/null +++ b/app/src/main/java/com/example/cosmosclient/services/CosmosBootReceiver.java @@ -0,0 +1,55 @@ +package com.example.cosmosclient.services; + +import android.Manifest; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Build; +import android.support.annotation.RequiresApi; +import android.support.v4.content.ContextCompat; +import android.util.Log; + +public class CosmosBootReceiver extends BroadcastReceiver { + private static final int REQUEST_MULTI_PERMISSIONS = 101; + private String TAG = CosmosBootReceiver.class.getSimpleName(); + + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "onReceive"); + // Android 6, API 23以上でペーミッションの確認 + if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()) && Build.VERSION.SDK_INT >= 23) { + checkMultiPermissions(context); + } else{ + // サービスの起動 + startService(context); + } + } + + // 位置情報許可の確認、外部ストレージのPermissionにも対応できるようにしておく + private void checkMultiPermissions(Context context){ + // 位置情報の Permission + int permissionLocation = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION); + + // 位置情報の Permission が許可されているか確認 + if (permissionLocation == PackageManager.PERMISSION_GRANTED) { + // 許可済 + startService(context); + } else{ + // 未許可 + } + } + + //serviceをスタートさせる + private void startService(final Context context) { + final Thread thread = new Thread() { + @RequiresApi(api = Build.VERSION_CODES.O) + public void run() { + // サービスの起動 + Intent intentservice = new Intent(context, CosmosBackgroundService.class); + context.startForegroundService(intentservice); + } + }; + thread.start(); + } +} diff --git a/app/src/main/java/com/example/cosmosclient/services/CosomosBackgroundService.java b/app/src/main/java/com/example/cosmosclient/services/CosomosBackgroundService.java deleted file mode 100644 index cd2f3e8..0000000 --- a/app/src/main/java/com/example/cosmosclient/services/CosomosBackgroundService.java +++ /dev/null @@ -1,276 +0,0 @@ -package com.example.cosmosclient.services; - -import android.Manifest; -import android.app.IntentService; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Intent; -import android.content.Context; -import android.content.pm.PackageManager; -import android.graphics.Color; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.os.Build; -import android.os.Bundle; -import android.provider.Settings; -import android.support.annotation.RequiresApi; -import android.support.v4.app.ActivityCompat; -import android.util.Log; - -import com.example.cosmosclient.R; -import com.example.cosmosclient.app.Cosmos; -import com.example.cosmosclient.entities.Group; -import com.example.cosmosclient.entities.GroupListResponse; -import com.example.cosmosclient.entities.RequestList; -import com.example.cosmosclient.entities.jsons.GroupJson; -import com.example.cosmosclient.resources.GroupsRest; - -import java.io.IOException; -import java.util.TimeZone; -import java.util.Timer; -import java.util.TimerTask; - -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; -import retrofit2.converter.jackson.JacksonConverterFactory; - - -public class CosomosBackgroundService extends IntentService implements LocationListener { - private Context context; - private LocationManager locationManager; - private static final int MinTime = 1000;/*最小時間間隔*/ - private static final float MinDistance = 1;/*最小距離間隔*/ - - public CosomosBackgroundService() { - super("CosomosBackgroundService"); - } - - @Override - public void onCreate() { - super.onCreate(); -// Log.d("debug", "onCreate"); - context = getApplicationContext(); - // LocationManager インスタンス生成 - locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); - } - - @RequiresApi(api = Build.VERSION_CODES.O) - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - -// Log.d("debug", "onStartCommand"); - int requestCode = 0; - String channelId = "default"; - String title = context.getString(R.string.app_name); - PendingIntent pendingIntent = - PendingIntent.getActivity(context, requestCode, - intent, PendingIntent.FLAG_UPDATE_CURRENT); - // ForegroundにするためNotificationが必要、Contextを設定 - NotificationManager notificationManager = - (NotificationManager) context. - getSystemService(Context.NOTIFICATION_SERVICE); - // Notification Channel 設定 - NotificationChannel channel = new NotificationChannel( - channelId, title, NotificationManager.IMPORTANCE_DEFAULT); - channel.setDescription("Silent Notification"); - // 通知音を消さないと毎回通知音が出てしまう - // この辺りの設定はcleanにしてから変更 - channel.setSound(null, null); - // 通知ランプを消す - channel.enableLights(false); - channel.setLightColor(Color.BLUE); - // 通知バイブレーション無し - channel.enableVibration(false); - if (notificationManager != null) { - notificationManager.createNotificationChannel(channel); - Notification notification = new Notification.Builder(context, channelId) - .setContentTitle(title) - // 本来なら衛星のアイコンですがandroid標準アイコンを設定 - .setSmallIcon(android.R.drawable.btn_star) - .setContentText("GPS") - .setAutoCancel(true) - .setContentIntent(pendingIntent) - .setWhen(System.currentTimeMillis()) - .build(); - - // startForeground - startForeground(1, notification); - } - - startGPS(); - Timer timer = new Timer(); - TimerTask task = new TimerTask() { - @Override - public void run() { - startUpdateRequest(); - } - }; - //timer.scheduleAtFixedRate(定期的に実行したいタスク,初回のタスク実行までの時間(ms),実行するタスクの間隔(ms)); - timer.scheduleAtFixedRate(task, 10000, 30000); - - return START_NOT_STICKY; - } - - @RequiresApi(api = Build.VERSION_CODES.O) - @Override - protected void onHandleIntent(Intent intent) { -// Log.d("debug", "onHandleIntent"); - } - - protected void startGPS() { - Log.d("debug", "startGPS"); - final boolean gpsEnabled - = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); - - if (!gpsEnabled) { - // GPSを設定するように促す - enableLocationSettings(); - } - - if (locationManager != null) { - try { - if (ActivityCompat.checkSelfPermission(this, - Manifest.permission.ACCESS_FINE_LOCATION) != - PackageManager.PERMISSION_GRANTED) { - return; - } -// Log.d("debug", "requestLocationUpdates:"); - - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, - MinTime, MinDistance, this); - } catch (Exception e) { -// Log.d("debug", "Exception:"); - - e.printStackTrace(); - } - } else { - } - } - - @Override - public void onDestroy() { -// Log.d("debug", "onDestroy"); - super.onDestroy(); - } - - @Override - public void onLocationChanged(Location location) { -// Log.d("debug", "onLocationChanged"); - Log.d("debug", "lat:" + location.getLatitude()); - Log.d("debug", "lon:" + location.getLongitude()); - - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - - } - - @Override - public void onProviderEnabled(String provider) { - - } - - @Override - public void onProviderDisabled(String provider) { - - } - - private void startUpdateRequest() { - final Cosmos app = (Cosmos) getApplication(); - if(app.getuId() != null) { - final String uId, token; - uId = app.getuId(); - token = app.getToken(); - - //retrofitの処理 - final Retrofit retrofit = new Retrofit.Builder() - .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/cosmos/rest/") - .addConverterFactory(JacksonConverterFactory.create()) - .build(); - //interfaceから実装を取得 - final GroupsRest getGroupsService = retrofit.create(GroupsRest.class); - final GroupsRest getRequestsService = retrofit.create(GroupsRest.class); - - //API呼び出しのための値入力 - final Call call = getGroupsService.getGroups(uId, token); - - //サーバからデータ受け取り - call.enqueue(new Callback() { - //成功時 - @Override - public void onResponse(Call call, Response response) { - if (response.isSuccessful()) { - final GroupListResponse groupListresult = response.body(); - Log.d("debug", "GroupListResponseグループ情報通信取得しました"); - - new Thread(new Runnable() { - public void run() { - for (GroupJson groupJson : groupListresult.getGroups()) { - app.setGroup(new Group(groupJson)); - if (groupJson.getRequestHash() != app.getGroup(groupJson.getgId()).getRequestHash()) { - //RequestList取得するための必要な情報 - final String gId = groupJson.getgId(); - final boolean detail = true; - int quantity = 20; - - final Call requestsListByGidCall = getRequestsService.getRequestsListByGid(gId, token, detail, quantity); - Response requestListResponse; - try { - requestListResponse = requestsListByGidCall.execute(); - if (requestListResponse.isSuccessful()) { - TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo")); - RequestList requestList = requestListResponse.body(); - app.getGroup(groupJson.getgId()).setRequestList(requestList); - app.getGroup(groupJson.getgId()).setRequestHash(groupJson.getRequestHash()); - Log.d("debug", groupJson.getName() + "のRequestListを取得しました"); - } else { - // onFailure - try { - System.out.println(requestListResponse.errorBody().string()); - } catch (IOException e) { - e.printStackTrace(); - } - - //onFailureでキャッチできないエラーの処理 - Log.d("debug", groupJson.getName() + "の通信エラー"); - } - } catch (IOException e) { - e.printStackTrace(); - Log.d("debug", groupJson.getName() + "のRequestListの取得失敗しました"); - } - } - } - } - }).start(); - } else { - //onFailureでキャッチできないエラー用 - Log.d("debug", "GroupListResponseグループ情報通信エラー"); - } - } - - //失敗時 - @Override - public void onFailure(Call call, Throwable t) { - t.printStackTrace(); - Log.d("debug", "GroupListResponseグループ情報取得失敗"); - } - }); - } else { - Log.d("debug", "app.getuId()がnull"); - } - - } - - private void enableLocationSettings() { - Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); - settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(settingsIntent); - } - -} diff --git a/app/src/main/java/com/example/cosmosclient/views/GroupListActivity.java b/app/src/main/java/com/example/cosmosclient/views/GroupListActivity.java index 0ff3b5b..aa105e2 100644 --- a/app/src/main/java/com/example/cosmosclient/views/GroupListActivity.java +++ b/app/src/main/java/com/example/cosmosclient/views/GroupListActivity.java @@ -1,7 +1,6 @@ package com.example.cosmosclient.views; import android.content.Intent; -import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.nfc.Tag; @@ -347,10 +346,8 @@ startActivity(intent); } else if (id == R.id.signOutButton){ //トークン削除 - SharedPreferences prefData = getSharedPreferences("pref_data", MODE_PRIVATE); - SharedPreferences.Editor editor = prefData.edit(); - editor.remove("token"); - editor.commit(); + Cosmos app = (Cosmos) getApplication(); + app.setToken(""); gridView.stopEditMode(); Intent intent=new Intent(GroupListActivity.this, com.example.cosmosclient.views.SigninActivity.class); ActivityCompat.finishAffinity(GroupListActivity.this); diff --git a/app/src/main/java/com/example/cosmosclient/views/SigninActivity.java b/app/src/main/java/com/example/cosmosclient/views/SigninActivity.java index 400555d..9b75c51 100644 --- a/app/src/main/java/com/example/cosmosclient/views/SigninActivity.java +++ b/app/src/main/java/com/example/cosmosclient/views/SigninActivity.java @@ -1,17 +1,11 @@ package com.example.cosmosclient.views; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; import android.content.Context; import android.Manifest; -import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Build; import android.os.Handler; -import android.os.HandlerThread; import android.support.annotation.NonNull; import android.support.annotation.RequiresApi; import android.support.v4.app.ActivityCompat; @@ -26,13 +20,11 @@ import android.widget.EditText; import android.widget.Toast; -import com.example.cosmosclient.MainActivity; import com.example.cosmosclient.R; import com.example.cosmosclient.app.Cosmos; -import com.example.cosmosclient.entities.AreaInformation; import com.example.cosmosclient.entities.SigninResponse; import com.example.cosmosclient.resources.UsersRest; -import com.example.cosmosclient.services.CosomosBackgroundService; +import com.example.cosmosclient.services.CosmosBackgroundService; import java.util.ArrayList; @@ -72,9 +64,16 @@ final EditText PasswordText = findViewById(R.id.PasswordText); Button ForgotPasswordButton = findViewById(R.id.ForgotPasswordButton); - // 「pref_data」という設定データファイルを読み込み - SharedPreferences prefData = getSharedPreferences("pref_data", MODE_PRIVATE); - String account = prefData.getString("account", ""); + Cosmos app = (Cosmos) getApplication(); + String account = app.getuId(); + String token = app.getToken(); + +// //ログアウトしていない場合singnin画面を表示しない +// if(token != ""){ +// Intent intent = new Intent(getApplication(), GroupListActivity.class); +// startActivity(intent); +// finish(); +// } // 空チェック if (account != null && account.length() > 0) { @@ -133,13 +132,6 @@ app.setToken(result.token); app.setuId(UserIdText.getText().toString()); - //SharedPreferencesに情報保存 - SharedPreferences prefData = getSharedPreferences("pref_data", MODE_PRIVATE); - SharedPreferences.Editor editor = prefData.edit(); - editor.putString("account", UserIdText.getText().toString()); - editor.putString("token", result.token); - editor.commit(); - //画面遷移 Intent intent = new Intent(getApplication(), GroupListActivity.class); startActivity(intent); @@ -306,7 +298,7 @@ Thread thread = new Thread() { @RequiresApi(api = Build.VERSION_CODES.O) public void run() { - intentservice = new Intent(SigninActivity.this, CosomosBackgroundService.class); + intentservice = new Intent(SigninActivity.this, CosmosBackgroundService.class); startForegroundService(intentservice); } diff --git a/app/src/main/java/com/example/cosmosclient/views/SignupActivity.java b/app/src/main/java/com/example/cosmosclient/views/SignupActivity.java index 619aa72..8db61a1 100644 --- a/app/src/main/java/com/example/cosmosclient/views/SignupActivity.java +++ b/app/src/main/java/com/example/cosmosclient/views/SignupActivity.java @@ -2,7 +2,6 @@ import android.content.Intent; -import android.content.SharedPreferences; import android.graphics.Bitmap; import android.net.Uri; import android.os.Handler; @@ -112,18 +111,6 @@ Cosmos app = (Cosmos) getApplication(); app.setToken(result.token); app.setuId(result.uId); - //データをprerefarenceに保存 - - // 「pref_data」という設定データファイルを読み込み - SharedPreferences prefData = getSharedPreferences("pref_data", MODE_PRIVATE); - SharedPreferences.Editor editor = prefData.edit(); - - // 入力されたログインIDとログインパスワード - editor.putString("account", result.uId); - editor.putString("token", result.token); - - // 保存 - editor.commit(); Intent intent = new Intent(getApplication(), GroupListActivity.class); startActivity(intent); diff --git a/app/src/main/res/drawable/icon_no.png b/app/src/main/res/drawable/icon_no.png new file mode 100644 index 0000000..807f3e4 --- /dev/null +++ b/app/src/main/res/drawable/icon_no.png Binary files differ