Android Studio Template package name - android

I tried make android studio template like activity template by this instruction
Current package set in globals.xml.ftl
<global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
and create template file
<instantiate from="src/app_package/LifecycleFragment.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${className}.java" />
It force my template file to src/main/java/myPackageName
But my current package is kotlin
How can i create template in current selected folder?

Sorry if I'm late with my answer, but maybe it will be useful for someone.
To change the source package from java to kotlin try add this line to globals.xml.ftl:
<global id="kotlinMainSourceSet" value="${srcOut?replace('java','kotlin') />
Use it in your receipt.xml.ftl as following:
! Replace SomeClass.kt.ftl with your class in app_package;
! Replace your_needed_path with path, in which you would like to put the file
! Replace someClassName with the id of the className from template.
<instantiate
from="src/app_package/SomeClass.kt.ftl"
to="${escapeXmlAttribute(kotlinMainSourceSet)}/${your_needed_path}/${someClassName}.kt" />
In addition I'll answer on the #AlexeiKorshun question with which I've faced too: applicationIdSuffix is added, while creating a directory. This can be easily fixed by overriding srcOut in your globals.kt.ftl with following:
<global id="srcOut" value="${srcDir}/${slashedPackageName(packageName?replace('.dev|.qa2|.stage', '', 'r'))}" />
.dev/.qa2/.stage are added as an example,please replace them with yours.

Related

Android DataBinding - Why Data Binding not support #mipmap images

Using DataBinding, I trying to access icon from mipmap folder, after write a code it not compile model class and it show error in log - "token recognition error". Look at the below screenshot even it not allowed #mipmap. If anyone know the reason Please let me know
<ImageView
android:id="#+id/img_page1"
android:layout_width="#dimen/splash_slider_circle"
android:layout_height="#dimen/splash_slider_circle"
android:src="#{slider.img1 ? #mipmap/ic_circle_filled : #mipmap/ic_circle_outline}" />
The exact reason for the described behaviour is unknown to me. But if it's inconvenient to move all your icons from mipmap to drawable folders, it's possible to import your generated R class in the layout and refer mipmaps in conditions starting with R.mipmap and using app:imageResource attribute:
<data>
<import type="your.package.R" />
...
</data>
<ImageView
...
app:imageResource="#{someConditionVariable ? R.mipmap.ic_for_true_condition : R.mipmap.ic_for_false_condition}"
... />

ClassCastException casting chronometer.java file

I'm using Kotlin. I tried using the Millisecond Chronometer found here https://github.com/antoniom/Millisecond-Chronometer. I downloaded the zipfile, and then copied the Chronometer.java file into a new .java file in my project.
I placed a chronometer widget in the layout file and gave its id chrono
When I tried to use Chronometer.java, it throws me an error:
val mChronometer = findViewById<Chronometer>(R.id.chrono)
//Caused by: java.lang.ClassCastException: android.widget.Chronometer cannot be cast to com.example.rinor.chronometertimer.Chronometer
How to fix this? I'm sure if I get this line right everything else is smooth sailing from there on.
Probably you use the wrong Chronometer in your .xml <Chronometer>...</Chronometer> instead of
<com.example.rinor.chronometertimer.Chronometer
android:layout_width="match_parent"
android:layout_height="wrap_content">...
</com.example.rinor.chronometertimer.Chronometer>
Probably you import "android.widget.Chronometer" instead of "com.example.rinor.chronometertimer.Chronometer" change the import.

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.

Where are the settings of a preferences screen stored?

I know this question is a little stupid but I cannot find where the settings of my preferences screen are stored.
I am using shared preferences this file is located at /data/data/my.package.name/shared_prefs/common.xml. However when I change something the changes are stored. I even implemented custom controls which can store their information so far. But however I cannot figure out where the settings are stored. /data/data/my.package.name/ is only one xml file which does not contain any related information. I also checked the virtual directories for multi user devices with no luck.
Here is my xml:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/my.package.name"
android:persistent="true" >
<PreferenceCategory android:title="#string/settings_basics_group" >
<EditTextPreference
android:key="nickname"
android:persistent="true"
android:positiveButtonText="#string/setting_change_name"
android:title="#string/settings_username" />
<my.package.name.controls.EmailPreference
android:key="mail"
android:title="#string/settings_email"
custom:domains="#array/known_email_domains" />
<Preference
android:summary="Mars"
android:title="#string/settings_current_location" />
<my.package.name.controls.DatePreference
android:key="birthday"
android:title="#string/settings_birthday" />
</PreferenceCategory>
</PreferenceScreen>
I would be really happy if somebody could explain me where these settings are stored.
For older Android versions including Jelly Bean (API 16) and older the answer of Dalmas is correct. So feel free to upvote that answer.
Beginning with Jelly Bean MR1 (API 17) there are new rules about path due the multiuser support:
I figured out that the settings file is located in /data/user/##/my.package.name/shared_prefs/my.package.name_preferences.xml where ## is my numeric user id.
For solving that path you need the ApplicationContext there you need to reflect mLoadedAPK and there mDataDir. For now I'm happy with that I could get the path from the debugger. Sorry to everyone who wants a ready to use code snippet, you have to do that yourself.
The app preferences are stored in the default shared preferences that you can retrieve with PreferenceManager.getDefaultSharedPreferences().
The XML file itself is located at /data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PACKAGE_NAME_preferences.xml

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