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.
Related
I am getting this error
ADB0010: Mono.AndroidTools.InstallFailedException: Unexpected install output: Failure [INSTALL_PARSE_FAILED_MANIFEST_MALFORMED: Failed parse during installPackageLI: /data/app/vmdl61481456.tmp/base.apk (at Binary XML file line #44): crc6494e14b9856016c30.PNFirebaseMessagingService: Targeting S+ (version 31 and above) requires that an explicit value for android:exported be defined when intent filters are present]
After installing "Xamarin.GooglePlayServices.Base version: 71.1610.0" for the dependency of the plugin.firebasepushnotification
Target Android version 12.0 (API Level 31 - S)
Here is my menifest.xml code
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="2" android:versionName="1.0.2" package="com.healholmes" android:installLocation="preferExternal">
<uses-sdk android:minSdkVersion="24" android:targetSdkVersion="31" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<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.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application tools:replace="android:label" android:label="Heal Holmes" android:icon="#mipmap/icon_ambush" />
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
</manifest>
The Xamarin.GooglePlayServices.Base version: 71.1610.0 is too old. According to the error message, there is a service named PNFirebaseMessagingService in your project doesn't declare the exported property.
It should be created by the nuget package you added in your project. So you can try to use the newest version of plugin.firebasepushnotification and the Xamarin.GooglePlayServices.Base.
Such as plugin.firebasepushnotification version 3.4.35 and Xamarin.GooglePlayServices.Base version 118.1.0
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
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>
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
I have followed Google's tutorial to use a SyncAdapter with a dummyAccount and no ContentProvider.
The tutorial is quite straight forward, and I'm aware of the limitations of using stubs for the Account and ContentProvider. I implemented it and when run on the emulator, it works wonderfully. I see the message in the Log of when it is periodically called with periodicSync(..) and when I request specifically to be called with requestSync(..).
Here is the mind-blowing part, when I run the app on my BQ 5 HD (Android 4.1.2) the SyncAdapter is never ever called. If re-installed the app, but nothing seems to be happening. I've wasted weeks with this, and I can´t figure it out.
Here is the my manifestFile
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
....Whole bunch of activities...
<provider
android:name="com.sf.app_name.stubs.StubProvider"
android:authorities="com.sf.app_name.provider"
android:exported="false"
android:syncable="true" />
<service android:name="com.sf.app_name.stubs.AuthenticatorService"
android:exported="false">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="#xml/authenticator" />
</service>
<service
android:name="com.sf.app_name.sync.SyncService"
android:exported="false"
android:process=":sync" >
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="#xml/syncadapter" />
</service>
</application>
authenticator.xml
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.sf.app_name"
android:userVisible="false" />
syncadapter.xml
<?xml version="1.0" encoding="utf-8"?>
<sync-adapter
xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.sf.app_name.provider"
android:accountType="com.sf.app_name"
android:userVisible="false"
android:supportsUploading="false"
android:allowParallelSyncs="true"
android:isAlwaysSyncable="true"/>
Input is very much appreciated.
Finally figured out what's wrong thanks to ye-old-faithful Log.d(...). It's a definite noob mistake and I'm posting the answer to prevent other beginners from committing the same mistake.
In my code where I create and add the "dummyAccount" needed by the SyncAdapter framework, I did the following:
Account[] accounts = accountManager.getAccounts();
if(accounts.length == 0){
Account newAccount = new Account(ACCOUNT, ACCOUNT_TYPE);
ContentResolver.setIsSyncable(newAccount, AUTHORITY, 1);
ContentResolver.setSyncAutomatically(newAccount, AUTHORITY, true);
ContentResolver.addPeriodicSync(newAccount, AUTHORITY, new Bundle(), 40l);
accountManager.addAccountExplicitly(newAccount, null, null);
Log.d("serverSync", "ContetResolver set periodic sync");
}
The methodgetAccounts() returns all of the accounts associated to the device. Obviously it is going to return ZERO when run in the emulator because the emulator has no account associated whatsoever. So I thought it save to do it like this. I create my account of type ACCOUNT_TYPE add it, and go merrily along my way. (By the way, the reason for the addPeriodicSync on top of the setIsSyncable and setSyncAutomatially is to solve a problem that pertains to another matter.
Ofcourse, the SyncAdapter of my APP was getting called when the following was executed:
ContentResolver.requestSync(signedInAccountInstance.getDummyAccount(),
AccountManagerActivity.AUTHORITY, bundle);
They getDummyAccount(..) was gotten like so:
Account[] accounts = accountManager.getAccounts();
return accounts[0];
When this was run on the actual physical device, I should have realized that getAccounts(..) would also return (atleast) the gmail account associated to my Android device. Hence when I would do
ContentResolver.requestSync(signedInAccountInstance.getDummyAccount(),
AccountManagerActivity.AUTHORITY, bundle);
the "dummyAccount" sent would be Google's AccountType, and hence why my app's SyncAdapter would never be called. Instead, it was the gmail app's SyncAdapter who was getting called with my bundle.
How did I discover this? By printing out my dummyAccount in Log after looking into the Accounts of my physical device under Settings>Accounts, and realizing that for some reason when I executed my app on my mobile, my gmail account would display a "sync error".
All this could have been prevented by doing things correctly the first time:
Account[] accounts = accountManager.getAccountsByType(ACCOUNT_TYPE);
Where ACCOUNT_TYPE is static final variable used in my app.
// An account type, in the form of a domain name
public static final String ACCOUNT_TYPE = "com.sf.app_name";
Hope this helps save someone some headaches.