こんばんは、ひよつこです。
今回もお世話になります。
現在作成中のビュアーアプリもどきとは関係のない話になりますが、よろしくお願いします。
AndroidのServiceはバックグラウンドで動作するため、
WindowManager.LayoutParamsの設定を変更することで
透明な画面を最前面に常時表示させることができる...ハズです。
そこで今回はそれを利用しIntentで渡した情報を元にTextViewを作成します。
そして、そのTextViewを透明な画面に組み込みます。
それによって、画面の最前面には常にユーザーが設定した文字を表示することができます。
そこで、そのようなプログラムを組んでみたのですが、文字を表示してからしばらく経つと、
表示されていた文字が消え、Intentからユーザーの設定した文字列が取得できなくなってしまいます。
ServiceのonDestroy()は呼ばれていないようなので全く原因がわかりません。
説明が下手でスミマセンがよろしくお願いします。
[android]透明な画面を常時表示する
Re: [android]透明な画面を常時表示する
正しい前面表示の方法を知りたいということですか?
ネットで見付かる前面表示のサンプルプログラムでも同じように表示が消えるとか?
それともひよつこさん作ったプログラムだけで発生するのでしょうか。
後者であればコードを提示していただかないとどうしようもないですが。
ネットで見付かる前面表示のサンプルプログラムでも同じように表示が消えるとか?
それともひよつこさん作ったプログラムだけで発生するのでしょうか。
後者であればコードを提示していただかないとどうしようもないですが。
-
ひよつこ
Re: [android]透明な画面を常時表示する
返信ありがとうございます。
参考になればと思いコードを提示します。
以上に提示したのがServiceのコードです。
どうかよろしくお願いします。
参考になればと思いコードを提示します。
private LinearLayout layout;
private WindowManager wManager;
private WindowManager.LayoutParams params;
private NotificationManager nManager;
private Notification notification;
private PendingIntent contentIntent;
private Intent intent;
@Override
public void onStart(Intent _intent, int startId){
super.onStart(intent,startId);
nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if(_intent != null)
this.intent = _intent;
contentIntent =PendingIntent.getActivity(this, 0, new Intent(this,メインアクティビティークラス), 0);
wManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(0, 0));
//Notificationの作成
notification = new Notification(画像Resourceのパス,"文字を表示します",System.currentTimeMillis());
notification.setLatestEventInfo(getApplicationContext(),"設定","文字の設定",contentIntent);
//透明な画面の作成
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
TextView text = new TextView(this);
text.setText(this.intent.getStringExtra("text"));
layout.addView(text);
nManager.notify(R.string.app_name, notification);
wManager.addView(layout, params);
}
@Override
public void onDestroy(){
super.onDestroy();
wManager.removeView(layout);
nManager.cancelAll();
}
どうかよろしくお願いします。
Re: [android]透明な画面を常時表示する
断片的なコードではほとんど何も分からないですが。
とりあえず「文字を表示してからしばらく経つと」というのは放っておいたServiceから文字が消えるということではないようですね。
Serviceを起動→通知領域をタップ→Activity起動→(※)→Serviceを起動→…
という動作を繰り返しているうちに※のところで渡しているはずの文字列が渡らないということでしょうか。
だとしたら問題はActivityのほうにあると思います。
デバッガを使って、あるいはログ出力して、ActivityがIntentにセットしている文字列をチェックしてみてください。
Intentにセットするときには既に消えていたりしないですか?
とりあえず「文字を表示してからしばらく経つと」というのは放っておいたServiceから文字が消えるということではないようですね。
Serviceを起動→通知領域をタップ→Activity起動→(※)→Serviceを起動→…
という動作を繰り返しているうちに※のところで渡しているはずの文字列が渡らないということでしょうか。
だとしたら問題はActivityのほうにあると思います。
デバッガを使って、あるいはログ出力して、ActivityがIntentにセットしている文字列をチェックしてみてください。
Intentにセットするときには既に消えていたりしないですか?
-
ひよつこ
Re: [android]透明な画面を常時表示する
返信ありがとうございます。
アプリの状態が正しく伝わっていないようなのでもう一度説明させて頂きます。
まず今回のアプリのActivityはユーザーの設定した文字列をIntentに付けて
Serviceを起動する処理のみを行うもので、その文字列も正しくServiceに渡せています。
問題はServiceによって画面の最前面に表示された文字列が消えるという点です。
というのは、Serviceを起動してからしばらくは文字列が表示されているのですが、
他のActivityを起動したり、画面をOFFにしてしばらくすると表示されていた文字列が
消えてしまうのです。
また、文字列が消えてしまってから再びServiceのonStart()が呼ばれるようで、
Intentから文字列が取得できないと言われます。
わかりにくい説明だと思いますが、よろしくお願いします。
アプリの状態が正しく伝わっていないようなのでもう一度説明させて頂きます。
まず今回のアプリのActivityはユーザーの設定した文字列をIntentに付けて
Serviceを起動する処理のみを行うもので、その文字列も正しくServiceに渡せています。
問題はServiceによって画面の最前面に表示された文字列が消えるという点です。
というのは、Serviceを起動してからしばらくは文字列が表示されているのですが、
他のActivityを起動したり、画面をOFFにしてしばらくすると表示されていた文字列が
消えてしまうのです。
また、文字列が消えてしまってから再びServiceのonStart()が呼ばれるようで、
Intentから文字列が取得できないと言われます。
わかりにくい説明だと思いますが、よろしくお願いします。
Re: [android]透明な画面を常時表示する
メンバに保持しておいたIntentの中から文字列が消えるということですか?
Intentは起動パラメータの受け渡しに使うものなので、参照を保持しておいてストレージのように使うことはできないのではないでしょうか。
調べてもそのへん公式に書かれたドキュメントは見付かりませんがわたしは引数で受け取ったメソッドの中でしか有効でないと考えます。
Serviceが再起動されるときにonStratの引数のIntentはnullなので、nullでなかったら文字列を取得すれば良いだけなのでは?
Intentは起動パラメータの受け渡しに使うものなので、参照を保持しておいてストレージのように使うことはできないのではないでしょうか。
調べてもそのへん公式に書かれたドキュメントは見付かりませんがわたしは引数で受け取ったメソッドの中でしか有効でないと考えます。
Serviceが再起動されるときにonStratの引数のIntentはnullなので、nullでなかったら文字列を取得すれば良いだけなのでは?
-
ひよつこ
Re: [android]透明な画面を常時表示する
返信ありがとうございます。
調べてみたところServiceの再起動の時、onDestroy()は呼ばれず、
onCreate()、onStart()が呼ばれService内の全ての変数が初期化されていました。
そのため、必然的にServiceは表示するはずの文字列がわからなくなってしまうようです。
いったい、どこに問題があるのでしょうか。
調べてみたところServiceの再起動の時、onDestroy()は呼ばれず、
onCreate()、onStart()が呼ばれService内の全ての変数が初期化されていました。
そのため、必然的にServiceは表示するはずの文字列がわからなくなってしまうようです。
いったい、どこに問題があるのでしょうか。
Re: [android]透明な画面を常時表示する
AndroidはServiceにしろActivityにしろシステムの都合でインスタンスが破棄される仕様で基本的に考慮して作成すべきです。
調べたところ、onStartCommandでSTART_REDELIVER_INTENTを返すと再起動時にnullではなく前回と同じIntentを受け取れるらしいです。
この件に関してはIntentが取れれば良いのでこれで解決するかと思います。
onStratはAndroidバージョン2以降で非推奨(廃止予定)なのでonStartCommandを使いましょう。
Activityでもシステムの都合で破棄されるときonDestroyが呼ばれないことがあるそうです。
onDestroyは信用しないでデータ保存などの重要な処理は含めないようにしましょう。
調べたところ、onStartCommandでSTART_REDELIVER_INTENTを返すと再起動時にnullではなく前回と同じIntentを受け取れるらしいです。
この件に関してはIntentが取れれば良いのでこれで解決するかと思います。
onStratはAndroidバージョン2以降で非推奨(廃止予定)なのでonStartCommandを使いましょう。
Activityでもシステムの都合で破棄されるときonDestroyが呼ばれないことがあるそうです。
onDestroyは信用しないでデータ保存などの重要な処理は含めないようにしましょう。
-
ひよつこ
Re: [android]透明な画面を常時表示する
返信ありがとうございます。
onStartCommand()の戻り値をSTART_REDELIVER_INTENTにしたら、
無事Intentから文字列を取得できました。
Serviceは再起動されることを前提に作るべきなのですね。
勉強になりました。
次回もよろしくお願いします。
onStartCommand()の戻り値をSTART_REDELIVER_INTENTにしたら、
無事Intentから文字列を取得できました。
Serviceは再起動されることを前提に作るべきなのですね。
勉強になりました。
次回もよろしくお願いします。