I'm trying to write an app that will start casting the screen from an Android phone to a TV via miracast. I'm using an HDMI dongle since the TV in question doesn't natively support miracast. I have been trying the code here, but it needs an Application ID which I have got following these steps. My question is, the instructions seem to indicate that I need to register the miracast dongle so it will talk to an unpublished 'debug' app. However, only Google Cast devices are mentioned and that isn't the same protocol as miracast. Do I still need to register the dongle?
Is there a simpler way of programmatically casting to a device via miracast? A requirement is no user interaction, so I can't just display a cast button.
I'm using Android 5.1 if that's relevant.
EDIT: After further research, I realized that Google Cast uses a completely different protocol from Miracast, and thus all the talk of registering the dongle is irrelevant. No registration is required at all to do Miracast in Android. The issue is the API is hidden, see my answer below for details.
So this is possible, but only on custom versions of Android due to permission problems.
What you need to use
The hidden part of the WifiDisplay API makes it all possible. This file contains examples of how to use the API to cast the display. It appears that Google will release it publicly at some point, although it's still hidden in the latest master of API 23 as far as I can see.
How to access the hidden API
To use hidden APIs, this guide(mirror here) provides a good introduction. If you're using API 22+ however, then that guide won't work as the format of android.jar has changed and classes.dex has been split across multiple files. So this advice is more accurate in that case. Note that the postscript about framework-classes2.dex must also be done; it isn't optional.
The latest version of the dex2jar tool fails to turn the .dex file from API 22 into a jar. The solution is mentioned by the author here. I opted to patch the tool instead of changing the dex, as that didn't work for me. Simply change the line the author mentions from throwing a RuntimeException to:
return TypeClass.INT;
How to get permission to use the hidden API
Once that is all done, the next step is giving your app the CONFIGURE_WIFI_DISPLAY permission. Unfortunately, as you can see here, it has system-level protection. This means that your app must be signed by the same key as the system to use this permission. So unless you have Google's private key, you can't have your app run on normal Android phones. My solution was to build a custom version of CyanogenMod(using this guide), with the permission changed from 'system' to 'normal'. This eliminates the need to bother with signing anything. I also did the same for the CONTROL_WIFI_DISPLAY permission. Whilst I'm not entirely sure this is necessary, it doesn't hurt. Both these permissions are located in frameworks/base/core/res/AndroidManifest.xml. Change the lines 2161-2169 from:
<permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY"
android:protectionLevel="signature" />
<permission android:name="android.permission.CONTROL_WIFI_DISPLAY"
android:protectionLevel="signature" />
To:
<permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY"
android:protectionLevel="normal" />
<permission android:name="android.permission.CONTROL_WIFI_DISPLAY"
android:protectionLevel="normal" />
Then build CyanogenMod as normal. I can confirm this does work, but this limits your app to running on devices which have this custom version of CyanogenMod installed. Furthermore, installing CyanogenMod on an Android phone will generally invalidate the warranty.
try {
startActivity(new Intent("android.settings.CAST_SETTINGS"));
return;
} catch (Exception exception1) {
Toast.makeText(getApplicationContext(), "Device not supported", Toast.LENGTH_LONG).show();
}
hope this will help you, done screen mirroring with the cast settings, it uses your device's cast service. but you have to connect with same wifi both device and tv.
Related
I am trying to build an app, as a self project, to understand permissions in detail. There are certain permissions, such as 'Bluetooth Connect' that was introduced in Android version 12 (API 31). Now if I am building an app with multiple features, say some of the features were introduced in the first version of Android, but some of them were introduced in the last version, do I have a method to check whether said permission exists in Android? The idea is to remove or restrict those features which are using APIs not defined and still have the app run on all phones.
For example, In my tests, I have noticed the permission when checked, using the ContextCompat.checkSelfPermission method, come back as 'Not granted' for permissions that are supposed to be undefined. Essentially, I want to know if there is a method of knowing whether the permissions are 'undefined'.
Additionally, I have seen some research papers go into the Android system logs and retrieve information. For example - . This is from the paper: Sleeping android: the danger of dormant permissions
I've tried to use ADB logcat to read the log files but not only is it very difficult, it doesn't say anything similar. Am I doing it wrong or was there an update which removed the information?
Even if I can see whether the permission exists or not via logs would be helpful.
Lint is set up to check this for you at compile time. It will force you to check that the SDK version is high enough to check for whichever permission you’re trying to use. For instance, if your minSdkVersion is lower than the version in which a permission constant was introduced, it will be a compile error to use that constant without wrapping it in an if statement that makes sure the SDK version on the device is high enough for it to exist.
I’m not sure how you have defeated this mechanism except that maybe you have compiled the app with Lint disabled.
The paper you linked is absolutely ancient. Lint probably didn’t help you with this back then.
My app uses WebView. As of L-preview, there is a new feature filter introduced:
FEATURE_WEBVIEW. Declares that your app must only be installed on devices that fully implement the android.webkit.* APIs. Example:
<uses-feature android:name="android.software.webview" android:required="true" />
Source: http://developer.android.com/preview/api-overview.html#Manifest
I would like to understand the impact and the reason of this feature filter.
Which devices won't implement full android.webkit.* API?
If I add this line into my AndroidManifest.xml, I expect my app will still be available for Android 2.3-4.4. Is that true?
Which devices won't implement full android.webkit.* API?
Android Wear, and perhaps others.
If I add this line into my AndroidManifest.xml, I expect my app will still be available for Android 2.3-4.4. Is that true?
It should be.
I have added the following line into the manifest file but Play Store still shows Microphone in the features and it also says "XX devices removed" for the new APK file. (because of the microphone requirement)
<uses-feature android:name="android.hardware.MICROPHONE" android:required="false"/>
What can be the problem?
You still are requesting that you are using the feature but saying the device does not need the feature to use the app.
therefore the feature will show up because you still use it even though you dont require it.
If you dont want it to show then dont use the microphone
Most likely this is because you're using android.hardware.MICROPHONE instead of android.hardware.microphone. Hardware features are all lowercase.
Since it's not finding a matching <uses-feature> tag, it uses the implicit feature from the RECORD_AUDIO permission.
This is my problem:
I have an application that requires a certain persmission (Write-SMS) that will of course only function on phones. Now, the app requires that permission for a feature that will be disabled on tablet versions but it won't let users install the app on tablets.
I guess my question is this:
Can I easily create a second manifest for the tablet version, that will be roughly the same as the phone version but without the persmission?
If I'm doing so, is there a way to check what manifest version is being used? I might want to add features to the tablet version that are tablet exclusive and vice versa.
All of course preferibly in one apk, that gets exported and signed once. Thanks for your help in advance!
Simple add:
<uses-feature android:name="android.hardware.telephony" android:required="false" />
To your manifest. The SMS permission automatically asks for a Telephony feature. Adding this tells android that even though you ask for this feature, you don't need it.
Be sure to add an if-else check to see if you can sens SMS from the device before doing so.
I think you must check it in the actual method itself, because permissions can be optional or compulsory, but that's it, not distinguishable for different devices..
I am just wondering how to enable/disable 3G/2G using the Android SDK and not just intenting to the 3G settings page. Thanks. Also is there a way to do the same thing, but with GPS. Thanks!
There is no exported to the SDK functionality to switch between 2G and 3G. For a given device you could probably figure out the private functionality, but it wouldn't work unless the app was signed with the system key.
You can disable the radios though, by turning on airplane mode.
And you might be able to make a shortcut to open the appropriate settings activity directly, instead of going through a few levels of menus to get there.
If you make your own build, you can presumably add the capability you really want, but that's likely not useful to anyone but yourself.
Edit: further detail - to understand how it works, look at the settings menu code (default version, a given device will differ):
http://android.git.kernel.org/?p=platform/packages/apps/Phone.git;a=blob;f=src/com/android/phone/Settings.java;hb=HEAD
Edit: AOSP is no longer served from kernel.org. A browsable mirror of
the current phone repository is at
https://github.com/android/platform_packages_apps_phone however due to
evolution of code organization there is no longer a Settings.java
there. One might either use git to reconstruct the version above from
this repository, or else try to figure out where the code has migrated
to in current releases.
You would need to find out the implementation specific set of NT_MODE_ constants you wish to toggle between. And you need to be able to write to secure settings, which requires being signed with the system key. Unless it's a custom build, you probably don't have access to that.
You cannot enable or disable any of these from an SDK application.