Multiple API keys in the same Android project - android

Is it possible to specify multiple keys for Google Maps Android API in the same code base?
It looks like I have to change the key in manifest file each time I change keystore. It's not very convenient, imho, if you need to test the app signed with keys form debug and release keystores.

I added both keys in the manifest at once. Like this
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
..
android:versionCode="1"
android:versionName="1.0" >
<!-- RELEASE key -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="my-release-keu" />
<!-- DEBUG key -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="my-debug-key" />
</application>
</manifest>
Apparently, this works. Looks like Google code is smart enough to use relevant key automatically.

I don't think this is what you want to do. You should add both debug and release SHA1 key to API key on Google Developer API Console. Take a look at this answer

AFAIK, there is no programmatical form on doing this. For comodity, you can define API keys in strings.xml, and retrieve it from the manifest

String debugMapKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
String releaseMapKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
String mapKey = BuildConfig.DEBUG ? debugMapKey : releaseMapKey;
MapView mv = new MapView(this, mapKey);

Related

The Client Token must be specified in the string resource file as com.facebook.accountkit.ClientToken

I have an android project and i want to use facebook account kit. I did all settings but when i run the project, i am getting this message;
E/AndroidRuntime: 500: Initialization error: 503: The Client Token must be specified in the string resource file as com.facebook.accountkit.ClientToken
But i specified it in strings.xml
<string name="ACCOUNT_KIT_CLIENT_TOKEN">***</string>
AndroidManifest.xml
<meta-data android:name="com.facebook.accountkit.ClientToken"
android:value="#string/ACCOUNT_KIT_CLIENT_TOKEN" />
Waiting for your helps, thank you.
For me solution was adding following to the manifest file:
<meta-data android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id"/>
<meta-data android:name="com.facebook.accountkit.ApplicationName"
android:value="#string/app_name"/>
<meta-data
android:name="com.facebook.accountkit.ClientToken"
android:value="#string/ACCOUNT_KIT_CLIENT_TOKEN" />
And the creating the respective String resources as:
facebook_app_id with app id, found at top-left corner next to navigation pane of facebook developer console for your app.
app_name which is already defined generally in your string resource file with the name of your app.
ACCOUNT_KIT_CLIENT_TOKEN with value found at Settings>advanced in navigation drawer of facebook developer console. Then go to Security, there you will find "Client Token". Use this client token value for value of this String resource.
This worked for me. Hope this helps.
You should have something like this in string resources (you have to get the app_id)
<string name="facebook_app_id">2077942129****</string>
and in you Manifest:
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
Check the attached to find to solution click on your products then go account-kit-->settings

Google Analytics XML Config File vs JSON?

I've added Google Analytics to my mobile application by using the google-services.json file.
Now I've enabled auto activity tracking and I want to provide a screen name for each activity.
Google documents say, I should add
<screenName name=".MyActivity">My activity</screenName>
to my XML configuration file. Where's this coming from? I don't have a xml config file, I have a google-services.json file.
Do I need to create a XML file inside res/xml/ ?
What values are necessary as I am currently using the android default R.xml.global_tracker ?
Or do I need to add these screen-name information to the json file and if yes, whats the structure then?
Thanks in advance.
You could create your own XML. Here is mine, remember to replace your tracking ID:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="ga_trackingId" translatable="false">UA-99999999-1</string>
<!-- Enable automatic Activity measurement -->
<bool name="ga_autoActivityTracking">true</bool>
<!-- The screen names that will appear in reports -->
<screenName name="com.codylab.squats.MainActivity">MainActivity</screenName>
<screenName name="com.codylab.squats.SettingsActivity">SettingsActivity</screenName>
<screenName name="com.codylab.squats.BreakActivity">BreakActivity</screenName>
<screenName name="com.codylab.squats.FinishedActivity">FinishedActivity</screenName>
<screenName name="com.codylab.squats.InitialActivity">InitialActivity</screenName>
<screenName name="com.codylab.squats.WorkoutActivity">WorkoutActivity</screenName>
</resources>
Create an Application class:
public class YourNameApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Stetho.initializeWithDefaults(this);
GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
// To enable debug logging use: adb shell setprop log.tag.GAv4 DEBUG
analytics.newTracker(R.xml.squats_tracker);
}
}
Add a name attribute of application tag in your AndroidMenifest.xml
...
<application
android:name=".YourNameApplication"
...>
...
</application>

Change ID App in Qt

