I was updating one of my clients app, and testing it how it behaves on Android O (API 26). The app requires permissions to draw over system windows (android.permission.SYSTEM_ALERT_WINDOW). On Android 6 (API 23) and up, you are obligated to request ‘special’ permissions while the app is running.
The ‘SYSTEM_ALERT_WINDOW’ permission is a special permission that breaks the rules set by the new permission model available on Android 6 (API 23) and up. It’s request involves calling Settings.canDrawOverlays() and if it returns ‘false‘ starting ‘Settings‘ where the user can choose to grant your app the ability to draw overlays or not.
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M){// On API 23 and later ask the user to grant us permission to draw system overlay// windows.if(!Settings.canDrawOverlays(this)){
Intent intent =new Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:"+ getPackageName()));
startActivityForResult(intent, REQUEST_PERMISSION_SYSTEM_OVERLAY_RESULT);}}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
// On API 23 and later ask the user to grant us permission to draw system overlay
// windows.
if (!Settings.canDrawOverlays(this))
{
Intent intent = new Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_PERMISSION_SYSTEM_OVERLAY_RESULT);
}
}
There is a bug with Settings.canDrawOverlays() (only) on API 26 where it will always return ‘false’ disregarding the actual user decision. The workaround provided here is a bit ugly, but does not involves restarting the app (which will be quite annoying for the user) after the permission is granted.
The code below first checks the result of System.canDrawOverlays() if it returns ‘true’ it continues with the rest of the application flow. If it returns ‘false’ a check if we are running on Android O (API 26) is performed. If that’s the case, we are calling our ‘workaround’ method.
The ‘workaround’ method tries to add an invisible overlay window on the screen, and if that’s OK we assume that we have a permission to draw overlays, else an exception is thrown.
@Override
protectedvoid onActivityResult(int requestCode, int resultCode, Intent data){super.onActivityResult(requestCode, resultCode, data);if(Build.VERSION.SDK_INT< Build.VERSION_CODES.M)return;if(requestCode == REQUEST_PERMISSION_SYSTEM_OVERLAY_RESULT){if(Settings.canDrawOverlays(this)){ m_permissionSystemOverlayWindowGranted =true;if(m_permissionReadPhoneStateGranted && m_permissionProcessOutgoingCallsGranted){ startService(new Intent(this, EstatePlusService.class)); m_layoutNoPermissions.setVisibility(View.INVISIBLE); m_progressBar.setVisibility(View.INVISIBLE); m_layoutLogin.setVisibility(View.VISIBLE);}}elseif(Build.VERSION.SDK_INT== Build.VERSION_CODES.O){// NOTE: This is a workaround to fix the bug in Android O where the // Settings.canDrawOverlays() will always return 'false' if(canDrawOverlays(this)) { m_permissionSystemOverlayWindowGranted = true; if(m_permissionReadPhoneStateGranted && m_permissionProcessOutgoingCallsGranted) { startService(new Intent(this, EstatePlusService.class)); m_layoutNoPermissions.setVisibility(View.INVISIBLE); m_progressBar.setVisibility(View.INVISIBLE); m_layoutLogin.setVisibility(View.VISIBLE); } } } } } /** * Workaround for Android O */ public static boolean canDrawOverlays(Context context) { try { WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); if (windowManager == null) { return false; } final View viewToAdd = new View(context); WindowManager.LayoutParams params = new WindowManager.LayoutParams( 0, 0, android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O ?
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY: WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
viewToAdd.setLayoutParams(params);
windowManager.addView(viewToAdd, params);
windowManager.removeView(viewToAdd);returntrue;}catch(Exception e){
e.printStackTrace();}returnfalse;}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return; if(requestCode == REQUEST_PERMISSION_SYSTEM_OVERLAY_RESULT) { if(Settings.canDrawOverlays(this)) { m_permissionSystemOverlayWindowGranted = true; if(m_permissionReadPhoneStateGranted && m_permissionProcessOutgoingCallsGranted) { startService(new Intent(this, EstatePlusService.class)); m_layoutNoPermissions.setVisibility(View.INVISIBLE); m_progressBar.setVisibility(View.INVISIBLE); m_layoutLogin.setVisibility(View.VISIBLE); } } else if(Build.VERSION.SDK_INT == Build.VERSION_CODES.O) { // NOTE: This is a workaround to fix the bug in Android O where the // Settings.canDrawOverlays() will always return 'false' if(canDrawOverlays(this)) { m_permissionSystemOverlayWindowGranted = true; if(m_permissionReadPhoneStateGranted && m_permissionProcessOutgoingCallsGranted) { startService(new Intent(this, EstatePlusService.class)); m_layoutNoPermissions.setVisibility(View.INVISIBLE); m_progressBar.setVisibility(View.INVISIBLE); m_layoutLogin.setVisibility(View.VISIBLE); } } } } } /** * Workaround for Android O */ public static boolean canDrawOverlays(Context context) { try { WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); if (windowManager == null) { return false; } final View viewToAdd = new View(context); WindowManager.LayoutParams params = new WindowManager.LayoutParams( 0, 0, android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O ?
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
viewToAdd.setLayoutParams(params);
windowManager.addView(viewToAdd, params);
windowManager.removeView(viewToAdd);
return true;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
I currently work on connecting my PC XT clone to my home network. But why? What are the benefits of connecting a 30 years old machine to the network?
It gives me one more reason to fire up my Pravetz 16 ๐ It would be cool chatting on IRC on that monochrome (green and black) monitor, running an FTP server for file transfers between the PC XT and other PC’s on the network or an HTTP server, etc…
The PC XT will be connected to the network using the so called ‘Thin Ethernet‘ (10Base2) using a coaxial cable and BNC connectors. Why? Because finding 8-bit ISA compatible Ethernet card is extremely rare nowadays, and chances to find one with RJ45 connector are close to zero.
My long search for 8-bit ISA network adapter finally gave results and for 10$ I’m an owner of PLUS & PLUS PCN-001. Plus & Plus PNC-001 Ethernet adpater
It’s 10Mbps Ethernet card with support for coaxial and DIX transceiver wiring. It has an option for a boot ROM but mine don’t have a chip. This card is a clone of AMERICAN RESEARCH CORPORATION PNC-001, it’s NE1000 compatible and supported by the NE1000 driver for DOS available in the many-other-drivers.zip along with many other packet drives, thanks to Crynwr Software!
After a bit of googling I found the required information on how to configure the adapter here. That exact same information is copy / pasted at the end of this post for future references.
Setting the IRQ to 2, the I/O base address to 200h, and disabling the boot ROM and DMA settings, changing the cable type jumpers from ‘DIX transceiver via DB-15 port’ to ‘RG-58A/U 50ohm coaxial’ I booted the PC, loaded the NE1000 driver
C:\>ne1000 0x7E 2 0x200
C:\>ne1000 0x7E 2 0x200
UPDATE 16/02/2016: I was having problems receiving network packets, changing the IRQ to 5 and I/O base address to 0x280h resolved the problem.
NE1000 packet driver loaded and success! The card is working! 10$ well spend ๐
NOTE: Installation instructions for packet drivers are in INSTALL.DOC (many-other-drivers.zip)
The Ethernet adapter is now configured and working properly. This concludes Part 1 of the series of articles about connecting my PC XT to the network. Later I will review other vital network component. The Surecom Ether Perfect 517T hub with BNC connector.
PLUS & PLUS (AMERICAN RESEARCH CORPORATION) PNC-001 Jumper settings (Information taken from Total Hardware 1999 page on the topic available here.)