Search code examples
androidandroid-activityscreen-orientation

Can I get other application's available screen orientation in android?


I has a plan to develop screen orientation service in android to allow upside down portrait in some phone. Mine is Nexus6 for instance, cannot rotate upside down from auto rotation

I was using other rotation control app. And it missing one feature I need

I want to allow force rotation from sensor. But limit to portrait or landscape by the app's preferred orientation. If the app design for portrait mode it can go 0 or 180 degree but not 90 or 270 and vise versa

All the app I used cannot set like that. It force landscape app to be portrait when the sensor align downward and the result was so ugly

To do that I think I need to get ApplicationInfo or something alike and get the value of "android:screenOrientation" that app was set in its manifest

Is it possible?

ps. This is the sample of service I want to develop

https://play.google.com/store/apps/details?id=com.pranavpandey.rotation&hl=en


Solution

  • You can read the Manifest file of other app :

    PackageManager pm = getPackageManager();
    List<ApplicationInfo> apps = pm.getInstalledApplications(PackageManager.GET_META_DATA | PackageManager.GET_SHARED_LIBRARY_FILES);
    for(ApplicationInfo app : apps){
        try {
            ZipFile apk = new ZipFile(app.publicSourceDir);
            ZipEntry manifest = apk.getEntry("AndroidManifest.xml");
            if (manifest != null){
                byte[] binaryXml = toByteArray(apk.getInputStream(manifest));
                // decode binary Xml
            }
            apk.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static byte[] toByteArray(InputStream in) throws IOException {
        try {
            byte[] buf = new byte[1024*8];
            try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
                int len;
                while ((len = in.read(buf)) != -1) {
                    bos.write(buf, 0, len);
                }
                return bos.toByteArray();
            }
        } finally {
            in.close();
        }
    }
    

    The "problem" is that you will get the binary xml which is not just a string converted to a byte array ; it's a compressed format for xml files.

    You need to decompress this array to get a String then you can parse it to get the value of screenOrientation.

    I found this GIST that does the job but it raises an IndexOutOfBounds error in some cases... The hardest part (decoding the binray xml) is done, you just have to fix the exception problem.

    Then you would get the String this way :

    String xml = AndroidXMLDecompress.decompressXML(binaryXml);