AndroidTV and OPEN_DOCUMENT_TREE Intent - android-tv

How do I find out if the ACTION_OPEN_DOCUMENT_TREE intent is supported on Android TV?
Targeting API 32 and using the StorageVolume createOpenDocumentTreeIntent call. I can create the intent, but when I attempt to launch it, I get:
"You don't have an app that can do this message".
My app can do that on Android Phones and Tablets, just not AndroidTV. My storage related permissions are:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
For Android TV support, I have added:
<uses-feature android:name="android.software.leanback"
android:required="false" />
<uses-feature android:name="android.hardware.touchscreen"
android:required="false" />
And my TV Activity is declared as:
<activity
android:exported="true"
android:name="com.connectedway.connectedsmb.TvActivity"
android:label="#string/app_name"
android:theme="#style/Theme.Leanback">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
The app comes up on Android TV fine, but when I try to bring up a picker, it fails with the "You don't have an app..." message. I'm thinking there isn't support for this on AndroidTV, but it could be something else.

It looks like Storage Access Framework is not included in Android TV:
https://issuetracker.google.com/issues/202985150
I guess Android TV, is not quite Android.

Related

Flutter : INSTALL_PARSE_FAILED_MANIFEST_MALFORMED: Failed parse during installPackageLI

My flutter app isn't install on Android 12 version. I tried with android:exported, but nothing work. It's show me this type of error-
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk... 3.3s
Error: ADB exited with exit code 1
Performing Streamed Install
adb: failed to install /Users/abir/Documents/Office
Work/MediMate-App-Old-Version/build/app/outputs/flutter-apk/app.apk: Failure
[INSTALL_PARSE_FAILED_MANIFEST_MALFORMED: Failed parse during installPackageLI:
/data/app/vmdl489268217.tmp/base.apk (at Binary XML file line #125):
io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService: Targeting S+ (version 31 and above)
requires that an explicit value for android:exported be defined when intent filters are present]
Error launching application on sdk gphone64 x86 64.
Here is my AndroidManifest.xml file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="care.example.health">
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- The Agora SDK requires Bluetooth permissions in case users are using Bluetooth devices.-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:label="example"
android:name="${applicationName}"
android:icon="#mipmap/ic_launcher">
<activity
android:exported="true"
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<intent-filter
android:exported="false">
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter
android:exported="false">
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
What did I miss ?
If you get this error message when you try to run your flutter app on android studio emulator, this solved it for me!
Error: ADB exited with exit code 1
Performing Streamed Install
adb: failed to install C:\Users\aasmu\OneDrive\Proskjekt\Flutter_course\flash-chat-flutter\build\app\outputs\flutter-apk\app.apk: Failure [INSTALL_PARSE_FAILED_MANIFEST_MALFORMED: Failed parse during installPackageLI: /data/app/vmdl2080833837.tmp/base.apk (at Binary XML file line #28): co.appbrewery.flash_chat.MainActivity: Targeting S+ (version 31 and above) requires that an explicit value for android:exported be defined when intent filters are present]
1. Locate your androidManifest.xml
In the right corner of android studio where your project files are follow this path:
'your project name'/android/app/src/main/AndroidManifest.xml
Image showing file path in android studio with yellow highelighter
2. In the AndroidManifest.xml file, find this set of code:
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
Image showing the section between the two perpendicular red lines
3. Copy and paste this line somewhere between '<activity' and the next '>'.
android:exported="true"
Image showing the line pasted in between the yellow'<activity' and '<'
Your problem should now be solved!
If your problem persists:
Make sure your flutter doctor checks out, i had mine checked out on everything except Visual studio when i solved this. (type 'flutter doctor' in the android studio terminal)
Check these two things mentioned in this answer. https://stackoverflow.com/a/56417433/14637333
Even I faced the same issue. I'm able to overcome it by adding below code for the particular service directly in the plugin.
android:exported="true"
You can find the plugin code in the below path
your_flutter_sdk_location/.pub-cache/hosted/pub.dartlang.org/package_name
As per your question, your issue is arriving of FlutterFirebaseMessagingService. If you see in log there is already mention that
io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService: Targeting S+ (version 31 and above)
requires that an explicit value for android:exported be defined when intent filters are present]
You just need to delete extra android:exported="false" from intent-filter.
put here as like
<intent-filter >
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
also update plugin, if they are not updated
firebase_core: ^1.16.0
firebase_messaging: ^11.3.0
add this property to as from android 12 its required to be write this for activity and your device has android api level 31 which is android - 12
android:exported="true"
very simple add this line of code android:exported="true" AndroidManifest.xml
location android/app/src/main/AndroidManifest.xml
if none of the solutions above worked, use the forked version of firebase_messaging: ^6.0.16 with android:exported="false".
firebase_messaging:
git:
url: https://github.com/itsAyyazdev/firebase_messaging.git

Xamarin.Forms Android App API Level range on Google Play Store

I'm trying to publish a Xamarin.Forms Android App to the Google Play Store and all is well except the API level is restricted by range. Normally apps will say API 7 and up but mine says 7.1 - 10 (see screenshots) making it "invisible" to device with Android v 11 and up. Naturally, I would like it to just say "7.1 and up"
Any suggestions would be greatly appreciated!
so this is really bizarre. The only way I can "force" it is by specifying a max SdkVersion in the manifest. Shouldn't have to do that (Not even recommended by Google). Perhaps will figure in the future:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="REMOVED" android:versionName="3.14" android:installLocation="auto" android:versionCode="17">
<uses-sdk android:minSdkVersion="26" android:targetSdkVersion="30" android:maxSdkVersion="31" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application android:label="REMOVED" android:icon="#drawable/splashLF" android:allowBackup="false" android:usesCleartextTraffic="false">
<provider android:name="android.support.v4.content.FileProvider" android:authorities="org.REMOVED.REMOVED.provider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/provider_paths" />
</provider>
</application>
</manifest>

error APT2263: unexpected element <queries> found in <manifest>

First I beg your pardon if the problem sounds silly, but I'm a newbie in Xamarin.Forms development.
I created my first app (with a lot of efforts) and I decided to use AppCenter to deploy debug releases to my testers.
Everything went fine till the last month, when I updated packages (dependencies), removed some deprecated one and pushed changes to GIT: from that moment AppCenter can't compile my app anymore, app that's compiled properly on my pc.
If I compile using v10.0 this is the error I get:
/Users/runner/work/1/s/src/StamuraApp/StamuraApp.Android/StamuraApp.Android.csproj"
(PackageForAndroid target) (1) -> (_CreateBaseApkWithAapt2 target) ->
/Users/runner/work/1/s/src/StamuraApp/StamuraApp.Android/obj/Release/android/manifest/AndroidManifest.xml(31):
error APT2263: unexpected element <queries> found in <manifest>.
[/Users/runner/work/1/s/src/StamuraApp/StamuraApp.Android/StamuraApp.Android.csproj]
If I try to compile using v11.0 I get the error:
/Users/runner/work/1/s/src/StamuraApp/StamuraApp.Android/StamuraApp.Android.csproj"
(PackageForAndroid target) (1) -> (_ResolveSdks target) ->
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/Android/Xamarin.Android.Common.targets(819,2):
error XA0000: Could not determine API level for $(TargetFrameworkVersion) of 'v11.0'.
[/Users/runner/work/1/s/src/StamuraApp/StamuraApp.Android/StamuraApp.Android.csproj]
So I understand that AppCenter can't use v11.0, but I don't know what to do with the error.
I searched other questions and most of them talk about Gradle version, but I don't know how to set it in Visual Studio.
AppCenter warns me that
Usage of Android Gradle Plugin 4.1.0+ is not supported at the moment.
Please use any of the earlier versions.
but I don't know how I can solve it.
Is there a way I can fix the issue?
EDITED
My manifest is this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="156" android:versionName="1.10.6" package="com.sefstamura.stamuraapp" android:installLocation="auto">
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="29" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- Push notifications
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
****************** -->
<application android:label="StamuraApp" android:fullBackupContent="#xml/appcenter_backup_rule">
<!-- File provider -->
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/file_paths"></meta-data>
</provider>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
</manifest>
Faced the same issue when I tried to Upgrade My FormsApp to use XamarinForms to 5.0.
Please make sure to install the latest SDK versions on your machine i.e in my case Android 11[API 30]and corresponding build tool versions.
Also, upgrade the VisualStudio to the latest version where the XamarinAndroidSDK version in turn updated to pick the API level it supports.

Xamarin.Forms FCM OnRefereshToken Method not called in release mode Android Device

I have Implemented a Xamarin Pushnotification using FCM and my code looks like
// This service handles the device's registration with FCM.
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class ZCFirebaseIIDService : FirebaseInstanceIdService
{
#region override methods
public override void OnTokenRefresh()
{
var refreshedToken = FirebaseInstanceId.Instance.Token;
App.DeviceToken = FirebaseInstanceId.Instance.Token;
}
#endregion
}
Also I have added all required permission in AndroidManifest and its like
<uses-sdk android:minSdkVersion="14" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="App name" android:icon="#drawable/icon">
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.appname.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/file_paths">
</meta-data>
</provider>
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
</application>
it's perfectly fine in Debug mode but when I run the app in release mode OnTokenRefresh method not even called .
can anyone please suggest me how can I resolve this issue.
There is a known bug in FCM that even I faced when I was implementing the same in my android application
Java.Lang.IllegalStateException: Default FirebaseApp is not initialized in this process
Make sure to call FirebaseApp.initializeApp(Context) first.
Which is a bug that you will also find in the Microsoft xamarin website where it shows the implementation of FCM which you can find here
Also, there is a Bugzilla report on the same here.
Steps to solve the issue:
Xamarin only gives you this:
This is a known problem that you can work around by cleaning the solution and rebuilding the project (Build > Clean Solution, Build > Rebuild Solution). For more information, see this forum discussion.
But I recommend you do the following to be sure.
Check if you are receiving notifications when in debug mode.
If not remove bin and obj folders from your Android project.
Clean build your solution and try again
If it works archive the application and in release mode, test if you are receiving notifications.(If it works on one device it will work in all).
Steps for archive can be found here

push notifications not handled by onMessage if received when app closed using IBM MobileFirst Platform 7.0

We are using MFP 7.0.0.00-20150907-1450 and building a hybrid app targeting iOS and Android.
We're using the "send bulk messages" REST API to send broadcast messages.
We've implemented WL.Client.Push.onMessage in our app, and as long as the app is running when the notification is received, it handles the message.
If the application is closed when the notification reaches the phone, the message payload doesn't seem to get to our onMessage implementation.
This behavior is identical between iOS and Android.
I suspect there's a timing issue between our onMessage function being assigned and when the MFP framework is trying to pass the the message into our app.
Some pointers on how we might get the message handled in the case where it was received when the app was closed would be great!
(Below are some details of our setup.)
We're using Angular and had this in our main app module:
if (angular.isDefined(window.WL) && angular.isDefined(window.WL.Client.Push)) {
window.WL.Client.Push.onMessage = function (props, payload) {
console.log('Received push notification in client', JSON.stringify(props), JSON.stringify(payload));
$rootScope.$broadcast('pushNotification', props, payload);
};
}
After noticing this ("You must declare it outside any function.") in the docs for onMessage, I've moved the assignment out to the top of a JavaScript file, outside of even an IIFE. This function doesn't seem to be called, certainly there's no logging and the variable remains undefined:
var lastPushMessage;
function pushMessageRecorder(props, payload) {
lastPushMessage = {
props: props,
payload: payload
};
console.log('MFP: push received: ' + JSON.stringify(lastPushMessage, null, 2));
}
WL.Client.Push.onMessage = pushMessageRecorder;
Our security test (users don't have to log in, just have a app packaged with our keys):
<customSecurityTest name="customTests">
<test realm="wl_antiXSRFRealm" step="1" />
<test realm="wl_authenticityRealm" step="1" />
<test realm="wl_remoteDisableRealm" step="1" />
<test realm="wl_directUpdateRealm" mode="perSession" step="1" />
<test realm="wl_anonymousUserRealm" isInternalUserID="true" step="1" />
<test realm="wl_deviceNoProvisioningRealm" isInternalDeviceID="true" step="2" />
</customSecurityTest>
It looks like I've got it working.
(Mostly. If the app is not running and the user swipes away the notification, or opens the app directly from the launcher, then the notification still doesn't show up in the app.)
There were 2 things that needed doing:
the assignment to WL.Client.Push.onMessage had to be done "outside of any function"
it looks like the value for the string "app_name" in native/res/values/strings.xml is used to locate the app from the push service and make sure the message comes through
The second point still doesn't really make sense to me, but it looks like the intent-filter action android:name value in AndroidManifest.xml is built using these values:
{AndroidManifest.xml:/manifest[#package]}.{res/values/strings.xml:/resources/string[#name="app_name"]}.NOTIFICATION
Since the app_name value is used to build the notification qualifier, it can't have any spaces, which is not so nice for the name of your app that's displayed on the phone.
I've worked around that by adding another variable to the strings.xml file (although I could have just hard coded the name in the AndroidManifest.xml too, and then use that variable as my label.
Here's what's working:
res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MyApp</string>
<string name="app_label">My App</string>
<string name="push_notification_title">My App</string>
<!-- ... -->
</resources>
AndroidManifest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.MyProject" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19"/>
<supports-screens android:smallScreens="false" android:normalScreens="true" android:largeScreens="false"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Push permissions -->
<permission android:name="com.MyProject.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="com.MyProject.permission.C2D_MESSAGE"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="#string/app_label" android:icon="#drawable/icon">
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity android:name=".MyApp" android:label="#string/app_name" android:configChanges="orientation|keyboardHidden|screenSize" android:launchMode="singleTask" android:theme="#android:style/Theme.Translucent.NoTitleBar" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="com.MyProject.MyApp.NOTIFICATION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<!-- Preference Activity -->
<activity android:name="com.worklight.common.WLSettingActivity" android:label="Worklight Settings"/>
<!-- UI Activity for displaying native dialogs -->
<activity android:name="com.worklight.wlclient.ui.UIActivity"/>
<!-- Push service -->
<!-- In order to use the c2dm library, an application must declare a class with the name C2DMReceiver, in its own package, extending com.google.android.c2dm.C2DMBaseReceiver
It must also include this section in the manifest, replacing "com.google.android.apps.chrometophone" with its package name. -->
<service android:name=".GCMIntentService"/>
<service android:name=".ForegroundService"/>
<!-- Only google service can send data messages for the app. If permission is not set - any other app can generate it -->
<receiver android:name="com.worklight.androidgap.push.WLBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<!-- Receive the actual message -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="com.MyProject"/>
</intent-filter>
<!-- Receive the registration id -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="com.MyProject"/>
</intent-filter>
</receiver>
</application>
</manifest>

Resources