My expo react native application comunicates with a zebra printer via a HTTP post request this works just fine in web , however on android and I suspect also iOS this isnt the case, from what i gather i need to add something along the lines of :
<uses-permission android:name="android.permission.INTERNET" />
Into androidmanifest.xml however expo doesnt give you direct access to that file , so i need to make a expo plugin that puts the permission into androidmanifest via expo.
I found this post teaching how to remove permissions however my current case requires me to add permissions ill still link the code from the post down here:
const { withAndroidManifest } = require("#expo/config-plugins")
module.exports = function androiManifestPlugin(config) {
return withAndroidManifest(config, async config => {
let androidManifest = config.modResults.manifest
// add the tools to apply permission remove
androidManifest.$ = {
...androidManifest.$,
"xmlns:tools": "http://schemas.android.com/tools",
}
// add remove property to the audio record permission
androidManifest["uses-permission"] = androidManifest["uses-permission"].map(
perm => {
if (perm.$["android:name"] === "android.permission.RECORD_AUDIO") {
perm.$["tools:node"] = "remove"
}
return perm
}
)
return config
})
}
Does anyone know how to add http permissions to my expo app? Thanks.
To add permissions you do not need expo-plugins.
You simply need to add the permission in your app.json (or app.config.js if you have dynamic configuration)
On Android, permissions are little bit simpler than iOS. In the managed workflow, permissions are controlled via the android.permissions property in your app.json file.
https://docs.expo.dev/guides/permissions/
I'm making an app using flutter that uses the contacts(using contact_services plugin) from user's phone. Thus it needs as well to give the ability to add a new contact using the system default add contact page. However there isn't such functionality in contacts_services. What is the way using plugin or existing contact_services plugin to open the add new contact page?
void openAddContacts() async{
if (Platform.isAndroid) {
final AndroidIntent intent = AndroidIntent(
action: 'ContactsContract.Intents.Insert.ACTION',
category: 'ContactsContract.RawContacts.CONTENT_TYPE',
);
await intent.launch();
}
}
This may help you : https://github.com/differenz-system/Addressbook.Flutter
Or if you xant to dive deeper and want to understand the mechanism under the hood, I suggestion you to use Platform Channel to communicate with native codes. Here is an example proposed by Google for address-book : https://developers.google.com/protocol-buffers/docs/darttutorial
if you use this plugin https://pub.dev/packages/contacts_service you can look full working example here https://github.com/lukasgit/flutter_contacts/blob/master/example/lib/main.dart
Add permissions
Android #
Add the following permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
iOS #
Set the NSContactsUsageDescription in your Info.plist file
<key>NSContactsUsageDescription</key>
<string>This app requires contacts access to function properly.</string>
And after you can use code from the example by link above.
I'm using the Google analytics plugin for MvvmCross with the following namespace:-
OCS.MvvmCross.Plugins.MvxAnalytics
https://www.nuget.org/packages/OCS.MvvmCross.Plugins.MvxAnalytics
There isn't any documentation on how to use/implement it, from my discovery, the AnalyticsConfiguration needs to be defined, then added to the DroidAnalyticsService.Configuration.
Inside the AnalyticsConfiguration, there is TrackingId, which I understand, log levels and whether to report UncaughtExceptions (set to true)
The PluginBootstrap file is included which is great, but joining the last dots are a bit of a headscratch.
Any ideas how to get this working? I've messaged the creators so if they email me back, I'll post the details here.
Thanks in Advance.
I was able to set it up and it seems that it's working properly.
You have to setup all properties inside Configuration object and then it works.
var analyticsService = new DroidAnalyticsService();
analyticsService.Configuration.AppName = "Your app name";
analyticsService.Configuration.AnonymizeIp = true;
analyticsService.Configuration.AppVersion = "App version fro xml";
analyticsService.Configuration.TrackingId = "Tracking id from google";
analyticsService.Configuration.DispatchPeriod = 30;
analyticsService.Configuration.ReportUncaughtExceptions = true;
I am trying to configure ACRA for the first time. I have followed the Basic Setup guide :
1.Integrated the acra jar file to my app
2.Created a new class extending application class and have added the below code to it :
#ReportsCrashes(formKey = "", // will not be used
mailTo = "mymailId#gmail.com")
public class MyApplication extends Application
{
#Override
public void onCreate()
{
super.onCreate();
ACRA.init(this);
}
}
3.Made all necessary changes to manifest file
It seems that all is done correctly,I am able to get the below in logcat :
12-21 14:59:10.994: D/ACRA(28728): ACRA is enabled for com.android.demo.notepad1, intializing...
12-21 14:59:11.064: D/ACRA(28728): Using default Mail Report Fields
12-21 14:59:11.064: D/ACRA(28728): Looking for error files in /data/data/com.android.demo.notepad1/files
12-21 14:59:11.074: W/ACRA(28728): **com.android.demo.notepad1 reports will be sent by email (if accepted by user).**
But I am not able to get any mail :( !
As far i know, the mailTo option needs the user in order to send the email.
When an error occurs another mail client (such as Gmail.apk) has to be open to process the crash report and send e-mail. So the error will open a mail client and we need the user to click on send button.
Although a bit late, someone might find it useful anyways...
I did have at least a similar problem with ACRA 4.5.0 which I was able to resolve once all the other configuration options were actually set. This means – although partially labeled as optional – I had to give a value to the following options (in the #ReportsCrashes annotation)
resDialogText = R.string.crash_dialog_text, // Text to display upon crash
resDialogIcon = android.R.drawable.ic_dialog_info, //optional (apparently not). default is a warning sign
resDialogTitle = R.string.crash_dialog_title, // optional (apparently not). default is your application name
resDialogCommentPrompt = R.string.crash_dialog_comment_prompt, // optional (apparently not). when defined, adds a user text field input with this text resource as a label
resDialogOkToast = R.string.crash_dialog_ok_toast // optional (apparently not). displays a Toast message when the user accepts to send a report.
Though I had mode = ReportingInteractionMode.DIALOG, set which might be the source of my problems at least.
have not used "mailTo" field ,had only used #ReportsCrashes(formKey = "formkey")
Make sure you get the form key from google drive correctly
And on crash you will be getting the report on Google drive excel file
And also make sure you have added Internet permission and Added "MyApplication" in mainfeast
<manifest ...>
<application ... android:name="MyApplication">
...
</application>
<uses-permission android:name="android.permission.INTERNET">
</uses-permission>
</manifest>
Detail explanation is provided here http://acra.ch/
I received the above exception when trying to implement Sample Sync Adapter application. I have seen numerous posts related to this issue but no satisfactory response.
So I will jot down my solution here in case anyone else gets into the same issue.
Some other useful tips to debug problems like this.
First enable verbose logging for some tags:
$ adb shell setprop log.tag.AccountManagerService VERBOSE
$ adb shell setprop log.tag.Accounts VERBOSE
$ adb shell setprop log.tag.Account VERBOSE
$ adb shell setprop log.tag.PackageManager VERBOSE
You'll see logging like this:
V/AccountManagerService: initiating bind to authenticator type com.example.account
V/Accounts: there is no service connection for com.example.account
V/Accounts: there is no authenticator for com.example.account, bailing out
D/AccountManagerService: bind attempt failed for Session: expectLaunch true, connected false, stats (0/0/0), lifetime 0.002, addAccount, accountType com.example.account, requiredFeatures null
Which means that there is no authenticator registered for this account type. To see which authenticators are registered watch the log when installing the package:
D/PackageManager: encountered new type: ServiceInfo: AuthenticatorDescription {type=com.example.account}, ComponentInfo{com.example/com.example.android.AuthenticatorService}, uid 10028
D/PackageManager: notifyListener: AuthenticatorDescription {type=com.example.account} is added
I had the problem that the authenticator xml descriptor referred to a string resource which didn't get resolved properly during the installation:
android:accountType="#string/account_type"
The logs showed
encountered new type: ServiceInfo: AuthenticatorDescription {type=#2131231194}, ...
Replacing it with a normal string (not resource) solved the problem. This seems to be Android 2.1 specific.
android:accountType="com.example.account"
First, check the condition explained on this post:
[...] If you see an error from the AccountManagerService of the form caller uid XXXX is different than the authenticator's uid, it might be a bit misleading. The ‘authenticator’ in that message is not your authenticator class, it’s what Android understands to be the registered authenticator for the account’s type. The check that happens within the AccountManagerService looks like this:
private void checkCallingUidAgainstAuthenticator(Account account) {
final int uid = Binder.getCallingUid();
if (account == null || !hasAuthenticatorUid(account.type, uid)) {
String msg = "caller uid " + uid + " is different than the authenticator's uid";
Log.w(TAG, msg);
throw new SecurityException(msg);
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid");
}
}
Note that hasAuthenticatorUid() takes the account.type. This is where I’d screwed up. I was creating my Account with a type specified by a constant:
class LoginTask {
Account account = new Account(userId, AuthenticatorService.ACCOUNT_TYPE);
...
}
class AuthenticatorService extends Service {
public static final String ACCOUNT_TYPE = "com.joelapenna.foursquared";
...
}
but this constant did not match the XML definition for my authenticator:
<account-authenticator xmlns:android="/web/20150729061818/http://schemas.android.com/apk/res/android"
android:accountType="com.joelapenna.foursquared.account" ... />
Second, if you are like me and want to embed the sample into your existing app for testing then, make sure you use Constants class that is part of this example and not under android.provider.SyncStateContract package. Because both classes use the same attribute name ACCOUNT_TYPE that is used when creating Account object.
In my case the problem was very simply a mismatch in accountType declared in res/xml/authenticator.xml as android:accountType="com.foo" but referenced incorrectly as "foo.com" in creating the Account:
Account newAccount = new Account("dummyaccount", "foo.com");
Doh!
There are few parts to implement custom account...
To invoke AccountManager in your Activity, something like that you already implemented...
Account account = new Account(username, ACCESS_TYPE);
AccountManager am = AccountManager.get(this);
Bundle userdata = new Bundle();
userdata.putString("SERVER", "extra");
if (am.addAccountExplicitly(account, password, userdata)) {
Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, username);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCESS_TYPE);
setAccountAuthenticatorResult(result);
}
In res/xml/authenticator.xml you have to define your AccountAuthenticator data (responsible for your Authenticator UID). ACCESS_TYPE have to be the same string as your defined accountType in this xml!
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="de.buecherkiste"
android:icon="#drawable/buecher"
android:label="#string/app_name"
android:smallIcon="#drawable/buecher" >
</account-authenticator>
Finally you have to define your service your Manifest. Please do not forget the relevant permissions for manage your accounts (AUTHENTICATE_ACCOUNTS / USE_CREDENTIALS / GET_ACCOUNTS / MANAGE_ACCOUNTS)
<service android:name=".AuthenticationService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator"
android:resource="#xml/authenticator" />
</service>
My error was assuming the AccountManager getAccounts() method returned accounts only associated with my application context. I changed from
AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccounts();
to
AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccountsByType(Constants.ACCOUNT_TYPE);
The same error will appear if you put incorrect values in your intent-filters in your manifest.
I went through the android-dev tutorial on sync-adapters and ended up setting a bogus value for the "intent-filter/action android:name" as well as "meta-data/android:name" for syncadapter/accountauthenticator. This mistake caused the same errors to appear in the logs.
For the record, the correct values are: {android.content.SyncAdapter, android.accounts.AccountAuthenticator}
Make sure that your service XML is pointing to the correct location.
For instance if you're module name is
com.example.module.auth
you're service android:name should be
<service android:name=".module.auth.name-of-authenticator-service-class"...
in AndriodManifest.xml
First off, take another look at Jan Berkel's excellent debugging advice.
Finally, another thing to check is that your content provider and the authentication, and sync services are declared as children of the application tag.
<application
...>
<activity
...(Activity)...
</activity>
<provider
...(CP service declaration)/>
<service
...(Authentication service declaration)...
</service>
<service
...(Sync service declaration)...
</service>
</application>
For me it was a very silly mistake and was very hard to find.
In authenticator.xml I wrote
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.myapp"
android:icon="#drawable/ic_launcher"
android:smallIcon="#drawable/ic_launcher"
android:label="#string/app_name"
/>
instead of
<account-authenticator
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.myapp"
android:icon="#drawable/ic_launcher"
android:smallIcon="#drawable/ic_launcher"
android:label="#string/app_name"
/>
which was causing this error. Hope this helps someone!
In my case it was permissions in manifest file
i had
<uses-permission android:name="ANDROID.PERMISSION.GET_ACCOUNTS"/>
it was all caps, when i changed it to
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
problem was gone
Also,
Check to see if you are treating the AccountType too much like a plain-old-String.
I have most of my code packaged under com.mycompany.android
I have been using the following AccountType with success: com.mycompany.android.ACCOUNT.
Now I have a desire to use multiple accounts, and when I try the approach of appending ".subType" on the end of my account, it fails with the
caller uid xxxxx is different than the authenticator's uid
However, if I use "_subType" ( underscore instead of dot ), it works fine.
My guess is that somewhere under the hood Android is trying to treat com.mycompany.android.ACCOUNT as a legal package name, which it most certainly is not.
So, again:
BAD com.mycompany.android.ACCOUNT.subType
GOOD com.mycompany.android.ACCOUNT_subType
If you are getting this error, and all the above solutions are not working for you. Also, you assume that you have followed all the procedure. There may be a chance that the Authentication Service is developed by some other developer, which you want to make use of to Add Accounts.
What you can try is try signing your application with a release keystore. Now you run the application. I suppose this should work for you.
Here is another one possible solution.
I had this error when my user was registered in my app with the same e-mail as his android google account.
So, when I tried to accountManager.getAccounts() and search for this e-mail I found an account with the same e-mail BUT with another account type. So, when trying to use this (google.com) account I get this error.
So, the right way to find an account is:
public Account findAccount(String accountName) {
for (Account account : accountManager.getAccounts())
if (TextUtils.equals(account.name, accountName) && TextUtils.equals(account.type, "myservice.com"))
return account;
return null;
}
Also make sure your AccountAuthenticatorService has the prover intent filters ;
ie.
<service android:name=".service.AccountAuthenticatorService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator"
android:resource="#xml/authenticator" />
</service>
If you get this exception at Samsung devices be sure that you are not using safe mode.
If same apps are from different store ,for example amazon app store and google play store , eventually security exception gonna be thrown as the signature of the apps would be different in this case .If u had planned to use same authenticator for the purpose of single sign in , either of the app would crash. i had encountered this trouble once. Especially amazon app store would sign its apps with its own signature for the purpose of security.
Note: If there is no typo error or other answers mentioned here , please check for the signature of the apps in case of single sign in.
For those who still expierienced issue: https://stackoverflow.com/a/37102317/4171098
In my case I accidently defined AuthenticatorService in the Manifest
outside the <application> tags. Moving the declaration inside
<application> fixed the issue. Hope will help someone.