質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

0回答

605閲覧

他クラスのオブジェクト(Button)へのアクセス(Alt Beacon LibraryでBeacon受信時のみボタンをEnableにする方法)

dotsuru

総合スコア0

Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2021/05/10 10:06

編集2022/01/12 10:55

MainActivityクラスにあるボタンを、
他クラスから有効・無効を設定できるように、
以下のようにstaticなオブジェクトに設定し、

public class MainActivity extends AppCompatActivity { public static Button entButton; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); entButton = (Button) findViewById(R.id.buttonENT); } }

Alt Beacon LibraryというBluetoothのBeaconを受信するLibraryを使用して、
受信しているBeacon数を取得するモジュール内で、
Beaconを受信したときは、ButtonをEnableに、
受信できないときは、ButtonをDisableにするような処理を書きました。

public class RangingActivity extends Activity implements BeaconConsumer { ・・・ @Override public void onBeaconServiceConnect() { RangeNotifier rangeNotifier = new RangeNotifier() { @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { if (beacons.size() > 0) { MainActivity.entButton.setEnabled(true); }else{ MainActivity.entButton.setEnabled(false); } } } } ・・・

すると、起動時はBeaconの状態に応じてEnable/Disableは正常に動作するのですが、
Beacon状態が変化したとき(Enable→Disable もしくは Disable→Enable)に、
アプリがCrashして落ちます。

不思議なのは、Android StudioのVersionを4.2に上げる前までは正常に動いていました。
そこでVer.4.2をUninstallして、古いVer4.1.1をインストールしてみたのですが、
それでも正常動作しませんでした。

さらに、RangingActivityクラスに2つのボタンを追加し、
それぞれのボタンを押したときに、
MainActivity.entButton.setEnabled(true);とMainActivity.entButton.setEnabled(false);
を実行するようにしたところ、
ボタンのクリックにより、MainActivityクラスのボタンの
有効・無効を正常に切り替えることが出来ました。
もう、わけがわかりません(@_@?)
ボタンに割り当てた時との違いは、RangingActivityの画面が、
一番前に来ているかどうかなので、それが原因なのかとも思ったのですが、
確証が得られません。

他クラスから、別クラスのボタンObjectにアクセスする方法が間違っているのか、
Beacon Libraryが、新しいバージョンのAndroid Studioに対応しなくなったのかの
切り分けができずに困っています。

どうかお知恵をお貸しください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2021/05/10 12:18

MainActivity のボタンを、他の activity から直接変更しようとするのがそもそも間違ってます。ましてや static なんかにしてはいけません。 MainActivity と RangingActivity はどのように画面遷移しますか?
dotsuru

2021/05/10 12:27

基本的に画面表示されているのはMainActivtyだけで、裏でBeaconを受信しているRangingActivityを表示させるためには、MainActivityに設定したMenuからRangingActivityを呼び出す必要があります。 ただし、そのメニューはあくまでテストのために追加したもので、最終的な完成形では、RangingActivityが表示されることはありません。
dotsuru

2021/05/10 12:38

すいません。嘘言ったかもしれません。 RangingActivityを起動時に一度Intentしなければ、Beaconを受信することはできないはずですよね。 今、自宅なので、明日出社してからソース見直して、あらためて回答します。 申し訳ありませんが、もう少しお付き合いください。
hoshi-takanori

2021/05/10 13:19

Bluetooth はあまり詳しくありませんが、beacon を受信するとかの処理をバックグラウンドで行うには activity ではなく service とかを使うのでは…。
dotsuru

2021/05/10 13:30

serviceを使う方法もあるようですが、私はApplicationにコードを書き、起動時に一度だけ実行するように、Manifestに記述しました。 記憶が曖昧なので、明日正しい情報をかきますが、このApplicationクラスからRangingActivityを起動していたような気がします。 ネットで検索して、別Avtivityから他のActivityのObjectにアクセスする方法として、staticを利用するのを見つけたのですが、オブジェクト志向という観点から見ると、この方法は邪道なのでしょうか? では、正しくはどうすべきなのかがわかりません。 Staticなボタンのプロパティを直接操作するのは抵抗あったので、最初はpublicなメソッドを作成して、その中でstaticなボタンのプロパティを変更するようにしてたのですが、どっちもCrashすることに違いはありませんでした。
hoshi-takanori

2021/05/10 14:04 編集

オブジェクト指向の一般論としては、クラスとインスタンス (そのクラスのオブジェクト) を区別する必要があって、一つのクラスからは複数のインスタンスを作ることができますが、static 変数はクラスに一つしかないので、複数のインスタンスを生成する可能性のあるクラスで static 変数を特定のインスタンスのために使うのは良くないです。(逆に、あるクラスのインスタンスで共通に使いたい情報や、あるクラスのインスタンスを一つしか作らない場合 (シングルトンパターン) には static 変数を使います。) おそらく質問者さんは MainActivity の画面は一つしかないから MainActivity のインスタンスも一つしかないはずだとお考えだと思いますが、それは良くある誤解で、Android では画面を回転すると現在の Activity が破棄されて新しい Activity が作り直されますし、別の Activity やアプリに切り替えた状態でメモリ不足になるとバックグラウンドの Activity が破棄されてその Activity に戻った際に作り直されるというようなことが起こります。この際、static 変数から古い画面を参照しているとクラッシュやメモリーリークの原因になります。 Service を使えばアプリの切り替えやアプリ内での画面遷移とは関係なくバックグラウンドで処理を続けることができるので、beacon の処理などを行うにはその辺の (画面表示とは関係のない) Android OS の内部動作について学ぶ必要があるのではないかと思います。
dotsuru

2021/05/10 14:05

返信ありがとうございます。 MainActivityのインスタンスは一つしかないという誤解は、まさにその通りに誤解してました。 もしかしたら今回のCrashは、メモリ不足が発生して、破棄されたActivityをstatic変数が参照している可能性があるということですね。 でも、Serviceでbeaconの処理を実現しても、そのServiceからMainActivity上のボタンのプロパティにアクセスする必要があり、やはりstaticのお世話になりそうな気もするのですが・・。
hoshi-takanori

2021/05/10 14:24

Activity のライフサイクルについては、この辺をお読みください。 https://developer.android.com/guide/components/activities/activity-lifecycle?hl=ja Service と Activity の間で通信を行うには、Activity が生成されたりフォアグラウンドになった時に Service に接続 (バインド) して、Activity がバックグラウンドになったり破棄される時には接続を解除する必要があります。 https://developer.android.com/guide/components/bound-services?hl=ja
dotsuru

2021/05/10 14:48

Activityのライフサイクルについては、教えていただいたサイトを、目を皿のようにして熟読し、それでもBeacon受信プロセスが終了しないので、無理やりプロセスをkillする手段とかを取ってるので、まだまだ勉強不足かもしれません。 Serviceについては挫折してしまい、Applicationクラスで実装したら、うまく動いたので安心していたのですが、Android Studio(Gradle?)のバージョンを上げたら、急に落ちるようになってしまい、途方に暮れてた次第です。 setEnabledで、ずっとtrueを設定しつづけてるとCrashせず、true設定後にfalseに変更するとCrashするというあたりに、なんかヒントがあるような気がしてます。 MainAvtivityは、画面の回転を抑制してるし、backgroundに回ることもないので、Enable制御したいボタンをStaticにするのに問題はなさそうに見えるのですが、いつ、何が現金でメモリ不足になって、Activityが破棄されてるかはわかりませんものね。 さて、どうしたものか。もう少し悩んでみます。 P.S. 実は、最初はServiceでコーディングしてたのですが、Beaconを受信したときにCallされるべきメソッドが、さっぱりCallされず、原因もわからないので挫折しました。 Alt Beavon Libraryは、Beaconを扱うLibraryとしてはメジャーなのですが、詳細に公開されているサンプルプログラムが動かないとお手上げです┐('~`;)┌
hoshi-takanori

2021/05/10 14:58

ごめんなさい、自分は Bluetooth や Beacon には詳しくないので、Android の一般論しか分からないです。 この質問のタイトルだとその辺に詳しい人がいてもスルーしてしまうと思うので、質問を編集してタイトルを変更するか、この質問は一旦クローズして Beacon の処理に関する質問として仕切り直した方がいいかも。 なお、その際、コードは markdown の機能を利用して貼ってくれると助かります。 https://teratail.com/help/question-tips#questionTips3-5-1
dotsuru

2021/05/10 15:02

遅くまで付き合っていただきありがとうございます。 他の人はどうやってコードを見やすく書いているのかわからなかったので、助かりました。 明日、改めて修正してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問