はじめに
AndroidstudioでARアプリを開発しています。言語はjavaを使用しています。
カメラを向けた先に目的地があれば目的地の名称と現在地からの距離をの書かれた吹き出しを表示するというアプリです。
実現したいこと
目的地のデータをandroid端末の内部ストレージに保存してあるjsonファイルから取得し、後のプログラムにて使用したいです。
現状
実行時にエラーは出ないのですが、アプリを起動したときに吹き出しが表示されません。
考えられる原因は、内部ストレージからjsonファイルの取得ができていない、jsonファイルの読み取り方が間違っている、jsonから得た値の受け渡しが出来ていない、などだと思うのですが、初心者の私にはどこが問題なのか分かりませんでした。
知識のある方から見て、どこが問題であるのかご指摘頂けたら幸いです。よろしくお願いします。
sample.json
1[{ 2 "info":"ここに目的地の名称が入ります", 3 "latitude":35.xxxxxx, 4 "longitude":138.xxxxx 5 }, 6 { 7 "info":"〇〇〇〇〇〇", 8 "latitude":35.yyyyyy, 9 "longitude":138.yyyyyy 10 }, 11 ~略~ 12}] 13
/data/data/[packagename]/files/sample.json のように保存しています。
Overlayview.java
1package com.example.secondar6; 2 3import android.content.Context; 4import android.graphics.Canvas; 5import android.graphics.Color; 6import android.graphics.Paint; 7import android.graphics.Path; 8import android.graphics.RectF; 9import android.view.Display; 10import android.view.View; 11import android.view.WindowManager; 12 13import com.google.android.gms.maps.model.LatLng; 14 15import org.json.JSONArray; 16import org.json.JSONException; 17import org.json.JSONObject; 18 19import java.io.BufferedReader; 20import java.io.File; 21import java.io.FileNotFoundException; 22import java.io.FileReader; 23import java.io.IOException; 24import java.util.ArrayList; 25 26public class OverlayView extends View { 27 28 // カメラの画角を指定する 29 private final int ANGLE = 71; 30 // ARテキストの見える範囲を指定する 31 // ここでは3kmほどに指定する 32 private final float VIEW_LIMIT = 3000; 33 34 //赤道半径 35 private final double RADIUS = 6378137; 36 37 // ディスプレイサイズ 38 private int displayX; 39 // コンパスの描画位置を指定する 40 private final float POS_COMPASSX = 100; 41 private final float POS_COMPASSY = 100; 42 43 // 向きを保持する変数 44 float direction; 45 46 // 現在地を保持する変数 47 float posx; 48 float posy; 49 50 // ARテキストの情報を保持するオブジェクト 51 private ArrayList<readJson.GPSdata> glist; 52 53 public OverlayView(Context context) { 54 super(context); 55 // 画面サイズの取得 56 Display disp = ((WindowManager) context 57 .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 58 displayX = disp.getWidth(); 59 } 60 61 public static class readJson { 62 public static ArrayList<GPSdata> jlist = new ArrayList<>(); 63 public static void main(String[] args) throws JSONException { 64 String data = readFile(); 65 JSONArray jarray = new JSONArray(data); 66 67 for (int n = 0; n < jarray.length(); n++) { 68 JSONObject jobject = jarray.getJSONObject(n); 69 70 String info = (String) jobject.get("info"); 71 String slatitude = (String) jobject.get("latitude"); 72 String slongitude = (String) jobject.get("longitude"); 73 74 double latitude = Double.parseDouble(slatitude); 75 double longitude = Double.parseDouble(slongitude); 76 77 jlist.add(new GPSdata(info, latitude, longitude)); 78 } 79 } 80 81 public static class GPSdata { 82 String info; 83 double latitude; 84 double longitude; 85 86 public GPSdata(String info, double latitude, double longitude) { 87 this.info = info; 88 this.latitude = latitude; 89 this.longitude = longitude; 90 } 91 } 92 } 93 94 private static String readFile() { 95 Context context = Myapplication.getAppContext(); 96 String fileName = "sample.json"; 97 try { 98 File file = new File(context.getFilesDir(),fileName); 99 BufferedReader br = new BufferedReader(new FileReader(file)); 100 101 String data = " "; 102 String str = br.readLine(); 103 while (str != null){ 104 data += str; 105 str = br.readLine(); 106 } 107 br.close(); 108 return data; 109 }catch (FileNotFoundException e){ 110 System.out.println(e); 111 return null; 112 }catch (IOException e){ 113 System.out.println(e); 114 return null; 115 } 116 } 117 118 119 // (1)描画処理 120 @Override 121 protected void onDraw(Canvas canvas) { 122 Paint paint = new Paint(); 123 paint.setAntiAlias(true); 124 125 // 0.1秒休止 126 // 吹き出しの高速移動によるちらつきを抑える 127 try { 128 Thread.sleep(100); 129 } catch (InterruptedException e) { 130 e.printStackTrace(); 131 } 132 133 ArrayList<readJson.GPSdata> glist = readJson.jlist; 134 135 // 追記:ARテキストの描画 136 for (int i = 0; i < glist.size(); i++) { 137 // データの読み込み 138 readJson.GPSdata gdata = glist.get(i); 139 String info = gdata.info; 140 double y = gdata.latitude; 141 double x = gdata.longitude; 142 143 // ARテキストとの距離を求める 144 double dx = (x - posx); 145 double dy = (y - posy); 146 147 //緯度・経度差を距離(m)に直す 148 double yrad = Math.toRadians(y); 149 double posyrad = Math.toRadians(posy); 150 double dxrad = Math.toRadians(dx); 151 float distance = (float)(RADIUS * Math.acos(Math.sin(yrad)* Math.sin(posyrad) 152 + Math.cos(yrad) * Math.cos(posyrad) * Math.cos(dxrad))); 153 154 155 // ARテキストと現在地のなす角を求めて正規化する 156 double angle = Math.atan2(dy, dx); 157 float degree = (float) Math.toDegrees(angle); 158 degree = -degree + 90; 159 if (degree < 0) 160 degree = 360 + degree; 161 162 // 端末の向きとARテキストとの角度の差を求める 163 float sub = degree - direction; 164 if (sub < -180.0) 165 sub += 360; 166 if (sub > 180.0) 167 sub -= 360; 168 169 // ARテキストが視野に存在すれば描画処理を行う 170 if (Math.abs(sub) < (ANGLE / 2)) { 171 // 距離によってARテキストのサイズを決める 172 float textSize = 60 * (VIEW_LIMIT - distance) 173 / VIEW_LIMIT; 174 paint.setTextSize(textSize); 175 176 // ARテキストの描画を描画する 177 String infoDistance = info + " " + (int)distance + "m" ; 178 float textWidth = paint.measureText(infoDistance); 179 float diff = (sub / (ANGLE / 2)) / 2; 180 float left = (displayX / 2 + displayX * diff) - (textWidth / 2); 181 drawBalloonText(canvas, paint, infoDistance, left, 200); 182 } 183 } 184 185 // コンパスを描画する 186 drawCompass(canvas, paint); 187 } 188 189 private void drawBalloonText(Canvas canvas, Paint paint, String text, 190 float left, float top) { 191 // 文字列の幅を取得 192 float textWidth = paint.measureText(text); 193 // フォント情報の取得 194 Paint.FontMetrics fontMetrics = paint.getFontMetrics(); 195 196 // 文字列の20ポイント外側を囲む座標を求める 197 float bLeft = left - 20; 198 float bRight = left + textWidth + 20; 199 float bTop = top + fontMetrics.ascent - 20; 200 float bBottom = top + fontMetrics.descent + 20; 201 202 // 吹き出しの描画 203 RectF rectF = new RectF(bLeft, bTop, bRight, bBottom); 204 paint.setColor(Color.argb(100,0,255,0)); 205 canvas.drawRoundRect(rectF, 50, 50, paint); 206 207 208 // 三角形の描画 209 paint.setStyle(Paint.Style.FILL_AND_STROKE); 210 Path path = new Path(); 211 float center = left + textWidth / 2; 212 float triangleSize = paint.getTextSize() / 2; 213 path.moveTo(center, bBottom + triangleSize); 214 path.lineTo(center - triangleSize , bBottom ); 215 path.lineTo(center + triangleSize , bBottom ); 216 path.lineTo(center, bBottom + triangleSize); 217 canvas.drawPath(path, paint); 218 219 // 文字列の描画 220 paint.setColor(Color.WHITE); 221 canvas.drawText(text, left, top, paint); 222 223 } 224 225 // (2)コンパスの描画 226 private void drawCompass(Canvas canvas, Paint paint) { 227 Path path = new Path(); 228 path.moveTo(POS_COMPASSX, POS_COMPASSY - 40); 229 path.lineTo(POS_COMPASSX + 20, POS_COMPASSY + 20); 230 path.lineTo(POS_COMPASSX - 20, POS_COMPASSY + 20); 231 path.moveTo(POS_COMPASSX, POS_COMPASSY - 40); 232 paint.setColor(Color.RED); 233 canvas.rotate(-direction, POS_COMPASSX, POS_COMPASSY); 234 canvas.drawPath(path, paint); 235 canvas.rotate(direction, POS_COMPASSX, POS_COMPASSY); 236 } 237 238 // (3)センサー値の取得と再描画 239 public void drawScreen(float preDirection,LatLng latlng) { 240 // センサーの値から端末の向きを計算する 241 direction = (preDirection + 450) % 360; 242 // 座標情報の取得 243 if(latlng != null){ 244 posy = (float) latlng.latitude; 245 posx = (float) latlng.longitude; 246 } 247 // onDrawを呼び出して再描画 248 invalidate(); 249 } 250} 251

回答1件
あなたの回答
tips
プレビュー