Well.. I have a big problem my app id is "org.qtproject.example.test". I want to change to "com.mycompany.myapp". I was looking at the whole project and there is no way to change it. How do you do that?
change the package name in the Android manifest file.
manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mycompany.myapp" android:versionCode="1" android:versionName="1.0.0"
Open the AndroidManifest.xml file of your project in Creator and it's the first setting in the manifest editor form.
Also, from QGuiApplication see the setOrganizationName(), setOrganizationDomain() and setApplicationName() functions.

Google map displaying only blank tiles android

I have implemented google map in my app.But its display only blank grids.I have done changes in AndroidManifest.xml file and also included API key in layout file of map activity.
This may sound silly, but I kept encountering this problem until I realized that the <uses-permission> tags need to be direct children to the <manifest> element, rather than the <application> element. I had erroneously been putting them right after the <uses-library> tag. So the final structure of your AndroidManifest.xml file should be something like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<uses-sdk ... />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application ... >
<activity ... >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-library android:name="com.google.android.maps" />
</application>
</manifest>
Hope this helps anyone who was making the same mistake!
I was having the same problems until I realised that in the API console I had enabled
Google Maps API v2
and not the
Google Maps Android API v2
Once I enabled it everything was fine.
The problem is the code API. Use the following function to see if the Key Google Maps is correct:
private String getShaKey() {
//fucnion para saber si esta bien registrado el codigo de googlemaps
//ME SALE EXCEPTION DE NOMBRE NO ENCONTRADO?¿?¿
String strRet="";
try {
PackageInfo info = getPackageManager().getPackageInfo("your.package.name",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
//Log.v(TAG, "KeyHash:" + Base64.encodeToString(md.digest(),
strRet="KeyHash:" + Base64.encodeToString(md.digest(),Base64.DEFAULT);
}
} catch (NameNotFoundException e) {
//e.printStackTrace();
strRet="EXCEPTION NOMBRE NO ENCONTRADO";
} catch (NoSuchAlgorithmException e) {
//e.printStackTrace();
strRet="EXCEPTION ALGORITMO NO";
}
return strRet;
}
This happens to me also. On the first time I successfully launched the Google maps, in works fine, on the second day, the entire map(default view) is rendered only in half while the other half are filled with tiles only, after changing some properties in the map, it all went to tiles only.
Now, what I did is I renew my API key and everything went fine.
This happened to me when I launched the map as intent (Intent intent = new Intent(android.content.Intent.ACTION_VIEW, mapUrl) ...). The map was created empty and did not load anything. The map showed my icon as "logged in user" in the top right corner, but no error messages at all. Everything worked flawlessly on the emulator. Finally, I checked the normal Google Map App and it was empty too.
Solution: Remove my Google account from Settings App of the development device. It took me several hours to figure that out. No clue what that was, but maybe it saves someone time to know.
I had the same problem. I added this line on the Manifest.xml and everything is working fine now :
<uses-library android:name="com.google.android.maps" />

When to use which constructor for ComponentName in Android?

I am a little bit confused about the ComponentName class in Android.
There are different ways to get to a component name object, but I don't know when to use which... and why!
Example:
Application package is de.zordid.sampleapp
but widget provider class is de.zordid.sampleapp.widget.WidgetProvider
Using
ComponentName cn = new ComponentName("de.zordid.sampleapp.widget",
"WidgetProvider");
I got this component info: ComponentInfo{de.zordid.sampleapp.widget/WidgetProvider}, but I could not use this - the component is unknown!
But the JavaDoc says I should give the package and the class within that package - and that is what I did, didn't I??
Using
ComponentName cn = new ComponentName(context, WidgetProvider.class);
yields ComponentInfo{de.zordid.sampleapp/de.zordid.sampleapp.widget.WidgetProvider} - and that works fine!!
There is even another way to get a ComponentName - by context and a string.
Which one should be used where and when??
Thanks!
The ComponentName constructor taking two Strings can be used to refer to a component in another application. But, the first argument is not the package name of the class; it is the package name of the application---the package attribute of the manifest element in that application's AndroidManifest.xml. So your first example should be
ComponentName cn = new ComponentName("de.zordid.sampleapp",
"de.zordid.sampleapp.widget.WidgetProvider");
That constructor could certainly be used to refer to components in your own application, but since you already have hold of a Context from your own application you might as well use it and use one of the other constructors. In my opinion, the one taking a Class should be preferred whenever usable. You could use the one taking a String if you only know the class dynamically for some reason; in that case, it should take the fully-qualified class name as above.
Robert Tupelo-Schneck's answer is right about preferring objects against Strings. Here's how I see it with details on how all the different prefixes work.
To refer to your own components, use:
new ComponentName(getApplicationContext(), WidgetProvider.class);
To refer to some dynamically referenced component in your own app, use:
// values/strings.xml: <string name="provider">de.zordid.sampleapp.widget.WidgetProvider</string>
String fqcn = getResources().getString(R.string.provider);
new ComponentName(getApplicationContext(), fqcn);
This is useful when you want to use Android's resource qualifiers to decide which component to use, you can override the default string in values-*/strings.xml.
To refer to another application's component, use:
int componentFlags = GET_ACTIVITIES | GET_PROVIDERS | GET_RECEIVERS | GET_SERVICES;
PackageInfo otherApp = context.getPackageManager().getPackageInfo("com.other.app", componentFlags);
ComponentInfo info = otherApp.activities[i]; // or providers/receivers/...
new ComponentName(info.packageName, info.name);
#About .Names and <manifest package="
There may be some confusion here because I think historically Robert's statement was true:
it is the package name of the application---the package attribute of the manifest element in that application's AndroidManifest.xml
but not any more. Since the new Gradle build system was introduced there has been some changes around here, and then they changed it again in AGP 7.3, and made it mandatory in AGP 8.0.
If you have an android.defaultConfig.applicationId specified in your build.gradle that'll be the app package name, and then package attribute in manifest (or later namespace in build.gradle) is a separate thing when building your app. The first argument of ComponentName now refers to applicationId + applicationIdSuffix. The tricky thing is that after the final manifest merge and packaging the APK will have <manifest package=applicationId + applicationIdSuffix and all the .Names will be expanded to FQCNs.
Example app for learning name resolution
Here's an example structure based on the structure of one of my apps. Consider the following classes in a hypothetical app called "app":
net.twisterrob.app.android.App
net.twisterrob.app.android.GlideSetup
net.twisterrob.app.android.subpackage.SearchResultsActivity
net.twisterrob.app.android.subpackage.Activity
net.twisterrob.app.android.content.AppProvider
on the server side backend of the app and/or some shared model classes:
net.twisterrob.app.data.*
net.twisterrob.app.backend.*
net.twisterrob.app.web.*
in my Android helper library:
net.twisterrob.android.activity.AboutActivity
other libraries:
android.support.v4.content.FileProvider
This way everything is namespaced in net.twisterrob.app. The android app being just a single part of the whole inside it's own subpackage.
AndroidManifest.xml (irrelevant parts omitted)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.twisterrob.app.android">
<!--
`package` above defines the base package for .Names
to simplify reading/writing the manifest.
Notice that it's different than the `applicationId` in build.gradle
and can be independently changed in case you want to refactor your packages.
This way you can still publish the same app with the same name.
-->
<!-- Will be expanded to net.twisterrob.app.android.App in the manifest merging phase. -->
<application android:name=".App">
<!-- meta-data needs FQCNs because the merger can't know if you want to expand them or not.
Also notice that name and value both can contain class names, depending on what you use. -->
<meta-data android:name="net.twisterrob.app.android.GlideSetup" android:value="GlideModule" />
<meta-data android:name="android.app.default_searchable" android:value="net.twisterrob.app.android.subpackage.SearchResultsActivity" />
<!-- Will be expanded to net.twisterrob.app.android.subpackage.Activity in the manifest merging phase. -->
<activity android:name=".subpackage.Activity" />
<!-- Needs full qualification because it's not under the package defined on manifest element. -->
<activity android:name="net.twisterrob.android.activity.AboutActivity" />
<!-- Will be expanded to net.twisterrob.app.android.content.AppProvider in the manifest merging phase. -->
<provider android:name=".content.AppProvider" android:authorities="${applicationId}" />
<!-- Needs full qualification because it's not under the package defined on manifest element. -->
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.share" />
</application>
<!-- ${applicationId} will be replaced with what's defined in `build.gradle` -->
</manifest>
build.gradle
android {
defaultConfig {
// this is what will be used when you upload it to the Play Store
applicationId 'net.twisterrob.app'
// in later AGP versions, move manifest's package here:
// namespace 'net.twisterrob.app.android'
}
buildTypes {
debug {
// The neatest trick ever!
// Released application: net.twisterrob.app
// IDE built debug application: net.twisterrob.app.debug
// This will allow you to have your installed released version
// and sideloaded debug application at the same time working independently.
// All the ContentProvider authorities within a system must have a unique name
// so using ${applicationId} as authority will result in having two different content providers.
applicationIdSuffix '.debug'
}
}
}
To check out what your final manifest will look like after all the merging open build\intermediates\manifests\full\debug\AndroidManifest.xml.
Or you can use like this inside BroadcastReceiver :
ComponentName smsReceiver = new ComponentName(this, SMSReceiver.class);

Categories

Resources