2017年5月9日 星期二
2017年3月21日 星期二
Set window flag by reflection
Reference:
http://stackoverflow.com/questions/10555407/android-how-to-get-an-instance-of-a-member-field-via-reflectionhttp://stackoverflow.com/questions/32218419/how-i-can-access-inner-class-variable-value-using-reflection-in-java
http://www.qingpingshan.com/m/view.php?aid=125698
Description:
為了讓 system dialog可以在 multi user裡顯示,必須要設定 PRIVATE_FLAG_SHOW_FOR_ALL_USERS flag,但是因為 setPrivateFlags是 Window.java的 hide API,PRIVATE_FLAG_SHOW_FOR_ALL_USERS是 WindowManager的 hide variable,除了直接 import framework.jar之外,還可以透過 reflection的機制Code Snippet:
public static final int FRAMEWORK_PRIVATE_FLAG_SHOW_FOR_ALL_USERS = 0x00000010; public static void setShowForAllUsers(Window window) { LogTool.d(TAG, "setShowForAllUsers"); Class<?> windowClass = null; Class<?> windowManagerClass = null; try { try { windowClass = Class.forName("android.view.Window"); windowManagerClass = Class.forName("android.view.WindowManager"); } catch (ClassNotFoundException e) { e.printStackTrace(); } try { Method method = windowClass.getDeclaredMethod("setPrivateFlags", int.class, int.class); method.setAccessible(true); try { try { int allUsersFlag = FRAMEWORK_PRIVATE_FLAG_SHOW_FOR_ALL_USERS; Class<?>[] classes = windowManagerClass.getDeclaredClasses(); for(Class innerClass: classes){ if(innerClass.getName().contains("LayoutParams")){ Field field = innerClass.getDeclaredField("PRIVATE_FLAG_SHOW_FOR_ALL_USERS"); field.setAccessible(true); allUsersFlag = field.getInt(window.getAttributes()); break; } } LogTool.d(TAG, "allUsersFlag: " + allUsersFlag + " ; hex: " + Integer.toHexString(allUsersFlag)); method.invoke(window, allUsersFlag, allUsersFlag); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (IllegalAccessException e) { e.printStackTrace(); } } catch (NullPointerException e1) { e1.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch(NoSuchFieldException nsfe){ nsfe.printStackTrace(); } }
2017年2月20日 星期一
Android 6.0+ 請求 SYSTEM_ALERT_WINDOW權限
Reference:
http://stackoverflow.com/questions/32652533/android-system-overlay-windowhttp://caiyao.name/2016/03/02/Android-6-0%E8%BF%90%E8%A1%8C%E6%97%B6%E6%9D%83%E9%99%90%E5%B0%8F%E7%BB%93/
Error message:
Unable to add window android.view.ViewRoot$W@XXXXXXXX — permission denied for this window typeCode snippet:
在 Android 6.0+ (SDK 23+) 用 TYPE_SYSTEM_ALERT,即使在 Manifest裡有宣告 permission<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />依舊會出現上面的 Error message.
這時候要先透過 Settings.canDrawOverlays檢查 app是否有權限,如果沒有的話,發出 Settings.ACTION_MANAGE_OVERLAY_PERMISSION 的 Intent,讓使用者打開權限
@Overrideprotected void onResume() { super.onResume(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if(!Settings.canDrawOverlays(this)){ requestAlertWindowPermission(); } else{ // do something } } else{ // do something } }
private static final int REQUEST_CODE = 1; private void requestAlertWindowPermission() { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.setData(Uri.parse("package:" + getPackageName())); startActivityForResult(intent, REQUEST_CODE); } @Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Settings.canDrawOverlays(this)) { Log.i(TAG, "onActivityResult granted");// do something } else{ Log.i(TAG, "onActivityResult not granted"); } } } }
2017年2月6日 星期一
Turning on screen and keep screen lon
Reference:
http://stackoverflow.com/questions/2891337/turning-on-screen-programmaticallyAdvance:
Turn on screen and dismiss keyguard
http://stackoverflow.com/questions/30246425/turning-on-screen-from-receiver-service
Code snippet:
在需要打開螢幕的地方加入下面的 codeWakeLock wl = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
wl.acquire();
在離開前要記得釋放 wake lock,以免螢幕保持開啟,造成耗電的問題
wl.release();
Note:
釋放 (release)的 wake lock要和獲取 (acquire)的是同一個,不要再重新建立一個新的wake lock,否則釋放 wake lock時會不能正常運作
2017年1月16日 星期一
解決 Android minSDK支援的問題
Reference:
說明:
要解決minSDK支援的問題,可以使用Lint來找出哪些高版本API並不支援在低版本.
在Android Sutdio中
選擇功能表Analyze—>Configure Current File
Analysis—>Configure Inspections 清空所有的檢查項,然後如下圖勾選Calling
new methods on older versions 和 Using inlined
constants on older versions
2016年6月3日 星期五
Detect if TextVIew is ellipsized
Code snippet
//Hide/Show More buttion
final TextView detail = (TextView) findViewById(R.id.detail);
final TextView more = (TextView) findViewById(R.id.more);
ViewTreeObserver vto = detail.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
ViewTreeObserver observer = detail.getViewTreeObserver();
observer.removeOnPreDrawListener(this);
String text = detail.getText().toString();
String layoutText = detail.getLayout().getText().toString();
more.setVisibility((!text.equals(layoutText)) ? View.VISIBLE:View.INVISIBLE);
return true;
}
});
//Hide/Show More buttion
final TextView detail = (TextView) findViewById(R.id.detail);
final TextView more = (TextView) findViewById(R.id.more);
ViewTreeObserver vto = detail.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
ViewTreeObserver observer = detail.getViewTreeObserver();
observer.removeOnPreDrawListener(this);
String text = detail.getText().toString();
String layoutText = detail.getLayout().getText().toString();
more.setVisibility((!text.equals(layoutText)) ? View.VISIBLE:View.INVISIBLE);
return true;
}
});
2016年5月26日 星期四
Recyclerview inside ScrollView not scrolling smoothly
Method 1:
Reference:
http://stackoverflow.com/questions/33143485/recyclerview-inside-scrollview-not-scrolling-smoothlyIllustration:
RecyclerView view = (RecyclerView) findViewById(R.id.myrecycler);view .setNestedScrollingEnabled(false);
Drawback:
OutOfMemory when there are many bitmap in the RecyclerView
Method 2:
Wrap all the component into the RecyclerView
訂閱:
意見 (Atom)


