Last active
December 22, 2015 03:58
-
-
Save esperia/6413572 to your computer and use it in GitHub Desktop.
アプリケーションの最上位ビューを取得する糞Tipsアプリ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.esperia09.android.test_android.reflection; | |
import java.lang.reflect.Field; | |
import android.app.AlertDialog; | |
import android.app.AlertDialog.Builder; | |
import android.app.Dialog; | |
import android.graphics.Color; | |
import android.os.AsyncTask; | |
import android.os.Bundle; | |
import android.support.v4.app.DialogFragment; | |
import android.support.v4.app.FragmentActivity; | |
import android.text.TextUtils; | |
import android.util.Log; | |
import android.view.Gravity; | |
import android.view.Menu; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.view.WindowManager; | |
import android.view.WindowManager.LayoutParams; | |
import android.widget.TextView; | |
import android.widget.Toast; | |
public class RootViewsActivity extends FragmentActivity { | |
private static final String TAG = RootViewsActivity.class.getSimpleName(); | |
private static final String MENU_ADD_TEXT = "TextView追加"; | |
private static final String MENU_SHOW_DIALOG = "ダイアログ表示"; | |
private static final String MENU_SHOW_TOAST = "トースト表示"; | |
private WindowWatchTask mTask; | |
private TextView mTextView; | |
private TextView mWindowTextView; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
mTextView = new TextView(this); | |
setContentView(mTextView); | |
} | |
@Override | |
protected void onResume() { | |
super.onResume(); | |
mTask = new WindowWatchTask() { | |
@Override | |
protected void onProgressUpdate(Void... values) { | |
View[] views = getViews(getWindowManager()); | |
if (views != null) { | |
StringBuilder sb = new StringBuilder(); | |
sb.append("count=").append(views.length).append("\n"); | |
for (View v : views) { | |
sb.append(v).append("\n"); | |
} | |
mTextView.setText(sb.toString()); | |
} | |
} | |
}; | |
mTask.execute(); | |
} | |
@Override | |
protected void onPause() { | |
super.onPause(); | |
mTask.cancel(false); | |
mTask = null; | |
} | |
@Override | |
public boolean onCreateOptionsMenu(Menu menu) { | |
menu.add(MENU_ADD_TEXT); | |
menu.add(MENU_SHOW_DIALOG); | |
menu.add(MENU_SHOW_TOAST); | |
return super.onCreateOptionsMenu(menu); | |
} | |
@Override | |
public boolean onOptionsItemSelected(MenuItem item) { | |
CharSequence title = item.getTitle(); | |
if (TextUtils.equals(MENU_ADD_TEXT, title)) { | |
// TextViewを追加 | |
WindowManager wm = getWindowManager(); | |
if (mWindowTextView != null) { | |
wm.removeView(mWindowTextView); | |
} | |
mWindowTextView = new TextView(this); | |
mWindowTextView.setBackgroundColor(Color.WHITE); | |
mWindowTextView.setText("むおおおお"); | |
mWindowTextView.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
WindowManager wm = getWindowManager(); | |
wm.removeView(mWindowTextView); | |
mWindowTextView = null; | |
} | |
}); | |
LayoutParams params = createParams(); | |
wm.addView(mWindowTextView, params); | |
} else if (TextUtils.equals(MENU_SHOW_DIALOG, title)) { | |
// ダイアログ表示 | |
new DialogFragment() { | |
@Override | |
public Dialog onCreateDialog(Bundle savedInstanceState) { | |
Builder builder = new AlertDialog.Builder(getActivity()); | |
builder.setMessage("ダイアログ"); | |
builder.setPositiveButton("ok", null); | |
return builder.create(); | |
} | |
}.show(getSupportFragmentManager(), "MyDialog"); | |
} else if (TextUtils.equals(MENU_SHOW_TOAST, title)) { | |
Toast.makeText(this, "トースト表示", Toast.LENGTH_LONG).show(); | |
} | |
return super.onOptionsItemSelected(item); | |
} | |
/** | |
* WindowManagerのビューのリストを取得する | |
*/ | |
private View[] getViews(WindowManager wm) { | |
try { | |
Field declaredField = wm.getClass().getDeclaredField("mGlobal"); | |
declaredField.setAccessible(true); | |
Object windowManagerGlobalInstance = declaredField.get(wm); | |
Field viewsField = windowManagerGlobalInstance.getClass().getDeclaredField("mViews"); | |
viewsField.setAccessible(true); | |
Object object = viewsField.get(windowManagerGlobalInstance); | |
View[] views = View[].class.cast(object); | |
return views; | |
} catch (Exception e) { | |
Log.e(TAG, "メソッド呼び出しに失敗", e); | |
} | |
return null; | |
} | |
private LayoutParams createParams() { | |
LayoutParams params = new WindowManager.LayoutParams(); | |
params.width = WindowManager.LayoutParams.WRAP_CONTENT; | |
params.height = WindowManager.LayoutParams.WRAP_CONTENT; | |
params.gravity = Gravity.LEFT | Gravity.TOP; | |
return params; | |
} | |
private static class WindowWatchTask extends AsyncTask<Void, Void, Void> { | |
private static final int TIME_DST = 500; // ms | |
@Override | |
protected Void doInBackground(Void... params) { | |
while (!isCancelled()) { | |
publishProgress(); | |
try { | |
Thread.sleep(TIME_DST); | |
} catch (InterruptedException e) { | |
cancel(false); | |
} | |
} | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment