teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

コメント修正

2017/11/16 16:53

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -64,10 +64,11 @@
64
64
  if (mlocation != null) {
65
65
  latitude = mlocation.getLatitude();
66
66
  longitude = mlocation.getLongitude();
67
+ // onProgressUpdate()にmlocationを渡す
67
68
  publishProgress(mlocation);
68
69
  }
69
70
 
70
- SystemClock.sleep(1000);
71
+ SystemClock.sleep(1000); // 1000ミリ秒の時間稼ぎ
71
72
 
72
73
  if (this.isCancelled()) {
73
74
  loop = false;
@@ -81,7 +82,6 @@
81
82
  @Override
82
83
  protected void onProgressUpdate(Location... values) {
83
84
  // このメソッドはUIスレッドで動くのでTextViewなどを操作できる
84
- //
85
85
  TextView textView1 = ((Activity) mContextAsync).findViewById(R.id.textView1);
86
86
  TextView textView2 = ((Activity) mContextAsync).findViewById(R.id.textView2);
87
87
  textView1.setText(String.valueOf(values[0].getLatitude()));

2

コードで回答を提示

2017/11/16 16:53

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -30,4 +30,70 @@
30
30
 
31
31
  checkSelfPermissionは本来はContextCompatの持つクラスメソッドなので、上記のコードではそのように書き換えています。ActivityCompatはContextCompatを継承しているので、元のままでも支障はないのですが、気分的な問題です(まあどちらでもいいでしょう)。
32
32
 
33
- ただこの処理、AsyncTaskの中でも通ったかな?実証していないのでそこはちょっと自信がありません。もし蹴られるようなら、この作業をActivityのコードの、AsyncTaskをnewする以前の場所に移してみましょう。
33
+ ただこの処理、AsyncTaskの中でも通ったかな?実証していないのでそこはちょっと自信がありません。もし蹴られるようなら、この作業をActivityのコードの、AsyncTaskをnewする以前の場所に移してみましょう。
34
+
35
+ ---
36
+
37
+ 「時間稼ぎ」の部分の回答のコードとして
38
+
39
+ ```Java
40
+ // onProgressUpdateでLocationを受け取るので、真ん中をVoidではなくLocationにする
41
+ public class Asyn extends AsyncTask<Void, Location, Void> implements LocationListener {
42
+
43
+ private Context mContextAsync; // 頭が大文字の変数名は好ましくないのでmを付けた
44
+
45
+ public Asyn(Context context) {
46
+ // getApplicationContext()を呼ばずそのまま保持する
47
+ // この変数を用いていた他の処理はそのままでも問題ないはず
48
+ mContextAsync = context;
49
+ }
50
+
51
+ @Override
52
+ protected Void doInBackground(Void... voids) {
53
+
54
+ // 中略
55
+
56
+ if (ActivityCompat.checkSelfPermission(mContextAsync, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED ||
57
+ ActivityCompat.checkSelfPermission(mContextAsync, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
58
+
59
+ boolean loop = true;
60
+
61
+ // 繰り返し処理
62
+ while (loop) {
63
+ mlocation = locManAsyn.getLastKnownLocation(pro);
64
+ if (mlocation != null) {
65
+ latitude = mlocation.getLatitude();
66
+ longitude = mlocation.getLongitude();
67
+ publishProgress(mlocation);
68
+ }
69
+
70
+ SystemClock.sleep(1000);
71
+
72
+ if (this.isCancelled()) {
73
+ loop = false;
74
+ }
75
+ }
76
+ }
77
+
78
+ return null;
79
+ }
80
+
81
+ @Override
82
+ protected void onProgressUpdate(Location... values) {
83
+ // このメソッドはUIスレッドで動くのでTextViewなどを操作できる
84
+ //
85
+ TextView textView1 = ((Activity) mContextAsync).findViewById(R.id.textView1);
86
+ TextView textView2 = ((Activity) mContextAsync).findViewById(R.id.textView2);
87
+ textView1.setText(String.valueOf(values[0].getLatitude()));
88
+ textView2.setText(String.valueOf(values[0].getLongitude()));
89
+ }
90
+
91
+ @Override
92
+ protected void onCancelled() {
93
+ locManAsyn.removeUpdates(this);
94
+ }
95
+
96
+ // 中略
97
+
98
+ }
99
+ ```

1

修正

2017/11/16 16:43

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -1,8 +1,10 @@
1
+ アクセス許可がないということでエラーになっているようですね。
2
+
1
3
  ```Java
2
4
  if (ActivityCompat.checkSelfPermission(this.ContextAsync, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
3
5
  ActivityCompat.checkSelfPermission(this.ContextAsync, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
4
6
  ```
5
- という処理で許可があるかどうかを確認するまでは良いのですが、肝心の「許可がなければ許可を得る」という作業がありませんね。そのためにエラーになっているのではないでしょうか。また、上記は論理積(&&)になっているのですが、「どちらか一方の許可がなければ」という条件にした方が良いと思われるので、論理和(||)にした方が良さそうです。
7
+ という処理で許可を確認するまでは良いのですが、肝心の「なければ許可を得る」という処理がありませんね。そのためにエラーになっているのではないでしょうか。また、上記のコードは論理積(&&)になっていすが、「どちらか一方の許可がなければ」という論理和(||)にした方が良さそうです。
6
8
 
7
9
  許可を得るには、
8
10
  ```
@@ -13,8 +15,8 @@
13
15
  };
14
16
 
15
17
 
16
- if (ActivityCompat.checkSelfPermission(this.ContextAsync, mPermission[0]) != PackageManager.PERMISSION_GRANTED ||
18
+ if (ContextCompat.checkSelfPermission(this.ContextAsync, mPermission[0]) != PackageManager.PERMISSION_GRANTED ||
17
- ActivityCompat.checkSelfPermission(this.ContextAsync, mPermission[1]) != PackageManager.PERMISSION_GRANTED) {
19
+ ContextCompat.checkSelfPermission(this.ContextAsync, mPermission[1]) != PackageManager.PERMISSION_GRANTED) {
18
20
  ActivityCompat.requestPermissions(
19
21
  this.ContextAsync, mPermission, REQUEST_PERMISSION);
20
22
  }
@@ -22,8 +24,10 @@
22
24
 
23
25
  のような感じにすればいいのではないでしょうか。
24
26
 
25
- requestPermissionsを呼ぶと、汎用のAndroidアプリを初めて実行したときによく見るような「この端末の位置情報へのアクセスを許可しますか?」のようなダイアログが出ます。ここで「許可しない」を選ばれてしまうと結局エラーになってしまうので、そういう場合にはアプリを終了する処理を入れるとか、汎用性を持たせるためにはもっと細かい処理は必要になりますが、上記ではとりあえず「そういうことはしない!」と割りきっています。
27
+ ActivityCompat.requestPermissionsを呼ぶと、汎用のAndroidアプリを初めて実行したときによく見るような「この端末の位置情報へのアクセスを許可しますか?」のようなダイアログが出ます。ここで「許可しない」を選ばれてしまうと結局エラーになってしまうので、そういう場合にはアプリを終了する処理を入れるとか、汎用性を持たせるためにはもっと細かい処理は必要になりますが、上記ではとりあえず「そういうことはしない!」と割りきっています。
26
28
 
27
29
  なお、REQUEST_PERMISSIONはonRequestPermissionsResultというコールバックメソッドに渡される値になるので、これを用いなければ適当な数値で構いません。
28
30
 
31
+ checkSelfPermissionは本来はContextCompatの持つクラスメソッドなので、上記のコードではそのように書き換えています。ActivityCompatはContextCompatを継承しているので、元のままでも支障はないのですが、気分的な問題です(まあどちらでもいいでしょう)。
32
+
29
33
  ただこの処理、AsyncTaskの中でも通ったかな?実証していないのでそこはちょっと自信がありません。もし蹴られるようなら、この作業をActivityのコードの、AsyncTaskをnewする以前の場所に移してみましょう。